I am trying to write a custom function where I want to use the cor.test function but I am having trouble unquoting the needed arguments to create a working formula.
Here is what I currently have that doesn't work-
library(rlang)
# custom function
tryfn <- function(data, x, y) {
stats::cor.test(
formula = rlang::new_formula(NULL, {{ x }} + {{ y }}),
data = data,
method = "pearson"
)
}
# using the function
tryfn(mtcars, wt, mpg)
#> Error in rlang::new_formula(NULL, {: object 'wt' not found
Run Code Online (Sandbox Code Playgroud)
I tried this way because it seems to work if I don't have to unquote the formula in the function environment.
# without unquoting inside another function
print(rlang::new_formula(NULL, quote(x + y)))
#> ~x + y
Run Code Online (Sandbox Code Playgroud)
Any ideas on how to implement this?
请记住,这rlang::quo与并不相同base::quote。实际上,后者最终基本上等于rlang::expr。插值法{{会在其对应的环境中创建目标,因此它是类似以下情况的快捷方式:
x <- 0
with_curly <- function(foo) {
x <- 1
rlang::eval_tidy({{ foo }})
}
with_curly(x)
# 0
with_enquo <- function(foo) {
x <- 1
rlang::eval_tidy(rlang::enquo(foo))
}
with_enquo(x)
# 0
Run Code Online (Sandbox Code Playgroud)
另一方面,enexpr行为类似于,quote但对于用户键入的内容:
with_enexpr <- function(foo) {
x <- 1
rlang::eval_tidy(rlang::enexpr(foo))
}
with_enexpr(x)
# 1
Run Code Online (Sandbox Code Playgroud)
以我的经验,在不显式支持它们的函数中,quores不能很好地发挥作用(或根本不起作用),并且许多R函数期望“ raw”表达式。即使在打印过程中,您也可以看到它们没有得到相同的处理:
foo <- function(foo) {
rlang::qq_show({{ foo }})
rlang::qq_show(!!rlang::enexpr(foo))
invisible()
}
foo(x)
# ^x
# x
Run Code Online (Sandbox Code Playgroud)
这意味着,至少到目前为止,创建简单表达式没有捷径,您将需要做很长的路要走:
编辑:并不完全正确。简单表达式没有捷径,但是您仍然可以创建带有等式的公式。请参阅穆迪的答案和下面的评论。
有时也应该退后一步,并记住您并不需要到处都进行非标准评估:
tryfn <- function(data, x, y) {
stats::cor.test(
formula = as.formula(glue::glue("~ {x} + {y}")),
data = data,
method = "pearson"
)
}
tryfn(mtcars, "wt", "mpg")
Run Code Online (Sandbox Code Playgroud)