2

This loop creates a list of 3 ggplots, but because the arguments for x and xend depend on the index of the loop, dismay follows:

DF <- data.frame(column1=c(1,2,3,4,5), column2=c(4,5,6,7,8))

list_of_ggplots <- list()

for (num in seq(1:3)){ 
  p <- ggplot()
  p <- p + geom_segment(data=DF, aes(x=column1[num], xend=column2[num], y=1, yend=1))

  list_of_ggplots[[num]] <- p }
list_of_ggplots

We get 3 plots being fundamentally the same plot (since at the point in time they are called, num is 3).

What could be a better strategy to create these plots?

tumultous_rooster
  • 12,150
  • 32
  • 92
  • 149
  • Do you want make this without a loop? – Artur_Indio Feb 19 '15 at 02:59
  • The loop structure could be changed / altered / removed, as long as it basically does the same thing...dynamically creating a variable number of plots where the index for accessing the data in the dataframe is given based on the iteration over seq(1:n). Or something equivalent to seq(1:n). – tumultous_rooster Feb 19 '15 at 03:03
  • this could help [link](http://stackoverflow.com/questions/11357139/r-saving-ggplot2-plots-in-a-list) – Artur_Indio Feb 19 '15 at 04:02
  • Just subset the data set outside of `aes`: `geom_segment(data=DF[num,], aes(x=column1, xend=column2, y=1, yend=1))` – Marat Talipov Feb 19 '15 at 04:43
  • 2
    replace `aes` by `aes_q` and pass the values directly: `aes_q(x=DF$column1[num], xend=DF$column2[num], y=1, yend=1)` – kohske Feb 19 '15 at 04:59
  • Can someone please explain what is going on underneath this tiny, seemingly cosmetic change in the code? I never would have figured this out.. – tumultous_rooster Feb 19 '15 at 05:04
  • `aes` creates a list of **unevaluated** expressions, which are evaluated when you're attempting to generate plots--that is why `num` is the same in all plots in your example. One way to avoid the problem of late evaluation of `num` is to put it outside of `aes`, so I suggested to directly subset DF. Another approach, suggested by @kohske, is to use a variation of the `aes` function, called `aes_q`, which evaluates everything in place. – Marat Talipov Feb 19 '15 at 05:17
  • Why was it implemented like this; are there any advantages? Does it play any particular role or service in the course of creating visualizations? – tumultous_rooster Feb 19 '15 at 05:38
  • The problem statement in your post is "We get 3 plots being fundamentally the same" and in the duplicate it's "my problem is that each graph that is plotted uses data from the same column". Both times the issue is that looping over columns to create `ggplot` objects does not work. How are these not the same problems? – shadow Feb 19 '15 at 08:25
  • 1
    His/her problem revolves needing to display multiple plots on the same page. My problem revolves around at what time expressions in ggplot are evaluated. There are some similarities, but at the very least the solutions are absolutely different. Facet wrapping and layout issues play no role in the solution to my question nor were they the problem, nor would they solve my problem. Regardless, "This question already has an answer here:" is simply not the case. – tumultous_rooster Feb 19 '15 at 17:14

2 Answers2

0

You can get a list without running explicit loops by using lapply:

list_of_ggplots <- lapply(1:nrow(DF), function(i) {ggplot(DF[i,]) + aes(x=column1, xend=column2, y=1, yend=1)+geom_segment()})
Marat Talipov
  • 13,064
  • 5
  • 34
  • 53
0

you can make the list in a more "R"-like way with lapply and then just subset DF with num vs trying to do so in the aesthetics. However, you should also use scale_x_continuous and set the limits, otherwise they'll all still "look" the same (except for the #'s on the x axis)

list_of_ggplots <- lapply(1:nrow(DF), function(num) {
  p <- ggplot()
  p <- p + geom_segment(data=DF[num,], aes(x=column1, xend=column2, y=1, yend=1))
  p + scale_x_continuous(limits=c(0, max(DF$column2))) 
})
hrbrmstr
  • 77,368
  • 11
  • 139
  • 205