Search code examples
rggplot2iterationtidyverseuser-defined-functions

Use map function to create multiple plots in R


I am interested in creating plots exploring a range of variables in columns within a dataframe. So far, I have a function that successfully calls a plot, and now hoping to apply this in a tidyverse format with map.

require(dplyr)
library(purrr)
# create dataframe
mydf <- data.frame("category" = as.factor(sample(c("type1", "type2"), 10, replace = TRUE)),
                   "var1" = runif(10, min = 0, max = 100),
                   "var2" = runif(10, min = 50, max = 150))

# create function
make_plot <- function(data, var)  {
  data %>% 
    ggplot() +
    aes(x = .data$category, y = {{var}}, color = .data$category) + 
  geom_boxplot(width = 0.2, notch = FALSE, position = position_dodge(1), lwd = 1.8, outlier.shape = NA)
}
plot <- make_plot(mydf, var1)
plot

This works and I am now trying to use map to run this code over a range of variables *var1, var2, etc) and generate a list of plot objects, as in https://wilkelab.org/SDS375/slides/functional-programming.html#1 . I have reviewed https://www.rdocumentation.org/packages/purrr/versions/0.2.5/topics/map and tried variations on

vars <- c("var1", "var2")
plots <- mydf %>% map(vars, make_plot) %>% pull(plots) %>% walk(print)

However, I get errors like "no applicable method for 'pull' applied to an object of class "list". I have so far not used map much, interested in any solutions for this.


Solution

  • An approach using as.symbol to reference the vars.

    require(dplyr)
    library(purrr)
    library(ggplot2)
    
    make_plot <- function(data, var)  {
      data %>% 
        ggplot() +                                                    
        aes(x = category, y = !!as.symbol(var), color = category) + 
      geom_boxplot(width = 0.2, notch = FALSE, position = position_dodge(1), lwd = 1.8, outlier.shape = NA)
    }
    

    Generate plots

    vars <- c("var1", "var2")
    plots <- map(vars, ~ make_plot(mydf, .x))
    

    Plot

    plots[[1]] # or plots[[2]] etc