Reputation: 157
I have two lists of functions that I try to combine to one list of functions (one nested in the other).
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}
The lists will have the same length. Desired outcome is another function list:
finalfun=list()
finalfun[[1]] which shall be the same as funlist[[1]](anotherlist[[1]])
...
Hence, if I called
finalfun[[1]](6)
, I would get the result "6" [2*(0.5*6)], similar to calling:
funlist[[1]](anotherlist[[1]](6))
I tried the following to create a function that nests two input functions:
nestfun <- function(infun,outfun) {lapply(1:length(infun),function(i){outfun[[i]](infun[[i]])})}
test=nestfun(infun=anotherlist, outfun=funlist)
Which produced an error:
Error in 2 * x1 : non-numeric argument to binary operator
Called from: lapply(1:length(infun), function(i) {
outfun[[i]](infun[[i]])
})
What am I overlooking?
Upvotes: 1
Views: 155
Reputation: 1584
This should work:
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
Note that finalfun
is a list of closures. The function fnest
takes two functions as inputs and returns a composite function (a closure).
It's now trivial to create a function that operates on your two function lists:
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)
EDIT: In case people are curious about the use of force()
, check out this question on lazy evaluation: Explain a lazy evaluation quirk
Upvotes: 1
Reputation: 115392
Here is an approach that uses Compose
from the functional package. Note, due to lazy evaluation you need to force
the arguments
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
Upvotes: 1