ForevaR-
ForevaR-

Reputation: 35

R – Replicate/Automate scatterplots for each string group in column

I have a dataframe (170 observation and 3 columns) like so:

site_names <- c("WS1", "WS1", "WS2", "WS2", "WS3", "WS3")
x <- c(.15, .20, .17, .16, .20, .22)
y <- c(.026, .031, .045, .087, .09, .033)

df <- data.frame(site_names, x, y)

and I have a simple ggplot formula I can run for each site_name where I plot x and y accordingly:

df %>% 
filter(site_names == "") %>% 
ggplot(aes(x = x, y = y)) +
geom_point() +
labs(x = "Discharge", y = "Stage")

What I would like is to automate these plots and generate 26 separate plots by site_name and save them all to a PDF

Here is what I have tried:

scatter_expl = function(x, y) {
 ggplot(df, aes(x = x, y = y) ) +
      geom_point() +
      theme_bw() +
      labs(x = "Discharge", y = "Stage")
}

plots = map(df, ~scatter_expl())

plots

But this runs through the whole dataframe, returns a list and produces all scatters on the same plot: https://i.sstatic.net/gVBhf.png! How do I group by site and return individual graphs?

Upvotes: 3

Views: 71

Answers (2)

TarJae
TarJae

Reputation: 79164

Updated with the help of dear @akrun:

library(tidyverse)
library(purrr)
library(gridExtra)

# create list of df by site_names
dflist <- df %>% 
  group_split(site_names)

# create a function to plot 
scatter_fun = function(dat) {
  ggplot(dat, aes(x = x, y = y)) +
    geom_point() +
    theme_bw() +
    labs(x = "Discharge", y = "Stage")
}

# iterate through each list element and apply function (many thanks to @akrun for his help)
p <- map(dflist, ~scatter_fun(.x))

# save all in one pdf
ggsave(
  filename = "plots.pdf", 
  plot = marrangeGrob(p, nrow=2, ncol=2), 
  width = 7.5, height = 4.5
)

enter image description here

Upvotes: 1

akrun
akrun

Reputation: 887501

We may need to group_by

library(dplyr)
library(ggplot2)
library(gridExtra)
out <- df %>%
    group_by(site_names) %>%
    summarise(plot = list(ggplot(cur_data(), aes(x = x, y = y)) +
                geom_point() +
                labs(x = "Discharge", y = "Stage")+   
                ggtitle(sprintf('Plot for %s', cur_group()$site_names))))

-output

> out
# A tibble: 3 × 2
  site_names plot  
  <chr>      <list>
1 WS1        <gg>  
2 WS2        <gg>  
3 WS3        <gg>  

-save the output as pdf

ggsave(file.path(getwd(), "plot.pdf"), 
      marrangeGrob(out$plot, nrow = 1, ncol = 1), device = "pdf")

data

df <- structure(list(site_names = c("WS1", "WS1", "WS2", "WS2", "WS3", 
"WS3"), x = c(0.15, 0.2, 0.17, 0.16, 0.2, 0.22), y = c(0.026, 
0.031, 0.045, 0.087, 0.09, 0.033)), class = "data.frame", row.names = c(NA, 
-6L))

Upvotes: 2

Related Questions