1
votes

I have a data set where I need to generate multiple plots based on different columns, so instead of copy/pasting, I am trying to write a function, where I pass the function the dataframe and the column name. I am pretty sure that this requires a quosure, but I don't seem to be able to get it to work in ggplot2.

Ideally, I would be able to pass the dataframe, RawData, and the column name (B in this case) and it would generate a bar plot using column B, and including the column B label on the plot. For example.

RawData = data.frame(A = runif(12, 0, 5), B = LETTERS[seq(1,4)], C = letters[seq(3,1)])

ggplot(RawData, aes(x=A,y=B))+
  geom_bar(stat="identity",position="dodge")+
  xlab("Group")+ylab("B")

The function I wrote is effectively this...

PlotFn  = function(df, VarName) {
  VarName = quo(VarName)
  ggplot(df, aes(x=A,y=!!VarName))+
  geom_bar(stat="identity",position="dodge")+
  xlab("Group")+ylab(as_label(!!VarName))
}

PlotFn(RawData, B)

Which throws the error:

Error: Quosures can only be unquoted within a quasiquotation context.

# Bad: list(!!myquosure)

# Good: dplyr::mutate(data, !!myquosure)

Ideally I would be able to have my plot function run

PlotFn(RawData, B)

PlotFn(RawData, C)

and give bar plots that are labeled appropriately, like the one here.

1

1 Answers

3
votes

You don't need to unquote (!!) VarName

library(rlang)
library(tidyverse)

RawData = data.frame(A = runif(12, 0, 5), 
                     B = LETTERS[seq(1,4)], 
                     C = letters[seq(3,1)])

PlotFn <- function(df, .VarName) {
  VarName <- enquo(.VarName)
  ggplot(df, aes(x = A, y = !!VarName)) +
    geom_bar(stat = "identity", position = "dodge") +
    ylab(as_label(VarName)) +
    xlab("Group")
}
PlotFn(RawData, C)

I personally prefer .data[[]] like this

PlotFn2 <- function(df, .VarName) {
  ggplot(df, aes(x = A, y = .data[[.VarName]])) +
    geom_col(position = "dodge") +
    ylab(.VarName) +
    xlab("Group")
}

plot_list <- c("B", "C") %>% 
  map(~ PlotFn2(RawData, .x))
plot_list
#> [[1]]

#> 
#> [[2]]

Created on 2019-08-06 by the reprex package (v0.3.0)