假设我有以下内容:
df=read.table(text="ID ColB ColC ColD
1 A S1 X,Y,Z
2 A S2 A,B,C
3 B S3 A,B,C
4 B S4 X
5 C S6 X
6 C S8 X
", header=TRUE)
我想根据ColB合并重复的行,同时在这些行上合并ColC和ColD,比如结果是:
df <- read.table(text="ID ColB ColC ColD
1 A S1,S2 X,Y,Z,A,B,C
2 B S3,S4 A,B,C,X
3 C S6,S8 X
", header=TRUE)
如您所见,由于 ColD,第 5 行和第 6 行具有相同的值,因此生成的 ColD 第 3 行仅包含 X 值。
library(dplyr)
df %>%
mutate(ColD = toString(unique(ColD)),
ColC = toString(ColC),
.by = ColB) %>%
slice_head(by=ColB)
ID ColB ColC ColD
1 1 A S1, S2 X,Y,Z, A,B,C
2 3 B S3, S4 A,B,C, X
3 5 C S6, S8 X
使用
aggregate
和 strsplit
、unlist
和合并 toString
,最后添加一个新的 ID 列。
> aggregate(cbind(ColC, ColD) ~ ColB, df, \(x) {
+ unique(unlist(strsplit(x, ','))) |> toString()
+ }) |>
+ transform(id=seq_along(ColB))
ColB ColC ColD id
1 A S1, S2 X, Y, Z, A, B, C 1
2 B S3, S4 A, B, C, X 2
3 C S6, S8 X 3
如果你不喜欢空间,你可以用
paste(collapse=',')
而不是 toString
。
library("dplyr")
df %>%
group_by(ColB) %>%
group_modify(~{
tibble(ColC = list(unique(.x$ColC)),
ColD = list(unique(.x$ColD)) )
})