如何在R中汇总DataFrame时保留所有列并合并指定列内容
如何在分组合并指定列的同时保留所有其他列信息(无需硬编码列名)
问题场景
我有如下示例数据框:
dummy_df <- tibble( A=c("ABC", "ABC", "BCD", "CDF", "CDF", "CDF"), B=c(0.25, 0.25, 1.23, 0.58, 0.58, 0.58), C=c("lorem", "ipsum", "dolor", "amet", "something", "else"), D=c("up", "up", "down", "down", "down", "down"), E=c(132, 132, 243, 512, 512, 512), F=c("m1", "m1", "m5", "m3", "m3", "m3"), G=c("val", "val", "mur", "mad", "mad", "mad"), H=c("grx", "grx", "bcn", "sal", "sal", "sal"), I=c(1.68, 1.68, 2.31, 3.12, 3.12, 3.12), J=c("p", "p", "f", "p", "p", "p"), K=c(100, 100, 200, 143, 143, 143) )
我已经实现了按列A分组,将列C的内容合并为字符串并统计每组行数:
dummy_df %>% group_by(A) %>% summarise(hits = toString(C), nhits=n())
但这个操作会丢失其他所有列的信息,而这些信息对我很重要。我需要在合并列C的同时保留所有列的信息,而且最好不用硬编码列名,因为数据集的列数会变化。期望得到如下输出:
# A tibble: 3 × 12 A hits nhits B D E F G H I J K <chr> <chr> <int> <dbl> <chr> <dbl> <chr> <chr> <chr> <dbl> <chr> <dbl> 1 ABC lorem, ipsum 2 0.25 up 132 m1 val grx 1.68 p 100 2 BCD dolor 1 1.23 down 243 m5 mur bcn 2.31 f 200 3 CDF amet, something, else 3 0.58 down 512 m3 mad sal 3.12 p 143
解决方案
可以使用dplyr的across()函数,配合group_by()和summarise()实现需求。由于分组列A对应的其他列(除C外)每组内的值完全一致,我们可以对这些列提取每组的第一个值(或任意值,结果相同),同时完成C列的合并和行数统计:
library(dplyr) dummy_df %>% group_by(A) %>% summarise( hits = toString(C), nhits = n(), across(-c(A, C), first) # 保留除A、C外的所有列,取每组第一个值 ) %>% relocate(A, hits, nhits) # 调整列顺序,让A、hits、nhits排在最前面
代码说明
across(-c(A, C), first):-c(A, C)表示排除分组列A和要合并的列C,对剩余所有列应用first()函数。因为每组内这些列的值完全相同,所以取第一个值和其他值结果一致。relocate(A, hits, nhits):调整列的显示顺序,让核心分组、合并、统计列排在最前面,匹配期望的输出格式。
这种写法无需硬编码其他列名,无论后续数据集增加或减少列(只要分组后其他列每组内值一致),代码都能正常运行。
内容的提问来源于stack exchange,提问作者jpm92
相关产品推荐
相关产品推荐

