Passing plot labels through a function with ggplot2

Viewed 51

I have a function which renders a plot - how can I pass the plots label information (e.g., plot title, axis titles, etc.) through a function as I'm trying to do below?

library(dplyr)
library(ggplot2)

plot_func <- function(sample_size, lab_list) {
  mtcars %>% 
    sample_n(sample_size) %>% 
    ggplot(aes(x = mpg, y = hp)) +
    geom_point() +
    labs(lab_list)
}

plot_func(sample_size = 5, lab_list = list(title = "Plot Title", x = "MPG", y = "HP"))
2 Answers

We could use purrr::invoke or do.call

library(dplyr)
library(ggplot2)
plot_func <- function(sample_size, lab_list) {
 mtcars %>% 
   sample_n(sample_size) %>% 
   ggplot(aes(x = mpg, y = hp)) +
   geom_point() +
   do.call(labs, lab_list)
 }

-testing

plot_func(sample_size = 5, lab_list = list(title = "Plot Title",
      x = "MPG", y = "HP"))

enter image description here

That's interesting. There does seem to be a bug in labs(). According to the documentation it should accept a list, but that does not appear to be the case in practice. These are different

labs(x="HELLO")
# $x
# [1] "HELLO"
# attr(,"class")
# [1] "labels"

labs(list(x="HELLO"))
# [[1]]
# [[1]]$x
# [1] "HELLO"
# attr(,"class")
# [1] "labels"

The latter has an extra list that's getting in the way. You can use the base function do.call to property inject parmeters from a function into a list

do.call("labs", list(x="HELLO"))
# $x
# [1] "HELLO"
# attr(,"class")
# [1] "labels"

So your function would be

plot_func <- function(sample_size, lab_list) {
  mtcars %>% 
    sample_n(sample_size) %>% 
    ggplot(aes(x = mpg, y = hp)) +
    geom_point() +
    do.call("labs", lab_list)
}

It looks like there as a commit on Jan 4 that will allow you to use !!! in future (yet unreleased at the time of this question) versions of ggplot. So hopefully soon you'll be able to do

plot_func <- function(sample_size, lab_list) {
  mtcars %>% 
    sample_n(sample_size) %>% 
    ggplot(aes(x = mpg, y = hp)) +
    geom_point() +
    labs(!!!lab_list)
}

which is more consistent with how the rest of the tidyverse functions work.

Related