Choubi Choubi - 1 year ago 76
R Question

Creating functions in a for loop with lists

I am scratching my head at the following problem:

I am creating two functions inside a for loop with parameters that depend on some dataframe. Each function is then put inside a list.

Printing the parameters inside the for loop shows that eachh function is well defined. Yet, when I use those outside of the loop, only the last parameters are used for both functions. The following example should make that clearer.

dt <- data.frame(color = c("red", "blue"),
a = c(3,9),
b = c(1.3, 1.8))
function_list <- list()
for (col in dt$color) {
a <- dt$a[dt$color == col]
b <- dt$b[dt$color == col]

foo <- function(x) {
print(paste(col, foo(1)))
function_list[[col]] <- foo

[1] "red 3"

[1] "blue 9"


[1] 9


[1] 9

To note, this is inspired from the following question: R nested for loop to write multiple functions and plot them

The equivalent solution with
works (my answer to the previous question).

Answer Source

The relevant values of a and b are those when you call the function and not when you define it. The way you create the list, they are taken from the global environment. The solution is to create closures. I'd use Map for this, but you can do the same with a for loop:

funs <- Map(function(a, b) function(x) a*x^b, a = dt$a, b = dt$b)

#function (x) 
#a * x^b
#<environment: 0x000000000a9a4298>
#function (x) 
#a * x^b
#<environment: 0x000000000a9a3728>

Notice the different environments.

#[1] 3
#[1] 9

#[1] 3
#[1] 9
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download