I would like to create a vector of functions using a two agruments function 'func', for instance this one:
func = function(number, coefficient) {
return(coefficient*number)
}
here is how I create the vector of functions:
vector_of_functions = NULL
for (i in 1:4) {
vector_of_functions = c(vector_of_functions,
function(number) func(number=number, coefficient=i))
}
My issue is that all functions that compose my vector are the same, even if they have been created using different i through the loop. It seams that they are evaluated using the last value of i (which is here a global variable).
Anybody has an idea?
Thanks
You can "attach" the value of i
to each function by redefining i
in its own local environment (conveniently created by the function, local
in R). The resulting function with data "attached" 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
This can be solved using an eval-parse construct, although I strongly advice you not to use this construct. It often causes more problems than anything else. But I couldn't get a decent do.call way of doing it.
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,")"))))
}
Reason is as Aaron explained: everything within the function definition is taken as is until the function evaluation.
Small remark: this is especially a list of functions, and not a vector. It's impossible to have a vector of type "function". It's also absolutely useless, as you have to select the function using the index [[]] before you can use it. Then I'd just add the argument instead of defining a function for every possible value of one of the arguments.
So what you want to achieve is unclear, but if you want to apply func with different coefficients, I wonder why you don't simply do:
> 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
A variation on the theme by Marek (avoiding the 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))))
}
The 1L etc. you get, just indicate they're exact integers (that take less memory space).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With