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

如何在dplyr::summarise中用向量元素生成分组均值变量?

问题:在dplyr::summarise中通过向量动态生成汇总变量

数据集与需求

给定数据集:

df_x <- data.frame(year = c(2000, 2000, 2000, 2001, 2001, 2001, 2002, 2002, 2002),
                   a = c(7, 3, 5),
                   b = c(5, 8, 1),
                   c = c(8, 4, 3))

以及变量名向量:

v <- c("a", "b", "c")

需求是按year分组,生成y_a、y_b、y_c三个新变量,分别对应a、b、c的均值。直接写固定变量的代码可实现需求:

y <- df_x %>% group_by(year) %>%  dplyr::summarise(y_a = mean(a, na.rm = TRUE),
                                                   y_b = mean(b, na.rm = TRUE),
                                                   y_c = mean(c, na.rm = TRUE))

但尝试通过向量v动态生成变量时出现错误:

y <- df_x %>% group_by(year) %>%  dplyr::summarise(as.name(paste0("y_", v[1])) = mean(as.name(v[1]), na.rm = TRUE),
                                                   as.name(paste0("y_", v[2])) = mean(as.name(v[1]), na.rm = TRUE),
                                                   as.name(paste0("y_", v[3])) = mean(as.name(v[1]), na.rm = TRUE))

错误信息:

Error: unexpected '=' in "y <- df_x %>% group_by(year) %>%  dplyr::summarise(as.name(paste0("y_", v[1])) ="

正确解法

方法1:使用dplyr::across(推荐,dplyr 1.0.0+)

across是dplyr专门用于批量处理变量的函数,配合all_of选择向量中的变量,再通过.names参数自动生成新变量名:

library(dplyr)

y <- df_x %>%
  group_by(year) %>%
  summarise(across(all_of(v), ~mean(.x, na.rm = TRUE), .names = "y_{.col}"))

其中.names = "y_{.col}"会将原变量名(.col)自动拼接到y_后,直接生成y_a、y_b、y_c。

方法2:使用rlang准引用语法(适合复杂动态场景)

如果需要更灵活的动态逻辑,可以结合rlang的符号转换与动态赋值语法:

library(dplyr)
library(rlang)

# 生成包含动态命名与计算逻辑的表达式列表
summarise_exprs <- set_names(
  map(v, ~expr(mean(!!sym(.x), na.rm = TRUE))),
  paste0("y_", v)
)

# 将表达式列表展开传入summarise
y <- df_x %>%
  group_by(year) %>%
  summarise(!!!summarise_exprs)
  • sym(.x)将字符串变量名转为dplyr可识别的符号
  • !!用于解引用符号,让dplyr识别为数据集中的变量
  • set_names为表达式列表绑定新变量名
  • !!!将表达式列表展开,作为summarise的参数

方法3:使用dplyr::summarise_at(旧版本兼容)

若使用较旧版本的dplyr,可通过summarise_at实现,后续再调整变量名:

y <- df_x %>%
  group_by(year) %>%
  summarise_at(v, list(y = ~mean(., na.rm = TRUE))) %>%
  rename_with(~paste0("y_", v), ends_with("_y"))

该方法已被across替代,优先推荐方法1。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 21:10:28