R assigning ggplot objects to list in loop

The answers so far are very close, but unsatisfactory in my opinion. The problem is the following – after your for loop:

myplots[[1]]$mapping
#* x -> 1:dfmsize
#* y -> dfrm[, i]
myplots[[1]]$plot_env
#<environment: R_GlobalEnv>

myplots[[2]]$mapping
#* x -> 1:dfmsize
#* y -> dfrm[, i]
myplots[[2]]$plot_env
#<environment: R_GlobalEnv>

i
#[1] "B"

As the other answers mention, ggplot doesn’t actually evaluate those expressions until plotting, and since these are all in the global environment, and the value of i is "B", you get the undesirable results.

There are several ways of avoiding this issue, the simplest of which in fact simplifies your expressions:

myplots = lapply(v, function(col)
            ggplot(dfrm, aes(x=1:dfmsize, y=dfrm[,col])) + geom_point() + labs(y=col))

The reason this works, is because the environment is different for each of the values in the lapply loop:

myplots[[1]]$mapping
#* x -> 1:dfmsize
#* y -> dfrm[, col]
myplots[[1]]$plot_env
#<environment: 0x000000000bc27b58>

myplots[[2]]$mapping
#* x -> 1:dfmsize
#* y -> dfrm[, col]
myplots[[2]]$plot_env
#<environment: 0x000000000af2ef40>

eval(quote(dfrm[, col]), env = myplots[[1]]$plot_env)
#[1]  1  2  3  4  5  6  7  8  9 10
eval(quote(dfrm[, col]), env = myplots[[2]]$plot_env)
#[1] 10  9  8  7  6  5  4  3  2  1

So even though the expressions are the same, the results are different.

And in case you’re wondering what exactly is stored/copied to the environment of lapply – unsurprisingly it’s just the column name:

ls(myplots[[1]]$plot_env)
#[1] "col"

Leave a Comment