R语言中如何将enquo处理后的表达式传递给子函数
解决R中上层函数向下层函数传递
enquo()处理变量的问题 这个问题的核心是**!!!只能在准引用(quasiquotation)上下文里使用**,你直接在函数调用顶层用!!!就会触发那个错误。下面给你两种最常用的推荐解决方案,根据你的实际需求选择:
方案1:上层函数不提前处理,直接传递原始表达式(推荐,适合无需预处理变量的场景)
如果上层函数不需要对变量做额外操作,完全可以把原始的变量表达式直接传给下层函数,让下层自己用enquos()处理。这里用{{ }}(embrace操作符)来传递单个变量,要是需要支持多变量,改成...会更灵活:
单变量版本
higher_function <- function(dat, variables_of_interest_in_dat){ # 用{{}}把原始表达式传递给下层,不需要提前enquos lower_function(dat, {{variables_of_interest_in_dat}}) } lower_function <- function(dat, variables_of_interest_in_dat){ variables_of_interest_in_dat <- enquos(variables_of_interest_in_dat) dat %>% select(!!!variables_of_interest_in_dat) }
多变量版本(更实用)
如果需要支持同时传多个列,把参数改成...即可:
higher_function <- function(dat, ...){ lower_function(dat, ...) } lower_function <- function(dat, ...){ vars <- enquos(...) dat %>% select(!!!vars) }
调用示例:higher_function(mtcars, cyl, disp, hp),会直接返回这三列。
方案2:上层先处理quosure,下层直接接收已处理的对象(适合需要预处理变量的场景)
如果上层函数需要对变量做验证、修改等预处理,那上层先调用enquos()得到quosure列表,然后把这个列表直接传给下层,下层就不需要再调用enquos()了:
higher_function <- function(dat, variables_of_interest_in_dat){ # 上层先处理得到quosure列表,还可以在这里加预处理逻辑 vars <- enquos(variables_of_interest_in_dat) # 直接把处理好的vars传给下层,注意参数名要对应 lower_function(dat, vars = vars) } lower_function <- function(dat, vars){ # 不需要再enquos,直接用!!!展开已有的quosure列表 dat %>% select(!!!vars) }
为什么你之前的写法会报错?
!!!是用来在准引用环境中展开quosure的(比如dplyr函数内部、expr()/enquo()内部),而你直接在lower_function()的调用顶层用!!!,不属于准引用上下文,所以R会报错"Can't use !!! at top level."。
内容的提问来源于stack exchange,提问作者SiriO
相关产品推荐
相关产品推荐

