R:使用公式符号定义函数,如purrr::map(.f=)

R: Use formula notation to define a function, like purrr::map(.f=)

在 gtsummary 包中,有许多函数将其他函数作为参数。目前,用户必须传递一个适当的函数,但我想更新以允许用户使用公式语法使用快捷符号传递函数(类似于 purrr::map() 允许用户传递 purrr::map(.f = mean)purrr::map(.f = ~mean(.x))。整个 tidyverse 中还有其他函数,例如,在 dplyr 中使用类似的符号。这是 purrr::map() 帮助文件中的描述:

我写了一个将公式语法转换成新函数的小函数。但是,这只接受点符号(例如 ~mean(.))。我如何将其概括为接受 ..x..1?在我的用例中,我需要用 foo(1:5) 调用它们(不引用参数名称),并且该函数只有一个参数。

# convert a formula to a function
formula_to_function <- function(x) {
  function(.) eval(rlang::f_rhs(x), list(.))
}

# create a new function that is the mean of a vector
foo <- formula_to_function(~mean(., na.rm= TRUE))

# evaluate function
foo(1:5)
#> [1] 3

reprex package (v0.3.0)

于 2020-07-03 创建

谢谢!

在内部,purrr::map 使用 purrr::as_mapper.f 参数解析为函数。参见 here (line 110). So one option is to directly use purrr::as_mapper in your function, or you can try to rewrite as_mapper yourself (here's the implementation)。

gsubfn 中的

match.funfn 类似于 base R 中的 match.fun 除了它还接受公式。该公式可以使用任何变量,并且任何自由变量(使用但未定义)都被假定为遇到顺序中的参数。

library(gsubfn)

f <- function(x, y, z, fun) {
  fun <- match.funfn(fun)
  fun(x, y, z)
}

# test
f(1, 2, 3, ~ a + b + c)
## [1] 6

您可以选择在公式的左轴上指定参数

# same
f(1, 2, 3, a + b + c ~ a + b + c)
## [1] 6

或者传递一个函数

# same
f(1, 2, 3, function(a, b, c) a + b + c)
## [1] 6

还有其他功能,因此请参阅 gsubfn 包文档了解更多信息。

也可以将公式作为函数参数传递给一般函数,方法是在函数前面加上 fn$ 调用。

library(gsubfn)

f2 <- function(x, y, z, fun) {
  fun(x, y, z)
}

fn$f2(1, 2, 3, ~ a + b + c)
## [1] 6