0

I started to learn « ggplot2 » and loops since some times. So now, I try to plot some points with « ggplot2 » using a « for » loop. But, I don't really know how to do it, and I don't really know if it's a good idea. I checked over the similar questions and I just don't understand. Maybe, I need more explications.

I've been surfing on stack overflow for a while and it helped me a lot. However, it's my first question here and if it miss some informations or if the script is not correctly exposed, just tell me what's wrong and I'll take care it for the next time.

Here's my script with geom_point() :

    library(tidyverse)
    data("CO2")

    ggplot(data = CO2, mapping = aes(x = conc, y = uptake)) +            # I think that I must do this.

      for (i in 1:nrow(CO2)) {                                           # For each line of the dataset.
        if(CO2$Type[i] == "Quebec" & CO2$Treatment[i] == "nonchilled") { # Test these conditions.
          geom_point(mapping = aes(x = CO2$conc[i], y = CO2$uptake[i]))  # If they are true, add the point using geom_point.
        }                                                                # And eventually, I would like to add more « for » loops.
      }

And I also try with annotate() :

    ggplot(data = CO2, mapping = aes(x = conc, y = uptake)) +

      for (i in 1:nrow(CO2)) {
        if(CO2$Type[i] == "Quebec" & CO2$Treatment[i] == "nonchilled") {
          annotate(geom = "point", x = CO2$conc[i], y = CO2$uptake[i])
        }
      }

The points just don't appear. I also try to stock the values in vectors and assigned them to the « x » et « y » arguments.

Is someone knows how to do that simply, and if it's common to do that. If it's not, why? And what are the alternatives?

Thank you and have a good day!

4
  • data = subset(CO2, Type == "Quebec" & Treatment == "nonchilled"). In ggplot, you never need that type of code. Commented May 4, 2020 at 17:39
  • 1
    Or, since you're using tidyversethat also loads package dplyr, CO2 %>% filter(Type == "Quebec", Treatment = "nonchilled") %>% ggplot(mapping = ...). Note that the pipe means you don't pass a data argument to ggplot. Commented May 4, 2020 at 17:42
  • Are you trying to make points appear on the graph one at a time? Look at the gganimate package for that. Commented May 4, 2020 at 17:48
  • To answer the literal question of adding layers to a ggplot grob iteratively in a for loop (ultimately not what you need here): I'd start with gg <- ggplot(data, aes(...)), then for (i in ...) { gg <- gg + geom_*(...); }, then ultimately deal with the gg post-loop. But please, don't try to use this in this example, as you are defeating so many efficiencies in ggplot2 and in R by trying to do it in a loop. Commented May 4, 2020 at 17:50

5 Answers 5

1

I believe the other answers solve the stated question well, but if you plan to make multiple graphs using the different levels of Type & Treatment, you might try using facet_grid:

CO2 %>%
  ggplot(mapping = aes(x = conc, y = uptake)) +
  geom_point() +
  facet_grid(. ~ Type + Treatment)
Sign up to request clarification or add additional context in comments.

Comments

0

You're over complicating this. Try filter:

  library(tidyverse)
  data("CO2")

  CO2 %>% filter(Type == 'Quebec' & Treatment == 'nonchilled') %>% 
  ggplot(aes(x = conc, y = uptake)) + 
    geom_point()  

Comments

0

I agree with Rui Barradas, I would do something like this:

CO2 %>%
  filter(Type == "Quebec" & Treatment == "nonchilled") %>% # Get nonchilled Quebec data
  ggplot(aes(x = conc, y = uptake)) +                      # Plot concentration and uptake
    geom_point()                                           # Plot as points

Comments

0

I don't think you'll want to have the for loop within the ggplot function. I would recommend filtering your dataframe to the conditions you want before, and then plotting all those points.

You'll have to come up with a list of all the conditions you want and filter out to make a dataframe of only those observations you want to plot. See below:

CO2_quebec <- CO2 %>% 
  filter(Type=="Quebec") %>% #Filters out Type only in 'Quebec' 
  filter(Treatment == "nonchilled") #Filters out Treatment only for 'nonchilled' 

ggplot(data = CO2_quebec, mapping = aes(x = conc, y = uptake)) +  
  geom_point() #Note, your geom_point takes your x and y based on your ggplot line above unless otherwise specified 

Comments

0

It is a very common usage of ggplot.

Here is what you are probably looking for :

gg<- ggplot(data = CO2[CO2$Type=="Quebec" & CO2$Treatment=="nonchilled",], mapping = aes(x = conc, y = uptake))  + 
  geom_point()
gg

First of all, you should filter your data before doing the plot. It will make your life easier (as I did). Then, ggplot is a clever package : you don't need to precise every point you want to plot. If you don't tell him anything, it will understand that you want to plot everything (that's why it is useful to filter before).

Moreover, here is something you will probably appreciate :

gg<- ggplot(data = CO2[CO2$Treatment=="nonchilled",], mapping = aes(x = conc, y = uptake, group=Type,color=Type))  + 
  geom_point()
gg

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.