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

如何在dplyr函数中动态组合任意数量变量计算均值

动态计算分组内指定模式列的均值(R语言)

问题背景

需按固定列(A、B)对数据框分组,计算每组中所有以L开头的列的整体均值(将组内所有L列的非NA值合并后求均值),但L开头的列数是动态变化的,无法硬编码列名适配不同数据集。

测试数据

创建测试数据框

# 创建测试数据框
tdf <- data.frame(
  A = c('a','a','b','b','b'), 
  B = c('d','d','e','e','f'),
  L1 = as.numeric(c(1,2,3,4,5)), 
  L2 = as.numeric(c(11,12,13,'na',15)),
  L3 = as.numeric(c('na',22,23,'na',25)), 
  stringsAsFactors = FALSE
)

生成的数据结构

A B L1 L2 L3
1 a d  1 11 NA
2 a d  2 12 22
3 b e  3 13 23
4 b e  4 NA NA
5 b f  5 15 25

预期结果

按A、B分组后,每组所有L列非NA值的均值:

A B mean_L
1 a d   9.60
2 b e  10.75
3 b f  15.00

现有方法的局限

已能通过硬编码L列名实现需求,但无法适配动态列数:

library(dplyr)
# 硬编码列名的可行方法
tdf %>% group_by(A,B) %>% summarize(mean_L=mean(c(L1,L2,L3), na.rm=TRUE))

当L列数量变化时,无法动态传入列名列表。

解决方案

方法1:dplyr 1.0.0+ 原生支持(推荐)

利用c_across动态选择列并合并为向量,结合列选择语法匹配L开头的列:

library(dplyr)

tdf %>%
  group_by(A, B) %>%
  summarize(mean_L = mean(c_across(starts_with("L")), na.rm = TRUE))

starts_with("L")会自动匹配所有以L开头的列,无需硬编码列名。

方法2:tidyr重塑数据后计算

先将宽格式转为长格式,再分组计算,逻辑直观:

library(tidyr)
library(dplyr)

tdf %>%
  pivot_longer(cols = starts_with("L"), names_to = "L_col", values_to = "value") %>%
  group_by(A, B) %>%
  summarize(mean_L = mean(value, na.rm = TRUE))

方法3:基础R实现(无依赖)

用基础R工具匹配列名并分组计算:

# 获取所有L开头的列名
L_cols <- grep("^L", names(tdf), value = TRUE)

# 按A、B分组计算
aggregate(. ~ A + B, data = tdf[, c("A", "B", L_cols)], 
          FUN = function(x) mean(unlist(x), na.rm = TRUE)) %>%
  rename(mean_L = L1)  # 重命名结果列

方法4:data.table(大数据场景高效)

适合处理超大规模数据集,运行效率更高:

library(data.table)

setDT(tdf)
L_cols <- grep("^L", names(tdf), value = TRUE)

tdf[, .(mean_L = mean(unlist(.SD), na.rm = TRUE)), 
    by = .(A, B), .SDcols = L_cols]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 07:50:28