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

如何在R中按特定分组条件计算指定列的平均值?

R语言分组计算均值的代码优化方案

我有一个包含500多行、11列的数据框df,样本数据如下:

Subject    Group    RA    TA    Trial   VA1    VA2    VA3    VB1    VB2    VB3
1          CAI      0     1     1       6.289  5.924  7.194  4.058  9.770  -3.479
1          CAI      0     1     2       10.512 6.376  8.058  1.905  8.031  -10.698
1          CAI      0     1     3       6.554  5.046  9.482  1.825  7.152  -9.608
1          CAI      0     2     1       8.235  3.006  8.054  2.816  9.911  -4.125
1          CAI      0     2     2       6.744  2.176  9.751  3.566  12.217 -8.225
2          CAI      45    1     1       5.321  5.781  7.821  4.402  6.420  4.125
2          CAI      45    2     1       7.594  4.472  8.053  5.226  5.417  2.481
2          CAI      45    3     1       5.918  5.771  10.154 4.602  5.727  2.092
2          CAI      45    3     2       6.884  5.292  9.180  4.323  4.449  2.191

需要按Subject、Group、RA、TA组合分组,对每组内的VA1至VB3列计算所有Trial的平均值,期望输出格式如下:

Subject    Group    RA    TA    VA1    VA2    VA3    VB1    VB2    VB3
1          CAI      0     1     7.785  5.782  8.244  2.596  8.317  -7.928
1          CAI      0     2     7.490  2.591  8.902  3.191  11.064 -6.175
2          CAI      45    1     5.321  5.781  7.821  4.402  6.420  4.125
2          CAI      45    2     7.594  4.472  8.053  5.226  5.417  2.481
2          CAI      45    3     6.401  5.532  9.667  4.463  5.088  2.142

原循环代码可运行,但缺失Group列,且效率较低,原代码如下:

attach(df)

factor(Subject)
factor(Group)
factor(RA)
factor(TA)

ndf = c()
SubjList <- list(1,2)
RAList <- list(0, 45, -45)
TAList <- list(1,2,3,4)

for (S in SubjList){
  for (R in RAList){
    for (T in TAList){
      TEMP <- subset(M, (Subject == S & RA == R & TA ==T ))
      mVA1 = mean(TEMP$VA1)
      mVA2 = mean(TEMP$VA2)
      mVA3 = mean(TEMP$VA3)
      mVB1 = mean(TEMP$VB1)
      mVB2 = mean(TEMP$VB2)
      mVB3 = mean(TEMP$VB3)
      
      lst = c(S, R, T, mVA1, mVA2, mVA3, mVB1, mVB2, mVB3)
      ndf <- rbind(ndf, lst) 
    }
  }
}

原代码问题分析

  • 手动嵌套循环效率低下,500行数据会增加不必要的运行时间
  • 硬编码分组列表(SubjList、RAList等),数据新增类别时会出错
  • 未提取Group列信息,导致输出缺失该关键列
  • 使用attach()容易引发变量命名冲突,属于不推荐的写法
  • 循环中反复用rbind()拼接数据框,每次都会复制整个数据,性能损耗大

优化方案一:Base R 实现

利用aggregate()函数直接分组计算,无需手动循环:

# 定义需要计算均值的列
value_cols <- c("VA1", "VA2", "VA3", "VB1", "VB2", "VB3")
# 按指定列分组,计算均值
result_df <- aggregate(df[value_cols], 
                       by = list(Subject = df$Subject, 
                                 Group = df$Group, 
                                 RA = df$RA, 
                                 TA = df$TA),
                       FUN = mean,
                       na.rm = TRUE) # 可选:处理缺失值

# 查看结果
print(result_df)

优化方案二:Tidyverse 实现(更简洁易读)

使用dplyr包的分组聚合语法,代码更直观:

library(dplyr)

result_df <- df %>%
  group_by(Subject, Group, RA, TA) %>%
  summarise(across(c(VA1:VB3), mean, na.rm = TRUE), .groups = "drop")

# 查看结果
print(result_df)

方案说明

  • 两种方案都会自动保留Group列,无需手动处理
  • 无需硬编码分组的类别列表,自动识别数据中的所有组合
  • 避免了attach()的风险,代码更安全
  • 性能远优于手动循环,尤其是数据量较大时
  • na.rm = TRUE参数可以处理数据中的缺失值,如果数据无缺失可省略

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 11:01:02