Home > Software design >  Bug in R or am I doing the ggplot saving to a list wrong?
Bug in R or am I doing the ggplot saving to a list wrong?

Time:11-26

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:

library(ggplot2)

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

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

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)
}
plots

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

library(ggplot2)

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

lapply(
  1:3, function(i)
    ggplot(
      mtcars,
      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          
status                                     
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

CodePudding user response:

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()))


plot_cars$plot[[1]]
  • Related