例如,我有一个函数向量:fun_vec <- c(step1,step2,step3)
。
现在,我要像这样编写它们:step1(step2(step3(x)))
。如何使用fun_vec
执行此操作? (假设fun_vec
是不固定的,可以具有更多或更少的功能。)
答案 0 :(得分:4)
您可以使用magrittr软件包中的freduce:
fun_vec = c(function(x) x^2, function(x) sum(x), function(x) sqrt(x))
library(magrittr)
freduce(1:10, fun_vec)
或者,使用类似...的管道定义函数序列。
library(magrittr)
f = . %>% raise_to_power(2) %>% sum %>% sqrt
f(1:10)
答案 1 :(得分:4)
类似于弗兰克(Frank)使用freduce
,您可以使用Reduce
:
step1 <- function(a) a^2
step2 <- function(a) sum(a)
step3 <- function(a) sqrt(a)
steps <- list(step1, step2, step3)
Reduce(function(a,f) f(a), steps, 1:3)
# [1] 3.741657
step3(step2(step1(1:3)))
# [1] 3.741657
您可以通过以下方式看到它的“作用”:
Reduce(function(a,f) f(a), steps, 1:3, accumulate=TRUE)
# [[1]]
# [1] 1 2 3
# [[2]]
# [1] 1 4 9
# [[3]]
# [1] 14
# [[4]]
# [1] 3.741657
答案 2 :(得分:2)
看看purrr::compose
。如果您的函数存储在列表中,请使用purrr::invoke
将该列表传递给compose
:
fun_vec <- c( exp, log10, sqrt )
f <- purrr::invoke( purrr::compose, fun_vec )
f(4) # 1.35125
exp( log10( sqrt(4) ) ) # 1.35125
答案 3 :(得分:2)
这是基本的R递归方法:
compose <- function(funs) {
n <- length(funs)
fcomp <- function(x) funs[[n - 1]](funs[[n]](x))
ifelse(n > 2, compose(c(funs[1:(n - 2)], fcomp)), fcomp)
}
x <- c(sqrt, log, exp)
compose(x)(2)
# [1] 1.414214
sqrt(log(exp(2)))
# [1] 1.414214
如果funs
中的函数数量大于两个,我们通过将最后两个函数替换为它们的组成,将列表缩短一个。否则,我们返回剩下的最后两个的组成。假设最初funs
中至少有两个函数。