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

时间:2017-11-19 19:48:04

标签: r data-cleaning

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

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这样的包中,因为{该包中的{1}}函数似乎不太有用。我希望能够在加载必要的软件包后在一行中完成此操作。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:2)

这可以通过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