当所需变量的数量未知时,如何使用tidyr :: separate

bri*_*enb 15 r tidyr

我有一个包含电子邮件通信的数据集.一个例子:

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"))
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我很容易看到我需要多少变量,所以我可以执行以下操作:

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
Run Code Online (Sandbox Code Playgroud)

但是,我的数据集长度为4,000条记录,我宁愿不通过它找到包含最多元素的行,这样我就可以确定需要创建多少个变量.我处理这个问题的方法是首先自己拆分列并获得每个拆分的长度,然后找到最大值:

n_vars <- dat$to %>% str_split(",") %>% lapply(function(z) length(z)) %>% unlist() %>% max()
Run Code Online (Sandbox Code Playgroud)

但这似乎效率低下.有没有更好的方法呢?

jer*_*ycg 13

这是一个很好的问题-我平时repsonse是使用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
Run Code Online (Sandbox Code Playgroud)


akr*_*run 7

我们可以用 cSplit

library(splitstackshape) 
cSplit(dat, 'to', ',')
Run Code Online (Sandbox Code Playgroud)