是否有一个 R 函数可以将一列拆分为任意数量的多个以字段命名的列?

Is there an R function that splits a column into an arbitrary number of multiple field-named columns?

例如,我有一个如下所示的数据框:

df = data.frame(x=c('a, b, c','b, c', 'd, e'))

理想情况下,我最终会得到一个如下所示的数据框:

df.transformed = data.frame(x.a = c(1,0,0),
                            x.b = c(1,1,0),
                            x.c = c(1,1,0),
                            x.d = c(0,0,1),
                            x.e = c(0,0,1))

其中 x 中每个可能的逗号分隔值都已分开。

我已经多次为这个问题编写手动解决方案,但这是我在调查数据中多次遇到的问题,让我想知道为什么它没有包含在像 tidyr 这样的包中,因为该包中的 separate 函数似乎不太有用。我希望能够在加载必要的包后在一行中执行此操作。

添加行号列,将 x 分隔成行,并在 x 中的每个元素前加上 x.。然后 运行 table 并将其转换为数据框。如果不需要在每个名称前加上 paste 行,则可以省略;如果不需要数据框(table 即可),则可以省略最后一行。

library(dplyr)
library(tidyr)

df %>% 
   mutate(row = 1:n()) %>% 
   separate_rows(x) %>% 
   mutate(x = paste("x", x, sep = ".")) %>%
   table %>% 
   as.data.frame.matrix 

给予:

  x.a x.b x.c x.d x.e
1   1   1   1   0   0
2   0   1   1   0   0
3   0   0   0   1   1

请注意,如果我们省略可选行,那么我们将得到:

df %>% 
   mutate(row = 1:n()) %>% 
   separate_rows(x) %>% 
   table

给予:

   x
row a b c d e
  1 1 1 1 0 0
  2 0 1 1 0 0
  3 0 0 0 1 1

这可以通过 qdapTools 完成,我们将 'x' 拆分为 , 后跟零个或多个空格并使用 mtabulate

library(qdapTools)
mtabulate(strsplit(as.character(df$x), ",\s*"))
#  a b c d e
#1 1 1 1 0 0
#2 0 1 1 0 0
#3 0 0 0 1 1

或者我们使用tidyverse方法

library(tidyverse) 
rownames_to_column(df, 'rn') %>% #add row names
       separate_rows(x) %>% #split the rows into long format
       mutate(i = 1) %>% #create a column of 1s
       spread(x, i, fill = 0) %>% #spread to wide format
       select(-rn) %>%  #remove unnecessary columns
       rename_all(funs(paste0("x.", .))) #rename if needed
#    x.a x.b x.c x.d x.e
#1   1   1   1   0   0
#2   0   1   1   0   0
#3   0   0   0   1   1

注意:仅发布我的评论作为解决方案


或者另一个选项来自 base R table - 未使用包

table(stack(setNames(strsplit(as.character(df$x), ",\s*"), seq_len(nrow(df))))[2:1])
#       values
#ind a b c d e
# 1 1 1 1 0 0
# 2 0 1 1 0 0
# 3 0 0 0 1 1