如何用dplyr合并data.frame指定行并对不同列采用不同聚合函数
解决方案
完全可以通过dplyr的group_by() + summarize()组合实现需求,核心思路是先给需要合并的行打同一分组标签,其余行单独分组,再按分组规则分别聚合不同列即可,不需要提前知道行的位置,仅通过ID匹配即可完成操作。
完整实现代码
首先加载依赖包、构造示例数据:
library(dplyr) # 构造示例数据集 iris_df <- iris[1:5,] iris_df$ID <- paste0("ID_", 1:nrow(iris_df))
执行合并操作:
# 定义需要合并的ID列表,可按需修改 merge_id_list <- c("ID_1", "ID_2") # 合并后新的ID值,自动拼接不需要手动修改 new_merge_id <- paste(merge_id_list, collapse = "+") result <- iris_df %>% # 构造分组标识:需要合并的ID归为同一组,其余ID单独成组 mutate(merge_group = ifelse(ID %in% merge_id_list, "merge_target", ID)) %>% group_by(merge_group) %>% summarize( # Sepal开头列取均值 across(starts_with("Sepal"), mean), # Petal开头列取求和 across(starts_with("Petal"), sum), # 非数值常量列取第一个值即可,可根据业务调整规则 Species = first(Species), # 生成最终ID ID = ifelse(cur_group()$merge_group == "merge_target", new_merge_id, first(ID)) ) %>% # 移除临时分组列,恢复原始列顺序 select(all_of(colnames(iris_df))) %>% ungroup()
结果验证
打印result即可看到和预期完全一致的输出:
print(result) # Sepal.Length Sepal.Width Petal.Length Petal.Width Species ID # 1 5.0 3.25 2.8 0.4 setosa ID_1+ID_2 # 2 4.7 3.20 1.3 0.2 setosa ID_3 # 3 4.6 3.10 1.5 0.2 setosa ID_4 # 4 5.0 3.60 1.4 0.2 setosa ID_5
适配说明
- 若待合并的两个ID对应的
Species等非数值列取值不同,可以根据业务需要把first(Species)替换为其他聚合规则,比如paste(unique(Species), collapse = ",") - 可以灵活调整
starts_with的匹配规则,或者直接指定列名来适配不同的聚合需求
内容的提问来源于stack exchange,提问作者Johannes
相关产品推荐
相关产品推荐

