r - 铸造(传播)多列字符向量的优雅解决方案
问题描述
我想将带有联系信息的数据框转换为一个城市列表,其中类似信息(例如电话号码)出现在多个列中。
我试过同时使用reshape2::dcast()
和tidyr::spread()
,但都不能解决我的问题。我还检查了堆栈溢出的其他帖子,例如
尚未找到可行的解决方案。在我看来,这些问题应该相当简单(并且可以通过 spread 或 dcast 解决)。
tmp <- tibble(municipality = c("M1", "M2"),
name1 = c("n1", "n2"), name2 = c("n3", "n4"), name3 = c(NA, "n5"), # placeholder names
phone1 = c("p1", "p2"), phone2 = c("p3", "p4"), phone3 = c(NA, "p5")) # placeholder phone numbers
#solution 1
tmp %>% gather("colname", "value", -municipality) %>%
filter(municipality == "M1") %>% #too simplify, should be replaced with group_by(municipality)
na.omit() %>% mutate(colname = str_replace(colname, "\\d", replacement = "")) %>%
spread(., key = "colname", value = "value")
#Solution 2
tmp %>% gather("colname", "value", -municipality) %>%
filter(municipality == "M1") %>% # same as above
na.omit() %>% mutate(colname = str_replace(colname, "\\d", replacement = "")) %>%
dcast(municipality + value ~colname)
解决方案 1 导致以下错误: 错误:每行输出必须由唯一的键组合标识。
解决方案 2 产生以下数据框(这是所需的结果,但需要折叠):
municipality value name phone
1 M1 n1 n1 <NA>
2 M1 n3 n3 <NA>
3 M1 p1 <NA> p1
4 M1 p3 <NA> p3
解决方案
你在找吗?
library(dplyr)
library(tidyr)
tmp %>%
gather(key, value, -municipality, na.rm = TRUE) %>%
mutate(key = gsub("\\d+", "", key)) %>%
group_by(municipality, key) %>%
mutate(row = row_number()) %>%
spread(key, value) %>%
select(-row)
# municipality name phone
# <chr> <chr> <chr>
#1 M1 n1 p1
#2 M1 n3 p3
#3 M2 n2 p2
#4 M2 n4 p4
#5 M2 n5 p5
我们可以使用gather
以长格式删除NA
值的数据。从各个列名中删除数字,使它们共享相同key
,创建列group_by
municipality
并将数据转换key
为spread
宽格式。
推荐阅读
- process - BPM 人工任务调度
- symfony - Symfony 将所有字段值大写
- vba - 在列表框中插入单词标题,包括带有 VBA 的数字
- mqtt - 我如何发布和订阅图像(在 python 中使用 mqtt)
- c# - 在不添加网络凭据的情况下发送 Asp.Net 电子邮件
- c - rtspsrc 内部数据流错误 gstreamer c-appliaction
- mysql - 如果完整日期小于恢复日期,如何编写单个语句来检索用户观看视频的最后恢复?
- c++ - 树递归无限进行
- python - 自动化我创建 virtualenv 和 django 的任务
- java - 为什么子类对象引用父类值