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

如何在dplyr中实现含重叠类别的复杂分组(替代rbind)

问题描述

我有一个包含gr1、gr2和both分组的数据集,需要按c("gr1", "both")和c("gr2", "both")对gr列进行分组计算x的总和。目前我通过拆分过滤再rbind的方式实现了需求,但想知道能不能在dplyr里直接指定这些分组组合,不用手动拼接结果?

原始实现代码:

library(tidyverse)
set.seed(1234)

df = data.frame(x = 1:10, id = sample(LETTERS[1:3], size = 10, replace = TRUE),
           gr = c(rep("gr1",3), rep("gr2",4),rep("both",3)))

sum.gr1 = df %>% 
  filter(gr %in% c("gr1", "both")) %>% 
  group_by(id) %>% 
  summarize(x.sum = sum(x)) %>% 
  mutate(gr.filt = "gr1.both")

sum.gr2 = df %>% 
  filter(gr %in% c("gr2", "both")) %>% 
  group_by(id) %>% 
  summarize(x.sum = sum(x))%>% 
  mutate(gr.filt = "gr2.both")

df.gr = rbind(sum.gr1, sum.gr2)
df.gr
解决方案

可以用以下几种方法在dplyr中直接实现,无需手动拆分再拼接:

方法1:用map_dfr遍历分组组合

预先定义好需要的分组组合列表,用map_dfr自动遍历处理并合并结果,.id参数直接生成分组标识列:

library(tidyverse)
set.seed(1234)

df = data.frame(x = 1:10, id = sample(LETTERS[1:3], size = 10, replace = TRUE),
           gr = c(rep("gr1",3), rep("gr2",4),rep("both",3)))

# 定义分组组合,键作为分组标识
gr_groups = list(
  gr1.both = c("gr1", "both"),
  gr2.both = c("gr2", "both")
)

# 遍历组合并自动合并结果
df.gr = map_dfr(gr_groups, function(target_grs) {
  df %>%
    filter(gr %in% target_grs) %>%
    group_by(id) %>%
    summarize(x.sum = sum(x))
}, .id = "gr.filt")

# 查看结果
df.gr

运行后得到的结果和原始方法完全一致,而且新增分组组合时只需要修改gr_groups列表即可,扩展性更强。

方法2:用crossing生成组合后逐行计算

先生成所有id和分组类型的笛卡尔积,再按行匹配对应的分组规则计算总和:

df.gr = crossing(
  id = unique(df$id),
  gr.filt = c("gr1.both", "gr2.both")
) %>%
  mutate(
    # 为每个分组类型匹配对应的gr列表
    target_grs = case_when(
      gr.filt == "gr1.both" ~ list(c("gr1", "both")),
      gr.filt == "gr2.both" ~ list(c("gr2", "both"))
    )
  ) %>%
  rowwise() %>%
  mutate(
    # 计算当前id在对应分组下的x总和
    x.sum = sum(df$x[df$id == id & df$gr %in% target_grs])
  ) %>%
  ungroup() %>%
  select(-target_grs)

df.gr

这种方法不需要多次过滤原数据集,适合数据量较大的场景。

内容的提问来源于stack exchange,提问作者M. Beausoleil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 19:57:33