R: How to create a vector of functions?

I would like to create a function vector using two agruments 'func' functions, for example:

func = function(number, coefficient) { return(coefficient*number) } 

this is how i create a function vector:

 vector_of_functions = NULL for (i in 1:4) { vector_of_functions = c(vector_of_functions, function(number) func(number=number, coefficient=i)) } 

My problem is that all the functions that make up my vector are the same, even if they were created using different i-th loops. This means that they are evaluated using the last value of i (which is a global variable here).

Anyone have an idea?

thanks

+6
r
source share
3 answers

This can be solved using the eval-parse construct, although I highly recommend that you use the wrong construct. This often causes more problems than anything else. But I could not get a decent way to do this.

 vector_of_functions = NULL for (i in 1:4) { vector_of_functions = c(vector_of_functions, eval(parse(text=paste("function(number) func(number=number, coefficient=",i,")")))) } 

The reason is as Aaron explained: everything in the definition of a function is accepted in the same way as before the evaluation of a function.

A quick note: this is especially a list of functions, not a vector. It is not possible to have a function type vector. This is also completely useless, since you need to select a function using the [[]] index before you can use it. Then I just add an argument instead of defining a function for each possible value of one of the arguments.

What you want to achieve is unclear, but if you want to apply func with different coefficients, I wonder why you just don't:

 > x <- c(10,20,30) > sapply(1:4,function(y)func(number=x,coefficient=y)) [,1] [,2] [,3] [,4] [1,] 10 20 30 40 [2,] 20 40 60 80 [3,] 30 60 90 120 

Option on the topic of Marek (avoiding parsing):

 vector_of_functions = NULL for (i in 1:4) { vector_of_functions = c(vector_of_functions, eval(substitute(function(number) func(number=number, coefficient=i),list(i=i)))) } 

1L etc. you will get, just indicate that they are exact integers (which take up less memory space).

+3
source share

You can "attach" the value of i to each function by overriding i in your local environment (conveniently created by the local function in R). The resulting function with attached data is called a closure.

 > vector_of_functions = NULL > for (i in 1:4) { + vector_of_functions = c(vector_of_functions, + local({i <- i;function(number) func(number=number, coefficient=i)})) + } > vector_of_functions[[1]](1) [1] 1 > vector_of_functions[[2]](1) [1] 2 > vector_of_functions[[3]](1) [1] 3 > vector_of_functions[[4]](1) [1] 4 
+4
source share

The problem is with lazy evaluation, the variable "i" is not evaluated at every step, therefore, when the function is called, it uses the last value. The power function was created for a forced assessment in such cases (there is an example on the help page that is very similar to your question).

+2
source share

All Articles