Home > Software engineering >  Loop over objects in ggplot
Loop over objects in ggplot

Time:09-17

I have multiple data frames in the same format and I want to create multiple curves in the same graph using ggplot. Each data frame has data from a year, from 1956 to 2019. For example:

Year1956 <- data.frame(prob=c(5, 10, 20, 30, 100), Qmcs=c(1000, 500, 50, 10, 5))
Year1957 <- data.frame(prob=c(1, 3, 25, 35, 100), Qmcs=c(800, 600, 100, 50, 30))

It is possible to plot these multiple objects in the same graph manually, where ... would be Year1958 to Year2018

ggplot() 
  geom_line(data=Year1956, aes(x=prob, y=Qmcs)) 
  geom_line(data=Year1957, aes(x=prob, y=Qmcs)) 
  ...
  geom_line(data=Year2019, aes(x=prob, y=Qmcs))

Is there a way of doing this in a loop, since there are many data frames? Thank you in advance.

CodePudding user response:

Instead of showing how to loop over a list of dataframes to generate separate geom_line, my answer will instead show how to combine similarly structured data.frames and do it all in a single geom_line.

Let's presume we have a series of data.frames with the pattern "Year" number.

library(ggplot2)

Year1956 <- data.frame(prob=c(5, 10, 20, 30, 100), Qmcs=c(1000, 500, 50, 10, 5))
Year1957 <- data.frame(prob=c(1, 3, 25, 35, 100), Qmcs=c(800, 600, 100, 50, 30))

We can systematically gather all the data.frames that satisfy the pattern by looping over the years and using the get() function.

years <- c(1956:1957)

mylist <- lapply(setNames(nm = years), function(i) {
  get(paste0("Year", i), mode = "list")
})

Lastly, we can combine all those data.frames together and keep track of what year we had by using the idcol argument in data.table::rbindlist(). Plotting the data then will be simple.

df <- data.table::rbindlist(mylist, idcol = "year")
df$year <- as.numeric(df$year)

ggplot(df, aes(prob, Qmcs, group = year))  
  geom_line()

Created on 2021-09-12 by the reprex package (v2.0.1)

  • Related