Where am I missing something?
FUN<-list()
make.FUN<-function(i) function(n) i+n
for (i in 1:3) FUN[[i]]<-make.FUN(i)
FUN[[1]](1)
If I check FUN assignment I get a reference to a nested function (as expected):
> FUN
[[1]]
function (n)
i + n
<environment: 0x03adfad0>
[[2]]
function (n)
i + n
<environment: 0x03ae0834>
[[3]]
function (n)
i + n
<environment: 0x03ae0604>
>
Problem is that if I check:
> FUN[[1]](1)
[1] 4
>
when I expect 2! (clearly it is overwriting the last value)
On the other hand, if I manually assign for each element of the list:
FUN[[1]]<-make.FUN(1)
FUN[[2]]<-make.FUN(2)
FUN[[3]]<-make.FUN(3)
I get the correct answer:
> FUN[[1]](1)
[1] 2
> FUN[[2]](3)
[1] 5
>
I could workaround using do.call, but I can't realize what the interpreter is assuming in the first loop, or why is do.call mandatory in this case.
When I try:
FUN<-list()
make.FUN<-function(i) function(n) i+n
for (i in 1:3) FUN[[i]]<-do.call('make.FUN',list(i))
I get (as expected):
> FUN[[1]](2)
[1] 3
Any clue? (it only happens when using lists)
Your question is almost a copy-paste of the force example from the doc. You need to do:
FUN <- list()
make.FUN <- function(i) { force(i); function(n) i+n }
for (i in 1:3) FUN[[i]] <- make.FUN(i)
FUN[[1]](1)
# [1] 2
Relevant details from ?force:
force forces the evaluation of a formal argument. This can be useful if the argument will be captured in a closure by the lexical scoping rules and will later be altered by an explicit assignment or an implicit assignment in a loop or an apply function.
Related
I want to make a matrix of functions (that I wrote). Then access them element wise and call.
So I have : func1(x) , func2(y), func3(z) and func4(t) that are four R functions I wrote that work fine.They return numerics.
Now if I do:
a_matrix <- matrix(c(a=func1,b=func2,c=func3,d=func4),2,2)
a_func<-a_matrix[1,1]
a_func(x)
I get the following error:
error:attempt to call non-function.
Instead of matrix if I use list,
a_list<-list(a=func1,b=func2,c=func3,d=func4)
a_func<-list$a
a_func(x)
gives expected result
typeof(list$a)
[1] "closure"
If I do :
typeof(a_matrix)
[1] "list"
typeof(a_matrix[1,1])
[1] "list"
(am using R 3.1.1)
When you create non-atomic matrices like that, they are basically made into fancy lists. Similar rules apply to these lists as to regular lists when it comes to indexing; namely that [ ] will always return another list, and [[ ]] will extract the element without the list wrapper. You really want
func1 <- function(x) x+1
func2 <- function(x) x+2
func3 <- function(x) x+3
func4 <- function(x) x+4
a_matrix <- matrix(c(a=func1,b=func2,c=func3,d=func4),2,2)
a_func <- a_matrix[[1,1]]
a_func(5)
# [1] 6
You'd get the same results with your standard list syntax if you did
a_list <- list(a=func1,b=func2,c=func3,d=func4)
a_func <- a_list["a"]
a_func(5)
# Error: could not find function "a_func"
a_func <- a_list[["a"]]
a_func(5)
# [1] 6
When trying to create a list of similar functions using lapply, I find that all the functions in the list are identical and equal to what the final element should be.
Consider the following:
pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl
[[1]]
function (x)
pow(x, y)
<environment: 0x09ccd5f8>
[[2]]
function (x)
pow(x, y)
<environment: 0x09ccd6bc>
[[3]]
function (x)
pow(x, y)
<environment: 0x09ccd780>
When you try to evaluate these functions you get identical results:
pl[[1]](2)
[1] 8
pl[[2]](2)
[1] 8
pl[[3]](2)
[1] 8
What is going on here, and how can I get the result I desire (the correct functions in the list)?
R passes promises, not the values themselves. The promise is forced when it is first evaluated, not when it is passed, and by that time the index has changed if one uses the code in the question. The code can be written as follows to force the promise at the time the outer anonymous function is called and to make it clear to the reader:
pl <- lapply(1:3, function(y) { force(y); function(x) pow(x,y) } )
This is no longer true as of R 3.2.0!
The corresponding line in the change log reads:
Higher order functions such as the apply functions and Reduce() now
force arguments to the functions they apply in order to eliminate
undesirable interactions between lazy evaluation and variable capture
in closures.
And indeed:
pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl[[1]](2)
# [1] 2
pl[[2]](2)
# [1] 4
pl[[3]](2)
# [1] 8
When trying to create a list of similar functions using lapply, I find that all the functions in the list are identical and equal to what the final element should be.
Consider the following:
pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl
[[1]]
function (x)
pow(x, y)
<environment: 0x09ccd5f8>
[[2]]
function (x)
pow(x, y)
<environment: 0x09ccd6bc>
[[3]]
function (x)
pow(x, y)
<environment: 0x09ccd780>
When you try to evaluate these functions you get identical results:
pl[[1]](2)
[1] 8
pl[[2]](2)
[1] 8
pl[[3]](2)
[1] 8
What is going on here, and how can I get the result I desire (the correct functions in the list)?
R passes promises, not the values themselves. The promise is forced when it is first evaluated, not when it is passed, and by that time the index has changed if one uses the code in the question. The code can be written as follows to force the promise at the time the outer anonymous function is called and to make it clear to the reader:
pl <- lapply(1:3, function(y) { force(y); function(x) pow(x,y) } )
This is no longer true as of R 3.2.0!
The corresponding line in the change log reads:
Higher order functions such as the apply functions and Reduce() now
force arguments to the functions they apply in order to eliminate
undesirable interactions between lazy evaluation and variable capture
in closures.
And indeed:
pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl[[1]](2)
# [1] 2
pl[[2]](2)
# [1] 4
pl[[3]](2)
# [1] 8
When trying to create a list of similar functions using lapply, I find that all the functions in the list are identical and equal to what the final element should be.
Consider the following:
pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl
[[1]]
function (x)
pow(x, y)
<environment: 0x09ccd5f8>
[[2]]
function (x)
pow(x, y)
<environment: 0x09ccd6bc>
[[3]]
function (x)
pow(x, y)
<environment: 0x09ccd780>
When you try to evaluate these functions you get identical results:
pl[[1]](2)
[1] 8
pl[[2]](2)
[1] 8
pl[[3]](2)
[1] 8
What is going on here, and how can I get the result I desire (the correct functions in the list)?
R passes promises, not the values themselves. The promise is forced when it is first evaluated, not when it is passed, and by that time the index has changed if one uses the code in the question. The code can be written as follows to force the promise at the time the outer anonymous function is called and to make it clear to the reader:
pl <- lapply(1:3, function(y) { force(y); function(x) pow(x,y) } )
This is no longer true as of R 3.2.0!
The corresponding line in the change log reads:
Higher order functions such as the apply functions and Reduce() now
force arguments to the functions they apply in order to eliminate
undesirable interactions between lazy evaluation and variable capture
in closures.
And indeed:
pow <- function(x,y) x^y
pl <- lapply(1:3,function(y) function(x) pow(x,y))
pl[[1]](2)
# [1] 2
pl[[2]](2)
# [1] 4
pl[[3]](2)
# [1] 8
I am trying to call a function with a given string of the function name.
E.g.
print(funcList)
[[1]]
`*`
[[2]]
sin
works:
mult <- `*`
mult(5,6)
[1] 30
doesn't work:
func1 <- funcList[[1]]
func1(5,6)
func2 <- funcList[[2]]
func2(1.2)
So is it possible to call all of the functions in the functionList?
Those don't look like strings; that looks like a list of functions. To answer the question posed in your title, see get(). For example, using your list but stored as character strings:
funcList <- list("*", "sin")
we can use get() to return the function with name given by the selected element of the list:
> f <- get(funcList[[1]])
> f
function (e1, e2) .Primitive("*")
> f(3,4)
[1] 12
An alternative is the match.fun() function, which given a string will find a function with name matching that string:
> f2 <- match.fun(funcList[[1]])
> f2(3,4)
[1] 12
but as ?match.fun tells us, we probably shouldn't be doing that at the prompt, but from within a function.
If you do have a list of functions, then one can simply index into the list and use it as a function:
> funcList2 <- list(`*`, sin)
> str(funcList2)
List of 2
$ :function (e1, e2)
$ :function (x)
> funcList2[[1]](3, 4)
[1] 12
> funcList2[[2]](1.2)
[1] 0.9320391
or you can save the functions out as interim objects, but there is little point in doing this:
> f3 <- funcList2[[1]]
> f3(3,4)
[1] 12
> f4 <- funcList2[[2]]
> f4(1.2)
[1] 0.9320391
See documentation for do.call.
A quick demonstration:
do.call("rnorm", list(100, 0, 1))
first parameter can be a string literal, or R object, and the second one is list of arguments that are to be matched with provided function formal arguments.
you could also use match.fun
> functionlist <- list("*","sin")
> f <- match.fun(functionlist[[1]])
> f(5,6)
[1] 30