如何编写可像dplyr一样接受列名的R语言函数?
实现dplyr风格的列名参数传入
方法1:用rlang的tidyeval工具(推荐)
这是tidyverse系列包的底层实现逻辑,能完美支持列名自动补全,还不用传字符串。
具体操作:
- 用
enquos()捕获传入的列名表达式(就是你写的不带引号的列名) - 用
!!!把捕获的表达式拼接到数据框操作里
依赖dplyr的版本
library(rlang) library(dplyr) func <- function(df, ...) { # 捕获列名参数 vars <- enquos(...) # 提取指定列并返回前几行 head(select(df, !!!vars)) } # 直接写列名就行,还支持自动补全 func(mtcars, mpg, cyl)
不依赖dplyr的版本
如果不想引入dplyr,用base R处理也可以:
library(rlang) func <- function(df, ...) { vars <- enquos(...) # 把捕获的表达式转成字符串列名 var_names <- sapply(vars, as_label) head(df[, var_names, drop = FALSE]) } func(mtcars, mpg, cyl)
方法2:用base R原生方法(无额外依赖)
不想加包的话,用substitute()和match.call()也能实现,只是自动补全的支持稍弱:
func <- function(df, ...) { # 获取调用时传入的列名参数 args <- match.call(expand.dots = FALSE)$... # 把参数转成字符串列名 var_names <- sapply(args, deparse) head(df[, var_names, drop = FALSE]) } # 同样可以直接传列名 func(mtcars, mpg, cyl)
注意点
- 核心是用
...接收列名参数,再配合表达式解析工具处理,就能摆脱字符串传参 - 要IDE自动补全的话,优先选tidyeval方案,RStudio这类IDE对它的补全支持更好
内容的提问来源于stack exchange,提问作者Claudio Paladini
相关产品推荐
相关产品推荐

