r 将多列中的数据合并为一列

Posted

技术标签:

【中文标题】r 将多列中的数据合并为一列【英文标题】:r collapsing data from multiple columns into one 【发布时间】:2018-05-25 14:20:13 【问题描述】:

我知道关于这个主题有很多问题,所以如果这是一个重复的问题,我很抱歉。我正在尝试将数据集中的多列折叠为一列:

假设这是我正在使用的数据集的结构,

df <- data.frame(
      cbind(
      variable_1 = c('Var1', NA, NA,'Var1'),
      variable_2 = c('Var2', 'No', NA, NA),
      variable_3 = c(NA, NA, 'Var3', NA),
      variable_4 = c(NA, 'Var4', NA, NA),
      variable_5 = c(NA, 'No', 'Var5', NA),
      variable_6 = c(NA, NA, 'Var6', NA)

    ))

 variable_1  variable_2  variable_3  variable_4  variable_5  variable_6 
 Var1        Var2        NA          NA          NA          NA
 NA          No          NA          Var4        No          NA
 NA          NA          Var3        NA          Var5        Var6
 Var1        NA          NA          NA          NA          NA

我期待的是像这样的一列variable_7

 variable_1  variable_2  variable_3  variable_4  variable_5  variable_6  variable_7
 Var1        Var2        NA          NA          NA          NA          Var1, Var2
 NA          No          NA          Var4        No          NA          Var4
 NA          NA          Var3        NA          Var5        Var6        Var3, Var5, Var6
 Var1        NA          NA          NA          NA          NA          Var1

非常感谢您对完成此操作的任何帮助。

【问题讨论】:

【参考方案1】:
df$variable_7 <- apply(df, 1, function(x) paste(x[!is.na(x) & x != "No"], collapse = ", "));
df;
#  variable_1 variable_2 variable_3 variable_4 variable_5 variable_6
#1       Var1       Var2       <NA>       <NA>       <NA>       <NA>
#2       <NA>         No       <NA>       Var4         No       <NA>
#3       <NA>       <NA>       Var3       <NA>       Var5       Var6
#4       Var1       <NA>       <NA>       <NA>       <NA>       <NA>
#        variable_7
#1       Var1, Var2
#2             Var4
#3 Var3, Var5, Var6
#4             Var1

说明:使用applypaste(..., collapse = ", ") 连接所有行条目(NAs 和"No"s 除外)并存储在新列variable_7 中。


样本数据

df <- data.frame(
      cbind(
      variable_1 = c('Var1', NA, NA,'Var1'),
      variable_2 = c('Var2', 'No', NA, NA),
      variable_3 = c(NA, NA, 'Var3', NA),
      variable_4 = c(NA, 'Var4', NA, NA),
      variable_5 = c(NA, 'No', 'Var5', NA),
      variable_6 = c(NA, NA, 'Var6', NA)

    ))

【讨论】:

这正是我所期待的,谢谢。 太好了,很高兴帮助@Science11【参考方案2】:

我收集到,如果有 n 行,那么目标是创建一个由逗号分隔的字符串组成的 n 向量,每行中包含字符 Var。 (如果您打算使用其他标准来区分期望值和不期望值,则相应地更改 grep。)

apply(df, 1, function(x) toString(grep("Var", x, value = TRUE)))
## [1] "Var1, Var2"       "Var4"             "Var3, Var5, Var6" "Var1"         

【讨论】:

【参考方案3】:

使用dplyr 的解决方案。 df4 是最终输出。请查看我如何创建数据框dfcbind 不是必需的,最好添加 stringsAsFactors = FALSE 以防止创建因子列。

library(dplyr)
library(tidyr)

df2 <- df %>% mutate(ID = 1:n()) 

df3 <- df2 %>%
  gather(Variable, Value, -ID, na.rm = TRUE) %>%
  filter(!Value %in% "No") %>%
  group_by(ID) %>%
  summarise(variable_7 = toString(Value))

df4 <- df2 %>% 
  left_join(df3, by = "ID") %>%
  select(-ID) 

df4
#   variable_1 variable_2 variable_3 variable_4 variable_5 variable_6       variable_7
# 1       Var1       Var2       <NA>       <NA>       <NA>       <NA>       Var1, Var2
# 2       <NA>         No       <NA>       Var4         No       <NA>             Var4
# 3       <NA>       <NA>       Var3       <NA>       Var5       Var6 Var3, Var5, Var6
# 4       Var1       <NA>       <NA>       <NA>       <NA>       <NA>             Var1

数据

df <- data.frame(
    variable_1 = c('Var1', NA, NA,'Var1'),
    variable_2 = c('Var2', 'No', NA, NA),
    variable_3 = c(NA, NA, 'Var3', NA),
    variable_4 = c(NA, 'Var4', NA, NA),
    variable_5 = c(NA, 'No', 'Var5', NA),
    variable_6 = c(NA, NA, 'Var6', NA),
    stringsAsFactors = FALSE
  )

【讨论】:

【参考方案4】:

使用data.table“重塑”方法而不是循环/应用

library(data.table)
setDT(df)

df[, id := .I][
    melt(df, id.vars = "id")[grepl("Var", value), .(variable_7 = paste0(value, collapse = ",")), by = .(id)]
    , on = "id"
    , nomatch = 0
    ][order(id)]


#    variable_1 variable_2 variable_3 variable_4 variable_5 variable_6 id     variable_7
# 1:       Var1       Var2         NA         NA         NA         NA  1      Var1,Var2
# 2:         NA         No         NA       Var4         No         NA  2           Var4
# 3:         NA         NA       Var3         NA       Var5       Var6  3 Var3,Var5,Var6
# 4:       Var1         NA         NA         NA         NA         NA  4           Var1

【讨论】:

不错的解决方案,但似乎在此过程中删除了No @www - 我(可能不正确)认为这是要求的一部分 OP 的预期输出仍然是“否”,但这是小问题,不会影响您的解决方案的有效性。 @www - 在variable_7 列?我在variable_5variable_2 中维护了它们 @www - 我认为有些混乱,但我已将 order(id) 添加到链中以保持排序:)

以上是关于r 将多列中的数据合并为一列的主要内容,如果未能解决你的问题,请参考以下文章

将列中的数据合并为一列

sql数据库中,如何将一个表中的多列数字合并为一列

如何将 DataFrame 中两列中的两个日期和时间合并为一列? [复制]

【Excel】多列数据合并为一列

SQL 怎么将一列中的数据按一个分隔符分成多列显示

将多列合并为一列