我有功能列表,我想将其添加到一个“大”功能中。例如:
funlist=list()
funlist[[1]]=exp(x1)
funlist[[2]]=sin(x2)
期望的结果:
bigfun = exp(x1) + sin(x2)
我知道对于数字案例,可以使用reduce("+", list)
,但是如上所述的非数字案例呢?
请注意:我正在寻找一般的自动化解决方案,即功能列表可能不同(功能本身和列表长度/功能数量),但列表的所有功能必须添加到最后一个术语到底。每个函数都应该有自己必须提供的值(例如x1到funlist [[1]],x2到funlist [[2]]等等。
重要提示:然后将bigfun术语传递给优化器(optim),以找到每个函数的最佳值,从而最大限度地提高所有函数的结果。
编辑: 为简单起见,我选择了fucntions exp(x1)和sin(x2)。这些函数本身就是函数包装器,例如 函数(x){y1 * x + y2 * x ^ 2 + y3 * x ^ 3},其中y1,y2,y3之前已经计算过。
答案 0 :(得分:3)
这是一种函数式编程方法,可以将函数存储在列表中。
funs <- c(sin,exp)
bigfun<-function(x,funs){
sum(sapply(funs, function(f) f(x)))}
bigfun(x=10,funs=funs)
从Hadley Wickham那里了解到: http://adv-r.had.co.nz/Functional-programming.html#lists-of-functions
**编辑**提供多个值(即每个函数的值不同):
bigfun2<-function(vec,funs){vf<-function(vec,funs){funs(vec)}
sum(sapply(1:length(vec),function (i) vf(vec[i],funs[[i]])))}
optim(par=initvec,fn=bigfun2,funs=funs)
这假设您有一个等于数据向量长度的函数列表,其中funs
是您的函数列表,vec
是您的数据向量。在优化示例中,只需将矢量initvec
设置为初始值等于funs
的初始值,将其作为附加参数传递给optim
答案 1 :(得分:3)
这是一个功能,它将获取一系列函数并返回一个计算其总和的函数:
add.funs <- function(funlist) {
function(...) Reduce(`+`, lapply(funlist, do.call, as.list(...)))
}
例如:
funlist=list()
funlist[[1]] <- function(x) {5*x + 2*x^2 + 3*x^3}
funlist[[2]] <- function(x)sin(x)
bigfun <- add.funs(funlist)
bigfun(3)
# [1] 114.1411
确实与:
相同funlist[[1]](3) + funlist[[2]](3)
# [1] 114.1411
编辑:对于每个函数的单个不同参数,请尝试:
add.funs <- function(funlist) {
function(...) {
arglist <- lapply(as.list(...), as.list)
Reduce(`+`, Map(do.call, funlist, arglist))
}
}
bigfun <- add.funs(funlist)
bigfun(c(3, 4))
# [1] 113.2432
funlist[[1]](3) + funlist[[2]](4)
# [1] 113.2432
答案 2 :(得分:0)
这样的事情怎么样:
让我们说这些函数存储为字符串:
funlist=list()
funlist[[1]]="exp(x)"
funlist[[2]]="sin(x)"
您可以组合字符串,然后解析+ eval:
eval(parse(text=paste("bigfun <- function(x)", do.call(paste,c(funlist,sep="+")))))
答案 3 :(得分:0)
另见:
make_bigfun <- function(..., sep = " + ") {
funlist = list(...)
ff = function() NULL
environment(ff) = parent.frame()
formals(ff) = unlist(lapply(funlist, formals))
body(ff) = parse(text = do.call(paste, c(lapply(funlist, function(x) deparse(body(x))), sep = sep)))
return(ff)
}
make_bigfun(function(x1) exp(x1), function(x2) sin(x2), function(x3) cos(x3))
#function (x1, x2, x3)
#exp(x1) + sin(x2) + cos(x3)
do.call(make_bigfun, c(list(function(x1) exp(x1), function(x2) sin(x2)), sep = " - "))
#function (x1, x2)
#exp(x1) - sin(x2)
bigfun = make_bigfun(function(x1) exp(x1), function(x2) sin(x2))
identical(exp(1) + sin(2), bigfun(1,2))
#[1] TRUE