0

I used a for loop to automate the generation of 20 barplots with ggplot. I used the following code:

plist<-list()
for (i in 1:20){
  TheTable <- answers[i] %>% count(answers[i])
  colnames(TheTable) <- c("q", "n")
  rightans <- correct_answers[i]
  perc_wrong <- prop.table(table(right_wrong[i]))[1]*100
  p<-ggplot(TheTable)+
    geom_bar(stat="identity", aes(x=q, y=n, fill = q == rightans)) +
    scale_colour_manual(name = 'Right', values = setNames(c('green','red'), c(T, F)))+
    theme_classic()+
    theme(legend.position='none')+
    xlab("")+
    ylab("")+
    labs(title= paste0("Question ", i, " (", rightans, ") "),
         subtitle=paste0(round(perc_wrong, 0), "% was wrong"))
  print(p)
  plist[[i]]<-p
  assign(paste0("Q", i, "_plot"), p)
}
do.call(grid.arrange,plist)

My data can be found here (as .RData-file) for reproducibility


The loop and all works fine. If I flip through my plots in the plot area in RStudio immediately after running the code, they all look as they should.

Yet, there is one element that doesn't work: in using do.call(grid.arrange, plist) it seems as though the fill = q == rightans statement does not work. In fact, it colors the bars of all 20 plots in function of the last fill = q == rightans statement it received in the for loop. And this is only for the fill= argument in the aes()--all other arguments work flawlessly.

So when I plot them all together (or when I call one single plot later on from the console) it uses the last function it received, which means that each plot will have "C" colored as red (i.e. the wrong answer).

I don't understand what happens here and I have no clue how to solve this issue. I haven't found a working solution on StackOverflow or elsewhere on the web. Any suggestions?

Phil
  • 7,287
  • 3
  • 36
  • 66
  • 2
    This is one of the questions which are asked "almost once a week". For an explanation of the issue see e.g. https://stackoverflow.com/a/26246791/12993861 or https://stackoverflow.com/q/39799886/12993861 or https://stackoverflow.com/q/68632779/12993861 – stefan Nov 23 '21 at 16:12
  • Thank @stefan for your answer. Yet, I saw + tried several of those already (tried aes_(), aes_q(), aes_string(), but none of that works in my context. Also these solutions don't work as they are either concerned with reshaping data or for lapply (which is not an option in my case). So unfortunately they don't help me. – Thomas Frissen Nov 23 '21 at 16:25
  • 2
    Why shouldn't lapply be an option for you? I mean for everyone it is the best option to create ggplot via a loop? You could simply do `plist <- lapply(1:20, function(i) { BODY_OF_YOUR_FOR_LOOP }) `. And using lapply you could drop the `print` statement, the assignment `plist[[i]] <- ...` and best would be to drop the `assign` statement too. – stefan Nov 23 '21 at 16:47
  • 1
    It worked, thanks! – Thomas Frissen Nov 23 '21 at 19:27

0 Answers0