我有一个由电子邮件通信组成的数据集。一个例子:
library(dplyr)
library(tidyr)
dat <- data_frame('date' = Sys.time(),
'from' = c("person1@gmail.com", "person2@yahoo.com",
"person3@hotmail.com", "person4@msn.com"),
'to' = c("person2@yahoo.com,person3@hotmail.com", "person3@hotmail.com",
"person4@msn.com,person1@gmail.com,person2@yahoo.com", "person1@gmail.com"))
在上面的示例中,它很简单,可以看到我需要多少变量,所以我可以执行以下操作:
dat %>% separate(to, into = paste0("to_", 1:3), sep = ",", extra = "merge", fill = "right")
#Source: local data frame [4 x 5]
#
# date from to_1 to_2 to_3
# (time) (chr) (chr) (chr) (chr)
#1 2015-10-22 14:52:41 person1@gmail.com person2@yahoo.com person3@hotmail.com NA
#2 2015-10-22 14:52:41 person2@yahoo.com person3@hotmail.com NA NA
#3 2015-10-22 14:52:41 person3@hotmail.com person4@msn.com person1@gmail.com person2@yahoo.com
#4 2015-10-22 14:52:41 person4@msn.com person1@gmail.com NA NA
但是,我的数据集长度为4,000条记录,我宁愿不通过查找包含最多元素数量的行,这样我就可以确定需要创建多少个变量。我处理这个问题的方法是首先自己拆分列并获得每个拆分的长度,然后找到max:
n_vars <- dat$to %>% str_split(",") %>% lapply(function(z) length(z)) %>% unlist() %>% max()
但这似乎效率低下。有没有更好的方法呢?
答案 0 :(得分:12)
这是一个很好的问题 - 我通常的回答是使用strsplit
,然后是unnest
和spread
,这也不是超级高效的:
library(dplyr)
library(tidyr)
dat %>% mutate(to = strsplit(to, ",")) %>%
unnest(to) %>%
group_by(from) %>%
mutate(row = row_number()) %>%
spread(row, to)
Source: local data frame [4 x 5]
date from 1 2 3
(time) (chr) (chr) (chr) (chr)
1 2015-10-22 15:03:17 person1@gmail.com person2@yahoo.com person3@hotmail.com NA
2 2015-10-22 15:03:17 person2@yahoo.com person3@hotmail.com NA NA
3 2015-10-22 15:03:17 person3@hotmail.com person4@msn.com person1@gmail.com person2@yahoo.com
4 2015-10-22 15:03:17 person4@msn.com person1@gmail.com NA NA
答案 1 :(得分:6)
我们可以使用cSplit
library(splitstackshape)
cSplit(dat, 'to', ',')