【问题标题】:in R: nest two lists of functions and return combined functions in a list在 R 中:嵌套两个函数列表并在列表中返回组合函数
【发布时间】:2014-06-12 16:25:44
【问题描述】:

我有两个函数列表,我尝试将它们组合到一个函数列表中(一个嵌套在另一个函数列表中)。

funlist=list()
funlist[[1]] <- function(x1){2*x1}
funlist[[2]] <- function(x2){3*x2}

anotherlist=list()
anotherlist[[1]]=function(y1){0.5*y1}
anotherlist[[2]]=function(y2){0.7*y2}

列表的长度相同。期望的结果是另一个函数列表:

finalfun=list()
finalfun[[1]] which shall be the same as funlist[[1]](anotherlist[[1]])
...

因此,如果我打电话 finalfun[[1]](6),我会得到结果“6”[2*(0.5*6)],类似于调用:

 funlist[[1]](anotherlist[[1]](6))

我尝试了以下方法来创建一个嵌套两个输入函数的函数:

nestfun <- function(infun,outfun) {lapply(1:length(infun),function(i){outfun[[i]](infun[[i]])})}   
test=nestfun(infun=anotherlist, outfun=funlist)

产生错误:

Error in 2 * x1 : non-numeric argument to binary operator
Called from: lapply(1:length(infun), function(i) {
    outfun[[i]](infun[[i]])
})

我忽略了什么?

【问题讨论】:

  • dput() 是你的朋友,还有这个关于制作minimal reproducible example 的精彩常见问题解答
  • 我编辑了上面的例子。现在您可以重现该错误。但是,问题并不是真正的错误本身,而是我的函数式编程方法中的一些错误。即使没有“可重复的示例”,人们也可以看到这一点(尽管我同意,如果可能的话,应该始终提供一个——这就是我重新编辑文本的原因)。
  • 参见?mapply,它可以“成对”处理两个列表。
  • 创建列表时是否必须使用匿名函数?还是您引用命名函数?
  • Ben,是的,不幸的是我需要匿名函数(它们是闭包——之前由其他函数编写的函数)。感谢您昨天的帮助 - 如您所见,我尝试将您的解决方案应用于此案例,但不幸的是失败了:/

标签: r list function functional-programming nested


【解决方案1】:

这应该可行:

fnest<-function(f1,f2){  
force(f1)
force(f2)
nest<-function(x) f1(f2(x))}

finalfun<-list()
finalfun<-lapply(1:length(funlist), function (i) fnest(funlist[[i]], anotherlist[[i]]) )

finalfun[[2]](10)
#21

请注意,finalfun 是一个闭包列表。函数fnest 接受两个函数作为输入并返回一个复合函数(闭包)。

现在创建一个在两个函数列表上运行的函数很简单:

nestfun<-function(funlist,anotherlist){
fnest<-function(f1,f2){  
force(f1)
force(f2)
nest<-function(x) f1(f2(x))}

finalfun<-list()
finalfun<-lapply(1:length(funlist), function (i) fnest(funlist[[i]], anotherlist[[i]]) ) }

finalfun<-list()
finalfun<-nestfun(funlist,anotherlist)

编辑:如果人们对 force() 的使用感到好奇,请查看关于惰性评估的这个问题:Explain a lazy evaluation quirk

【讨论】:

  • 谢谢本!伟大的工作 - 通常,想知道为什么必须在两种解决方案中都使用武力(这里和下面的 mnel)。
  • 感谢您的链接/补充说明,本!
【解决方案2】:

这是一种使用功能包中的Compose 的方法。请注意,由于延迟评估,您需要 force 参数

library(functional)
Composed <- Map(function(x, y) {
  x <- force(x)
  y <- force(y)
   Compose(y, x)}, 
 funlist,anotherlist)
# A Couple of examples
Composed[[1]](6) 
# [1] 6
Composed[[2]](6)
# [1] 12.6

【讨论】:

  • 谢谢你!工作得很好。简洁明了的解决方案(我了解了一个要查看的新软件包)。请原谅我决定接受 Ben 的回答作为选定的解决方案 - 我只是喜欢您在他的方法中不需要另一个包。
猜你喜欢
  • 1970-01-01
  • 2018-11-17
  • 2012-08-31
  • 2019-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多