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

当所需变量的数量未知时,如何使用tidyr::separate,r,tidyr,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"),

我有一个由电子邮件通信组成的数据集。例如:

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"))
然而,我的数据集有4000条记录,我不希望遍历并找到其中元素最多的行,以便确定需要创建多少变量。我处理这个问题的方法是首先自己拆分列,得到每个拆分的长度,然后找到最大值:

n_vars <- dat$to %>% str_split(",") %>% lapply(function(z) length(z)) %>% unlist() %>% max()
n_变量%str_split(“,”)%%>%lapply(函数(z)长度(z))%%>%unlist()%%>%max()

但这似乎效率低下。有更好的方法吗?

这是一个好问题-我通常的回答是使用
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

我们可以使用
cSplit

library(splitstackshape) 
cSplit(dat, 'to', ',')

也可能
库(data.table);cbind(dat,setDT(dat)[,tstrsplit(to,“,”)])
似乎是一个足够合理的解决方案,而不是加载另一个包。如果您已经在加载
tidyverse
可以使用
map\u dbl
并删除
unlist
,使其稍微干净一些<代码>dat$到%>%str_split(“,”)%%>%map_dbl(~length(.))%%>%max()您可以更精确地计算n_变量,而无需使用
n_变量%str_count(pattern=“,”)%%>%max()+1
进行拆分,我认为这样更好,因为您可以选择不在末尾进行拆分。将电子邮件划分为所有这些单独的列似乎很愚蠢。@bramtayl我有一种感觉,分离故意让这变得很难,所以你不会得到广泛的数据,而不是long@bramtayl我同意在这种情况下拥有广泛的数据是没有意义的(在大多数情况下也是如此),但是,当您不知道需要多少新列时,您很容易理解使用
separate
的根本问题。Akrun的解决方案仍然是一个很好的解决方案,因为您将
direction=“long”
设置为在一列中获取所有电子邮件。请注意,如果您不想获得广泛的数据集,只需在
unnest
处停止命令,就可以得到
long
数据格式
library(splitstackshape) 
cSplit(dat, 'to', ',')