Bug in R or am I doing the ggplot saving to a list wrong?

I am trying to save a set of plots (ggplot) to a list, and it is behaving weird where the last plot overwrites ALL the list indices.

Here is my code:


mtcars <- mtcars[, c('cyl', 'am', 'gear', 'mpg')]

plots <- list()
for (i in 1:3) {
    plots[[i]] <- ggplot(
      aes(x = factor(mtcars[, i]), y = mtcars[, 'mpg'])
      ) + geom_point()

When I try to generally save something to a list, it works fine, as in this example:

plots <- list()
for (i in 1:3) {
    plots[[i]] <- sample(mtcars$mpg, 1)

Saving ggplot objects to a list using lapply also works just fine, as here:


mtcars <- mtcars[, c('cyl', 'am', 'gear', 'mpg')]

  1:3, function(i)
      aes(x = factor(mtcars[, i]), y = mtcars[, 'mpg'])
      ) + geom_point()

Any idea what is going on?

BTW – this info might be relevant:

> packageVersion('ggplot2')
[1] ‘3.3.3’

> version
platform       x86_64-apple-darwin17.0     
arch           x86_64                      
os             darwin17.0                  
system         x86_64, darwin17.0          
major          4                           
minor          0.3                         
year           2020                        
month          10                          
day            10                          
svn rev        79318                       
language       R                           
version.string R version 4.0.3 (2020-10-10)
nickname       Bunny-Wunnies Freak Out

>Solution :

The problem is that the list contains ggplot where the x-aesthetics depend on the i variable. To be more precise, after you run your code i is set to 3. In particular, the x-aesthetics always shows factor(mtcars[, 3]).

You can verify this by trying the following:

print(plots[[1]]) # prints the third plot
i <- 1
print(plots([[1]]) # prints the first plot because now i = 1

Here is an alternative workflow you can try:

plot_cars <- mtcars %>%
  gather(type, val, -mpg) %>%
  nest(data = c(val, mpg)) %>%
  mutate(plot = map(data, ~ggplot(.x,
    aes(x = val, y = mpg)) + geom_point()))


Leave a Reply