使用 tidy_eval/rlang 上下文将函数作为参数传递
Pass function as parameter using tidy_eval/rlang context
我有一个函数,我想将一个函数传递给它。但是,我似乎无法使用 tidy_eval 上下文让它工作。
这是一些数据:
df <- tribble(
~A, ~B,
"hi", "hello",
"bye", "later"
)
我希望能够像这样调用函数:
my_quoting_fn(df, A, str_detect(., pattern = "h*"))
其中第三个参数可以是任何不同的函数。
这是我第一次尝试编写函数:
my_quoting_fn <- function(df, col, func) {
func <- enquo(func)
expr <- quo_get_expr(func)
df %>%
pull({{col}}) %>%
eval(expr)
以上给出错误:
Error in eval(., expr) : invalid 'envir' argument of type 'language'`
如果我尝试:
my_quoting_fn <- function(df, col, func) {
df %>%
pull({{col}}) %>%
{{func}}
我收到错误
Error in stri_detect_regex(string, pattern, negate = negate, opts_regex = opts(pattern)) :
object '.' not found
如果您将函数作为带有波浪号 (~
) 的公式传递,您可以使用 rlang::as_function()
.
my_quoting_fn <- function(df, col, func) {
func = as_function(func)
df %>%
pull({{col}}) %>%
func
}
my_quoting_fn(df, A, ~str_detect(., pattern = "h*"))
[1] TRUE TRUE
如果您不想使用波浪号引号,您需要引用表达式并将其解析为rlang::as_function
可以理解的形式,然后再转换它以便调用它:
library(tidyverse)
df <- tribble(
~A, ~B,
"hi", "hello",
"bye", "later"
)
my_quoting_fn <- function(df, col, func) {
func <- enexpr(func) %>% # only want the expression, not the environment of a quosure
rlang::new_formula(NULL, .) %>% # tilde-quote the expression
rlang::as_function() # make it a formula
df %>%
pull({{col}}) %>%
func()
}
my_quoting_fn(df, A, str_detect(., pattern = "h*"))
#> [1] TRUE TRUE
虽然这不是一个众所周知的成语;保持简单可能更好。
我有一个函数,我想将一个函数传递给它。但是,我似乎无法使用 tidy_eval 上下文让它工作。
这是一些数据:
df <- tribble(
~A, ~B,
"hi", "hello",
"bye", "later"
)
我希望能够像这样调用函数:
my_quoting_fn(df, A, str_detect(., pattern = "h*"))
其中第三个参数可以是任何不同的函数。
这是我第一次尝试编写函数:
my_quoting_fn <- function(df, col, func) {
func <- enquo(func)
expr <- quo_get_expr(func)
df %>%
pull({{col}}) %>%
eval(expr)
以上给出错误:
Error in eval(., expr) : invalid 'envir' argument of type 'language'`
如果我尝试:
my_quoting_fn <- function(df, col, func) {
df %>%
pull({{col}}) %>%
{{func}}
我收到错误
Error in stri_detect_regex(string, pattern, negate = negate, opts_regex = opts(pattern)) : object '.' not found
如果您将函数作为带有波浪号 (~
) 的公式传递,您可以使用 rlang::as_function()
.
my_quoting_fn <- function(df, col, func) {
func = as_function(func)
df %>%
pull({{col}}) %>%
func
}
my_quoting_fn(df, A, ~str_detect(., pattern = "h*"))
[1] TRUE TRUE
如果您不想使用波浪号引号,您需要引用表达式并将其解析为rlang::as_function
可以理解的形式,然后再转换它以便调用它:
library(tidyverse)
df <- tribble(
~A, ~B,
"hi", "hello",
"bye", "later"
)
my_quoting_fn <- function(df, col, func) {
func <- enexpr(func) %>% # only want the expression, not the environment of a quosure
rlang::new_formula(NULL, .) %>% # tilde-quote the expression
rlang::as_function() # make it a formula
df %>%
pull({{col}}) %>%
func()
}
my_quoting_fn(df, A, str_detect(., pattern = "h*"))
#> [1] TRUE TRUE
虽然这不是一个众所周知的成语;保持简单可能更好。