在R中:将函数列表转换为一个大函数(元素的函数和)

时间:2014-04-26 08:35:50

标签: r list function

我有功能列表,我想将其添加到一个“大”功能中。例如:

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之前已经计算过。

4 个答案:

答案 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