多次调用函数而不复制它(使用 %>%)

Call function many times without duplicate it (with %>%)

假设我们有 3 个具有这种最小功能的函数:

func1 <- function (x) {
  x + 1
}

func2 <- function (x, plus = T) {
  if (plus == TRUE) {
    x + 2
  } else {
    x - 5 
  }
}

func3 <- function (x) {
  x + 3
}

我想像这样使用竖线 (%>%) 运算符将此函数相互嵌套:

library(magrittr)

func1(0) %>% func2(plus = T) %>% func2(plus = F) %>% func3
# result: 1

它的等效版本是:

func3(func2(func2(func1(0), plus = T), plus = F))
# result: 1

我试图找到一种不需要复制 func2() 函数的方法(因为我必须多次 运行 而且我想更改函数调用的次数和动态参数)。目前我不是应用函数或地图包的大专家,但我想至少其中之一可以完成这项工作。

这当然只是一个虚拟示例,我的真实代码要复杂得多,我只是尝试简化我的问题以找到解决方案。

我必须使用管道运算符,所以我只对同样适用于管道的解决方案感兴趣。

编写一个函数,将初始 x 和结果馈送到 func2 并循环遍历这些结果:

func2_iterate = function(x, outcomes){
  for (i in 1:length(outcomes)){
    x = func2(x, outcomes[i])
  }
  return(x)
}

然后运行(如上func1func2func3):

func1(0) %>% func2_iterate(c(T, F)) %>% func3
#result: 1

我还想指出,在这种特殊情况下,func2_iterate 的输出只是它的输入,加上 2 乘以 [=20] 中 T 的数量=],减去 5 乘以 outcomes 中的 F 的数量。但我假设你实际上有一些功能可以做更复杂的事情。

使用 partial / compose / invoke 组合:

library(tidyverse)
f2b <- invoke(compose, map(c(F,T), ~substitute(partial(func2, plus =.), lst(.))))

func1(0) %>% f2b %>% func3
# [1] 1