Reputation: 33
Defining multiple functions in a loop:
par <- 1:2 #parameters for functions
qF <- list() #list I will write the functions into
for(i in 1:2){
qF[[i]] <- function(p){qnorm(p, mean = par[i])}
}
My result:
>qF
[[1]]
function (p)
{
qnorm(p, mean = par[i])
}
[[2]]
function (p)
{
qnorm(p, mean = par[i])
}
The functions are the same! What I WANT my result to be:
>qF
[[1]]
function (p)
{
qnorm(p, mean = par[1])
}
[[2]]
function (p)
{
qnorm(p, mean = par[2])
}
Is there any way to do this?
Upvotes: 3
Views: 1904
Reputation: 32426
If you want to create the functions dynamically you need for the par[i]
to evaluate each time, otherwise all the par[i]
will be evaluated when the functions are called, and i
will be the value at the end of the loop.
for(i in 1:2){
qF[[i]] <- local({
mu <- par[i]
function(...) { qnorm(..., mean = mu) }
})
}
You could also substitute
the variable into the function body
for(i in 1:2){
qF[[i]] <- eval(substitute(
function(...) qnorm(..., mean = mu)), list(mu=par[i]))
}
And you can see what mu
is in each function's environment
sapply(qF, function(f) mget("mu", environment(f)))
# $mu
# [1] 1
#
# $mu
# [1] 2
Upvotes: 3
Reputation: 31171
You can do:
library(functional)
funcs = lapply(1:2, function(u) Curry(qnorm, mean=u))
funcs[[1]](0.77)
#[1] 1.738847
funcs[[2]](0.77)
#[1] 2.738847
Or if you do not appreciate spicy meals:
funcs = lapply(1:2, function(u) function(...) qnorm(..., mean=u))
Upvotes: 2