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
说明:使用apply
和paste(..., collapse = ", ")
连接所有行条目(NA
s 和"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
是最终输出。请查看我如何创建数据框df
。 cbind
不是必需的,最好添加 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_5
和variable_2
中维护了它们
@www - 我认为有些混乱,但我已将 order(id)
添加到链中以保持排序:)以上是关于r 将多列中的数据合并为一列的主要内容,如果未能解决你的问题,请参考以下文章