在dplyr::distinct()中使用数据掩码函数合并重复ID行并计算列均值的语法求助
嘿,我来帮你搞定这个需求!你想要对重复ID的行进行合并,同时计算每列的均值,其实不用在distinct()里硬凑逻辑——dplyr的group_by() + summarise(across())才是最直接、规范的解决方案,完全能达到你想要的效果。
正确实现代码
先直接上能得到你期望结果的代码:
library(dplyr) # 你的原始数据 a <- data.frame( "ID" = rep(1:3, each = 2) %>% as.numeric(), "x" = rep(1:3, each = 2) %>% as.numeric(), "y" = 1:6 %>% as.numeric() ) # 按ID分组,计算所有列的均值 final_result <- a %>% group_by(ID) %>% summarise(across(everything(), ~ mean(.x, na.rm = TRUE))) print(final_result)
运行后会得到你想要的输出:
# A tibble: 3 × 3 ID x y <dbl> <dbl> <dbl> 1 1 1.5 1.5 2 2 2.5 3 3 3 3 5.5
为什么你之前的方法行不通?
咱们来拆解下你之前尝试的问题:
第一个
grouped_mean函数的问题:
你在distinct()里调用grouped_mean(a, ID)时,这个函数是对**整个数据集a**计算ID的均值,而不是针对每个ID分组计算。所以它返回的是全局均值,不是你要的分组均值,自然会多出一个奇怪的mean列。而且distinct()的核心作用是去重,不是做分组聚合,硬在这里塞聚合函数会逻辑混乱。第二个
row_mean函数的问题:
你把row_mean(a, ID)传给distinct()的参数,但distinct()的第三个参数是用来指定去重的键,不是执行聚合的逻辑。所以它只是按ID去重后保留了每个ID的第一行数据,根本没触发你的聚合函数。
如果一定要用distinct()实现(不推荐)
虽然不建议这么做(效率低且逻辑不直观),但如果好奇怎么用distinct()达成目标,可以这么写:
a %>% distinct(ID, .keep_all = TRUE) %>% mutate( across(c(x, y), ~ mean(a[[cur_column()]][a$ID == ID], na.rm = TRUE)) )
这种方法是先去重保留每个ID的一行,再通过mutate手动匹配每个ID的所有行计算均值,但大数据集下会比group_by()慢很多,因为每次都要子集化数据。
总结
最推荐的还是group_by() + summarise(across()),这是dplyr专门设计用来处理分组聚合的标准流程,代码清晰、效率高,后续维护也更容易。
内容的提问来源于stack exchange,提问作者Pål Bjartan

