adl*_*adl 2 iteration r function
我想每次使用函数的输出在矢量上应用相同的函数一定次数.
一个带有简单函数的简化示例,仅用于演示:
# sample vector
a <- c(1,2,3)
# function to be applied n times
f1 <- function(x) {
x^2 + x^3
}
Run Code Online (Sandbox Code Playgroud)
我想申请f1
上a
,n
次数,例如这里可以说3次.
我听说purrr::reduce
或者purrr::map()
可能是个好主意,但无法使其发挥作用.
期望的输出如果n = 3
等于f1(f1(f1(a)))
.
让我们使用Reduce
(没有外部库要求,通常表现良好).我将稍微修改该函数以接受第二个(被忽略的)参数:
f1 <- function(x, ign) x^2 + x^3
Reduce(f1, 1:3, init = a)
# [1] 1.872000e+03 6.563711e+09 1.102629e+14
Run Code Online (Sandbox Code Playgroud)
这是正在发生的事情.Reduce
:
使用二元函数连续组合给定向量的元素和可能给定的初始值.
第一个参数是要使用的函数,它应该接受两个参数.第一个是此减少中先前执行函数的值.在第一次调用函数时,它使用init=
提供的值.
第一个电话:
f1(c(1,2,3), 1)
# [1] 2 12 36
Run Code Online (Sandbox Code Playgroud)第二个电话:
f1(c(2,12,36), 2)
# [1] 12 1872 47952
Run Code Online (Sandbox Code Playgroud)第三个电话:
f1(c(12,1872,47952), 3)
# [1] 1.872000e+03 6.563711e+09 1.102629e+14
Run Code Online (Sandbox Code Playgroud)第二个参数1:3
仅用于其长度.任何适当长度的东西都会起作用.
如果您不想重新定义f1
这种减少,您可以随时进行
Reduce(function(a,ign) f1(a), ...)
Run Code Online (Sandbox Code Playgroud)
基准测试:
library(microbenchmark)
r <- Reduce(function(a,b) call("f1", a), 1:3, init=quote(a))
triple_f1 <- function(a) f1(f1(f1(a)))
microbenchmark::microbenchmark(
base = Reduce(function(a,ign) f1(a), 1:3, a),
accum = a %>% accumulate(~ .x %>% f1, .init = f1(a)) %>% extract2(3),
reduc = purrr::reduce(1:3, function(a,ign) f1(a), .init=a),
whil = {
i <- 1
a <- c(1,2,3)
while (i < 10) {
i <- i + 1
a <- f1(a)
}
},
forloop = {
out <- a
for(i in seq_len(3)) out <- f1(out)
},
evaluated = {
r <- Reduce(function(a,b) call("f1", a), 1:3, init=quote(a))
eval(r)
},
precompiled = eval(r),
anotherfun = triple_f1(a)
)
# Unit: microseconds
# expr min lq mean median uq max neval
# base 5.101 7.3015 18.28691 9.3010 10.8510 848.302 100
# accum 294.201 328.4015 381.21204 356.1520 402.6510 823.602 100
# reduc 27.000 38.1005 57.55694 45.2510 54.2005 747.401 100
# whil 1717.300 1814.3510 1949.03100 1861.8510 1948.9510 2931.001 100
# forloop 1110.001 1167.1010 1369.87696 1205.5010 1292.6500 9935.501 100
# evaluated 6.702 10.2505 22.18598 13.3015 15.5510 715.301 100
# precompiled 2.300 3.2005 4.69090 4.0005 4.5010 26.800 100
# anotherfun 1.400 2.0515 12.85201 2.5010 3.3505 1017.801 100
Run Code Online (Sandbox Code Playgroud)