Search code examples
rggplot2plottitle

Use column name in plot title called by user-defined function in R


I am plotting multiple variables with a user-defined function to call plots, and map to iterate over multiple variables. I would like to add a title to each plot using a portion of the column name. Using str_extract works to get the desired text, but I am encountering difficulty passing this from within the plot function

#plot with hard-coded title - this part works
require(dplyr)
require(ggplot)
require(stringr)
require(purrr)

mydf <- data.frame("category" = as.factor(sample(c("type1", "type2"), 10, replace = TRUE)),
                   "test1_results" = runif(10, min = 0, max = 100),
                   "test2_results" = runif(10, min = 50, max = 150))

make_plot <- function(data, var)  {
    data %>% 
    ggplot() +
    aes(x = .data$category, y = !!as.symbol(var), color = .data$category) +
    ggtitle("plot title") +
    geom_boxplot(width = 0.2, notch = FALSE, position = position_dodge(1), lwd = 1.8, outlier.shape = NA)
}

vars <- c("test1_results", "test2_results")
plots <- map(vars, ~make_plot(mydf, .x))
plots[[1]]

Extracting desired string works in principle - this produces "test1" as desired:

text <- "test1_results"
str_extract(text, ".*(?=_results)")

Here's the problem

make_plot2 <- function(data, var)  {
  title <- str_extract(!!as.symbol(var), ".*(?=_results)") # problem here
  data %>% 
    ggplot() +
    aes(x = .data$category, y = !!as.symbol(var), color = .data$category) +
    ggtitle(title) +
    geom_boxplot(width = 0.2, notch = FALSE, position = position_dodge(1), lwd = 1.8, outlier.shape = NA)
}
title <- str_extract(!!as.symbol(var), ".*(?=_results)")
vars <- c("test1_results", "test2_results")
plots2 <- map(vars, ~make_plot(mydf, .x))
plots2[[1]]

R reports that "Error in as.vector(x, "symbol") : cannot coerce type 'closure' to vector of type 'symbol' "

I have tried lots of variations but not sure of the right syntax to pass the column name as a string from within the environment of the plot function


Solution

  • There is no need to turn var into a symbol. You can pass it directly and parse out the title:

    make_plot <- function(data, var)  {
      title <- str_remove(var, "_results") 
      data %>% 
        ggplot() +
        aes(x = .data$category, y = .data[[var]], color = .data$category) +
        ggtitle(title) +
        geom_boxplot(width = 0.2, notch = FALSE, position = position_dodge(1), lwd = 1.8, outlier.shape = NA)
    }
    vars <- c("test1_results", "test2_results")
    plots <- map(vars, ~make_plot(mydf, .x))