BioBroo
BioBroo

Reputation: 683

Generate mathematical functions using for loop

I want to generate mathematical functions using a for loop (in R) in such a way that I can then recall them by f[3] for i=3, for example.

What I originally tried was:

f<-NULL
for (i in 1:100){
    f[i]<-function(x){x*i}
}

This doesn't work. I suspect that this is because the for loop automatically generates a vector, and a function can't fit into a vector. I also suspect that the fix is fairly simple. Does anyone know how to generate functions like this?

My real functions are much more complicated, but I wanted to make the question readable. I will also be repeating this thousands of times, so manually entering in function is not a viable option.

Upvotes: 1

Views: 304

Answers (3)

dickoa
dickoa

Reputation: 18437

I think that you need to force the evaluation of your index (i) using the...force function and you can also replace the for loop by lapply.

size <- 5
f <- function(ind) { force(ind); function(x) x * ind }
fmult <- lapply(seq_len(size), function(i) f(i))
fmult[[3]](4)
## [1] 12

Upvotes: 3

mrip
mrip

Reputation: 15163

There are two problems here. The first is that you need to use a list rather than a vector. The second problem is a little more subtle. If you just do

f<-list()
for (i in 1:100){
    f[[i]]<-function(x){x*i}
}

This will create a list of functions, but the problem is that the variable i will still refer to the global environment. Since after the loop, the value of i is 100 then all of the functions will be the same:

> f[[5]](2)
[1] 200
> f[[10]](2)
[1] 200

In order to fix this, you can create a new environment to hold the local variables each time through the loop, and assign this environment to the function, as follows:

f<-list()
for (i in 1:100){
    e<-new.env()
    e$i<-i
    f[[i]]<-function(x){x*i}
    environment(f[[i]])<-e
}

Now each function will look up i in its local environment, so it works as expected:

> f[[5]](2)
[1] 10
> f[[10]](2)
[1] 20

Upvotes: 1

BrodieG
BrodieG

Reputation: 52637

size <- 100L
f<-vector("list", size)
for (i in seq_along(f)){
  f[[i]]<- function(x){x*i}
}    

You need a list. Also, note that the i in the function is recorded as i, not the value of i. If you want the value of i that is more complicated, but i'm just answering the question you asked directly.

Upvotes: 0

Related Questions