You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按ID合并数据框指定分组的行并对num_to_sum列求和?

解决方案:按指定分组合并并聚合数据

示例数据构造

先模拟符合你描述的数据集:

set.seed(123)
df <- data.frame(
  group = rep(c("group1", "group2", "group3"), each = 100),
  ID = rep(sprintf("%02d", 1:100), 3),
  feat2 = rep(sample(1:100, 100), 3),
  feat3 = rep(sample(letters, 100), 3),
  num_to_sum = rnorm(300, 50, 10)
)

方法一:用dplyr实现灵活分组合并

这种方式支持合并任意数量的分组,只需修改分组映射规则:

library(dplyr)

# 定义分组映射:键是新分组名,值是需要合并的原分组集合
group_mapping <- list(
  group12 = c("group1", "group2"),  # 合并group1和group2为group12
  group3 = "group3"                 # 保留原分组group3
)

# 反转映射,将原分组匹配到对应的新分组
reverse_map <- stack(group_mapping) %>%
  rename(old_group = values, new_group = ind)

# 执行合并与聚合
result_df <- df %>%
  left_join(reverse_map, by = c("group" = "old_group")) %>%
  group_by(new_group, ID) %>%
  summarise(
    num_to_sum = sum(num_to_sum),
    # 同一ID的feat2/feat3值一致,取任意一个即可
    feat2 = first(feat2),
    feat3 = first(feat3),
    .groups = "drop"
  )

# 如果不需要feat2/feat3,直接筛选列即可
result_df_no_feats <- result_df %>% select(new_group, ID, num_to_sum)

方法二:用data.table实现高效处理(适合大数据)

如果你的数据集规模较大,data.table的性能更优:

library(data.table)

setDT(df)

# 同样定义分组映射
group_mapping <- list(
  group12 = c("group1", "group2"),
  group3 = "group3"
)

reverse_map <- melt(group_mapping, value.name = "old_group", variable.name = "new_group")

# 合并并聚合
result_dt <- df[reverse_map, on = c(group = "old_group")][, .(
  num_to_sum = sum(num_to_sum),
  feat2 = first(feat2),
  feat3 = first(feat3)
), by = .(new_group, ID)]

# 去掉feat列的版本
result_dt_no_feats <- result_dt[, .(new_group, ID, num_to_sum)]

为什么stats::aggregate难以实现?

aggregate的聚合逻辑相对固定,无法直接自定义多分组到新分组的映射规则,而上述方法通过先建立分组映射关系,再按新分组+ID聚合的思路,完美解决了带条件的合并需求,且支持任意数量的分组合并。

内容的提问来源于stack exchange,提问作者j3141592653589793238

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 08:53:26