【问题标题】:Is there an R function that splits a column into an arbitrary number of multiple field-named columns?是否有一个 R 函数可以将一列拆分为任意数量的多个字段命名的列?
【发布时间】:2017-11-20 11:27:02
【问题描述】:

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

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该软件包中的功能似乎不太有用。我希望在加载必要的包后能够在一行中完成此操作。

【问题讨论】:

  • 试试qdapTools::mtabulate(strsplit(as.character(df$x), ",\\s*"))tidyverse rownames_to_column(df, 'rn') %>% separate_rows(x) %>% mutate(i = 1) %>% spread(x, i, fill = 0)
  • 如果需要重命名,用%>% select(-rn) %>% rename_all(funs(paste0("x", .)))链接

标签: r data-cleaning


【解决方案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

注意:只是将我的 cmets 发布为解决方案


或者另一个选项来自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

【讨论】:

    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-11
      • 2020-02-28
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多