gpt4 book ai didi

r - 如何使用 Reduce 从函数列表中创建新函数?

转载 作者:行者123 更新时间:2023-12-01 08:06:11 24 4
gpt4 key购买 nike

我想添加一些函数 f1,f2,...,fn 以便我有一个新函数,它产生 f(x)=f1(x)+...+fn(x) (称为逐点加法)。所以我有一个功能列表并尝试过

Reduce("funadd",fun.list)

其中 funadd 定义为

funadd <- function(f1,f2){
retfun <- function(x){
f1(x)+f2(x)
}
retfun
}

在两个函数上测试 funadd 时,它可以完美运行。但是,当我尝试评估 Reduce 命令的结果时,我得到了错误

Error: evaluation nested too deeply: infinite recursion / options(expressions=)?

最佳答案

有趣的是Reduce不起作用...请注意,“手动减少”有效:

f <- function(x) x^2
g <- function(x) x^3
h <- function(x) x^4
x <- runif(3)

f(x)+g(x)+h(x)
#[1] 0.9760703 0.1873004 0.1266966

funadd(funadd(f,g),h)(x)
#[1] 0.9760703 0.1873004 0.1266966

或者,你可以使用这个:

funadd2 <- function(...){
function(x) Reduce(`+`, lapply(list(...), function(f) f(x)))
}

funadd2(f,g,h)(x)
#[1] 0.9760703 0.1873004 0.1266966

编辑:这是怎么回事:

查看 Reduce 的源代码,我们可以看到它(大致)有一个循环这样做:

init <- f
init <- funadd(init, g)

如果有更多元素(init <- funadd(init, h),...),则继续。

这会导致对 f 的引用在第一次循环迭代中丢失:

init(x)
# Error: evaluation nested too deeply: infinite recursion / options(expressions=)?

发生这种情况是因为 f1在最后 retfun指向自己:

identical(environment(init)$f1, init, ignore.environment=FALSE)
# [1] TRUE

正如@Vincent 发现的那样,这也可以通过强制参数来解决,即通过制作一个避免对 f1 进行惰性求值的本地副本来解决。和 f2 :

funadd3 <- function(f1,f2){
f1.save <- f1
f2.save <- f2
retfun <- function(x){
f1.save(x)+f2.save(x)
}
retfun
}

Reduce(funadd3, list(f,g,h))(x)
# [1] 0.9760703 0.1873004 0.1266966

关于r - 如何使用 Reduce 从函数列表中创建新函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18741070/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com