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

使用dplyr的summarise实现多层级均值聚合的简便方法

如何在dplyr中同时获取分组整体均值与子组均值?

你遇到的痛点我太懂了——重复写分组代码或者重构数据确实麻烦,其实用dplyr本身的功能就能轻松搞定,不用额外绕路。先回顾下你的示例数据:

dta <- read.table(header=TRUE, text='
subject sex condition measurement
1 M control 7.9
1 M cond1 12.3
1 M cond2 10.7
2 F control 6.3
2 F cond1 10.6
2 F cond2 11.1
3 F control 9.5
3 F cond1 13.1
3 F cond2 13.8
4 M control 11.5
4 M cond1 13.4
4 M cond2 12.9
')

下面是三个简便的解决方案:

方法一:合并不同分组的结果(最直观)

先单独计算按sex的整体均值,给condition列标记为"total",再和按sex+condition分组的子组均值合并,最后排序让结果更清晰:

library(dplyr)

combined_means <- dta %>%
  # 计算按sex的整体均值,标记condition为total
  group_by(sex) %>%
  summarise(
    condition = "total",
    mean = mean(measurement),
    .groups = "drop"
  ) %>%
  # 合并子组均值
  bind_rows(
    dta %>%
      group_by(sex, condition) %>%
      summarise(mean = mean(measurement), .groups = "drop")
  ) %>%
  # 按sex和condition排序,方便查看
  arrange(sex, condition)

print(combined_means)

输出结果会同时包含每个sex的整体均值,以及每个sex下不同condition的分组均值:

# A tibble: 8 × 3
  sex   condition  mean
  <chr> <chr>     <dbl>
1 F     cond1      11.9
2 F     cond2      12.5
3 F     control     7.9
4 F     total      10.7
5 M     cond1      12.9
6 M     cond2      11.8
7 M     control     9.7
8 M     total      11.4

方法二:单次分组内同时计算两种均值(更紧凑)

利用dplyr的summarise配合across,在按sex分组的同时,一次性计算整体均值和各个condition的子组均值,最后转成长格式让结构统一:

library(dplyr)
library(tidyr) # 仅用于转长格式,可选

combined_means <- dta %>%
  group_by(sex) %>%
  summarise(
    # 先计算整体均值
    mean_total = mean(measurement),
    # 遍历每个condition,计算对应子组的均值
    across(unique(condition), ~mean(measurement[condition == .x]), .names = "mean_{.x}")
  ) %>%
  # 转成长格式,和方法一的输出结构一致
  pivot_longer(
    cols = starts_with("mean_"),
    names_to = "condition",
    values_to = "mean",
    names_prefix = "mean_"
  ) %>%
  arrange(sex, condition)

print(combined_means)

这个方法的好处是只需要一次主分组,后续转长格式也只是为了统一结果结构,如果能接受宽格式的话,转长步骤可以省略。

方法三:用group_modify批量处理(适合复杂场景)

如果后续还要添加更多统计量(比如标准差、样本量),group_modify会更灵活——它允许你对每个sex分组单独处理,同时返回整体和子组的统计结果:

library(dplyr)

combined_means <- dta %>%
  group_by(sex) %>%
  group_modify(~ {
    # 计算当前sex的整体均值
    total_mean <- tibble(condition = "total", mean = mean(.x$measurement))
    # 计算当前sex下各condition的子组均值
    group_means <- .x %>%
      group_by(condition) %>%
      summarise(mean = mean(measurement), .groups = "drop")
    # 合并两个结果
    bind_rows(total_mean, group_means)
  }) %>%
  ungroup() %>%
  arrange(sex, condition)

print(combined_means)

这个方法扩展性很强,比如你想同时添加标准差,只需要在两个tibble里加上sd = sd(measurement)即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:20:54