在R语言中如何通过tidyeval向函数传递多个变量名
用tidyeval通过
...传递多个变量名到函数 你可以通过enquos()函数捕获...中的变量表达式,再用!!!(非拼接运算符)将其展开传递给across,就能实现以独立参数形式传入多个分析变量的需求。
修正后的函数实现如下:
library(dplyr) a_summary_fn <- function(the_data, the_group, ...) { # 捕获...中的所有变量表达式 analysis_vars <- enquos(...) the_data |> group_by({{the_group}}) |> summarize( across( !!!analysis_vars, # 展开捕获的变量列表 list( mean = ~mean(., na.rm = TRUE), sd = ~sd(., na.rm = TRUE), n = ~sum(!is.na(.)) ) ) ) |> mutate(across(ends_with(c("_mean", "_sd")), ~round(., digits = 3))) } # 调用示例 a_summary_fn(mtcars, cyl, disp, hp)
关键逻辑说明:
- 捕获变量:
enquos(...)会把你通过...传入的每个变量(如disp、hp)转换成带环境上下文的quosure对象,打包成列表存储。 - 展开变量:
!!!运算符的作用是把这个quosure列表"拆解",让across能够逐个识别这些变量,效果等价于手动写c(disp, hp)。
在较新版本的dplyr中,也可以用更简化的写法,直接在across里使用c(...),dplyr会自动处理其中的变量表达式:
a_summary_fn <- function(the_data, the_group, ...) { the_data |> group_by({{the_group}}) |> summarize( across( c(...), # 直接用c(...)组合变量 list( mean = ~mean(., na.rm = TRUE), sd = ~sd(., na.rm = TRUE), n = ~sum(!is.na(.)) ) ) ) |> mutate(across(ends_with(c("_mean", "_sd")), ~round(., digits = 3))) }
两种写法都支持你想要的调用方式:a_summary_fn(mtcars, cyl, disp, hp)。其中enquos()的写法更符合tidyeval规范,也更灵活——它还支持传入带运算的表达式(比如disp/100这类)。
内容的提问来源于stack exchange,提问作者itsMeInMiami
相关产品推荐
相关产品推荐

