Indrajeet Patil
Indrajeet Patil

Reputation: 4889

getting function to work irrespective of whether argument has parentheses or not

I am writing a wrapper function around a function from some package. The function basically adds a new theme to ggplot objects. But the way the function has been implemented, the theme argument needs to be specified as a function. But I want my wrapper function to work irrespective of whether the argument is specified as a function or as a theme object. How can I do this?

Here is a toy example of the function, conditions under which it works, and conditions under which it doesn't work:

# loading needed libraries
library(ggplot2)

# creating basic plot on which themes are to be added
plot <- ggplot(mtcars, aes(wt, mpg)) + geom_point()

# first attempt at the function
theme_adder1 <- function(ggplot.obj, ggtheme = ggplot2::theme_bw) {
  # this can't be modified (because it was written by someone else)
  ggplot.obj + ggtheme() 
}

# this works
theme_adder1(ggplot.obj = plot, ggtheme = ggplot2::theme_grey)

# this doesn't work
theme_adder1(ggplot.obj = plot, ggtheme = ggplot2::theme_grey())
#> Error in ggtheme(): could not find function "ggtheme"

# checking classes
class(ggplot2::theme_bw())
#> [1] "theme" "gg"
class(ggplot2::theme_bw)
#> [1] "function"

So I am wondering if there is some way the ggtheme object - when entered as a theme object - can be converted to a function object and then used. But I am not sure how to do this.

# second attempt at modifying function in a way that it will work irrespective
# of how the ggtheme argument is entered
theme_adder2 <- function(ggplot.obj, ggtheme = ggplot2::theme_bw) {
  if (class(ggtheme)[[1]] == "function") {
    ggplot.obj + ggtheme()
  } else if (class(ggtheme)[[1]] == "theme") {
    # what modifcation can be made here?
    ggtheme <- ??? 
    ggplot.obj + ggtheme()
  }
}

Created on 2018-08-28 by the reprex package (v0.2.0.9000).

Upvotes: 1

Views: 183

Answers (1)

zack
zack

Reputation: 5415

Try this:

theme_adder2 <- function(ggplot.obj, ggtheme = ggplot2::theme_bw) {
  if (class(ggtheme)[[1]] == "function") {
    ggplot.obj + ggtheme()
  } else if (class(ggtheme)[[1]] == "theme") {
    # what modifcation can be made here?
      ggplot.obj + eval(ggtheme)
  }
}

also just realized you could just add on ggtheme without eval()...

theme_adder2 <- function(ggplot.obj, ggtheme = ggplot2::theme_bw) {
  if (class(ggtheme)[[1]] == "function") {
    ggplot.obj + ggtheme()
  } else if (class(ggtheme)[[1]] == "theme") {
    # what modifcation can be made here?
      ggplot.obj + ggtheme
  }
}

Upvotes: 2

Related Questions