如何合并除一列以外的所有列中具有相同信息的行?
How to merge rows that have the same information in all columns except one?
我有一个大数据框,看起来像这样:
A 1 2 3 4 ...
B 1 2 3 4 ...
C 1 2 3 4 ...
D 5 2 1 4 ...
E 3 2 3 9 ...
F 0 0 2 2 ...
G 0 0 2 2 ...
如您所见,如果您暂时忽略第一列,有些行是重复的条目。我想 combine/merge 这些行生成如下内容:
A;B;C 1 2 3 4 ...
D 5 2 1 4 ...
E 3 2 3 9 ...
F;G 0 0 2 2 ...
我可以编写一个循环遍历行的 for 循环,但这既不美观也不高效。我很确定有更好的方法可以做到这一点。
我以为我可以:
- 对 df 进行切片,这样我就有了除第一列之外的所有列
slice <- df[, 2:ncols(df)]
- 通过
dups <- df[duplicated(slice)]
获取包含所有 "duplicate" 行的数据框
- 通过
uniq <- df[unique(slice)]
获得另一个包含 "unique" 行的数据框
- 使用除第一列以外的所有列合并它们
merge(uniq, dups, by... )
除非那行不通,因为 unique 不是 return 索引而是整个数据框,这意味着我无法使用 slice
.[=18 中的相应行索引 df
=]
有什么建议吗?
编辑: 我应该澄清 A、B、C... 不是行名,而是数据框的一部分,string/character 表示中给出的条目
有几个函数可以做到这一点。它们都是常见的聚合函数:aggregate
、tapply
、by
、...,当然还有流行的"data.table" 和 "dplyr" 函数集。
这里是aggregate
:
aggregate(V1 ~ ., mydf, toString)
# V2 V3 V4 V5 V6 V1
# 1 0 0 2 2 ... F, G
# 2 5 2 1 4 ... D
# 3 1 2 3 4 ... A, B, C
# 4 3 2 3 9 ... E
其他选项(如开头段落所示):
library(data.table)
as.data.table(mydf)[, toString(V1), by = eval(setdiff(names(mydf), "V1"))]
library(dplyr)
mydf %>%
group_by(V2, V3, V4, V5, V6) %>%
summarise(V1 = toString(V1))
您可以使用经典的 paste(., collapse = ";")
方法,而不是 toString
,这使您对最终输出具有更大的灵活性。
我有一个大数据框,看起来像这样:
A 1 2 3 4 ...
B 1 2 3 4 ...
C 1 2 3 4 ...
D 5 2 1 4 ...
E 3 2 3 9 ...
F 0 0 2 2 ...
G 0 0 2 2 ...
如您所见,如果您暂时忽略第一列,有些行是重复的条目。我想 combine/merge 这些行生成如下内容:
A;B;C 1 2 3 4 ...
D 5 2 1 4 ...
E 3 2 3 9 ...
F;G 0 0 2 2 ...
我可以编写一个循环遍历行的 for 循环,但这既不美观也不高效。我很确定有更好的方法可以做到这一点。
我以为我可以:
- 对 df 进行切片,这样我就有了除第一列之外的所有列
slice <- df[, 2:ncols(df)]
- 通过
dups <- df[duplicated(slice)]
获取包含所有 "duplicate" 行的数据框
- 通过
uniq <- df[unique(slice)]
获得另一个包含 "unique" 行的数据框
- 使用除第一列以外的所有列合并它们
merge(uniq, dups, by... )
除非那行不通,因为 unique 不是 return 索引而是整个数据框,这意味着我无法使用 slice
.[=18 中的相应行索引 df
=]
有什么建议吗?
编辑: 我应该澄清 A、B、C... 不是行名,而是数据框的一部分,string/character 表示中给出的条目
有几个函数可以做到这一点。它们都是常见的聚合函数:aggregate
、tapply
、by
、...,当然还有流行的"data.table" 和 "dplyr" 函数集。
这里是aggregate
:
aggregate(V1 ~ ., mydf, toString)
# V2 V3 V4 V5 V6 V1
# 1 0 0 2 2 ... F, G
# 2 5 2 1 4 ... D
# 3 1 2 3 4 ... A, B, C
# 4 3 2 3 9 ... E
其他选项(如开头段落所示):
library(data.table)
as.data.table(mydf)[, toString(V1), by = eval(setdiff(names(mydf), "V1"))]
library(dplyr)
mydf %>%
group_by(V2, V3, V4, V5, V6) %>%
summarise(V1 = toString(V1))
您可以使用经典的 paste(., collapse = ";")
方法,而不是 toString
,这使您对最终输出具有更大的灵活性。