R语言rlang嵌套准引用在tibble中失效,data.frame可正常运行
解决tibble与rlang准引用嵌套求值的问题
问题原因
核心问题出在quosure的环境绑定逻辑:通过enquos()捕获用户参数得到quosure列表后,将tibble(!!!dots)传入eval_in_mtcars时,enquo(expr)会把整个tibble(...)表达式包装成quosure。此时tibble求值参数时,会优先使用每个quosure自身绑定的原始环境(即wrap_in_tibble的函数环境),而非eval_tidy提供的mtcars数据环境,导致找不到mpg这类变量。
而data.frame的参数处理逻辑不同,它会自动在当前求值环境(即mtcars数据环境)中解析表达式,因此不会报错。
解决方案
不需要修改eval_in_mtcars的核心逻辑,只需调整wrap_in_tibble中传递表达式的方式,让quosures在mtcars环境中正确求值。有两种简洁的实现方式:
方式1:直接在wrap_in_tibble中完成求值
wrap_in_tibble <- function(...){ dots <- rlang::enquos(...) rlang::eval_tidy(rlang::expr(tibble::tibble(!!! dots)), data = mtcars[1:3,]) }
方式2:修改eval_in_mtcars接受表达式而非捕获参数
eval_in_mtcars <- function(expr){ rlang::eval_tidy(expr, data = mtcars[1:3,]) } wrap_in_tibble <- function(...){ dots <- rlang::enquos(...) eval_in_mtcars(rlang::expr(tibble::tibble(!!! dots))) }
验证结果
运行修正后的代码:
wrap_in_tibble(mpg * 2, cyl + 3) #> # A tibble: 3 × 2 #> `mpg * 2` `cyl + 3` #> <dbl> <dbl> #> 1 42 9 #> 2 42 9 #> 3 45.6 7
关键原理
使用rlang::expr()创建原始表达式而非通过enquo()捕获quosure,确保!!!dots注入的quosures在eval_tidy的data环境中被求值,而非绑定到原始函数环境。这样tibble就能正确识别mtcars中的变量。
内容的提问来源于stack exchange,提问作者const-ae
相关产品推荐
相关产品推荐

