Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create ggplot2 function and specify arguments as variables in data as per ggplot2 standard functionality

Tags:

r

ggplot2

I want to create a plotting function where I specify the data set, and specify the plotting arguments as function arguments in similar fashion as I can within ggplot2, i.e. where we specify the variable name without the dataset, e.g. hp instead of mtcars$hp.

For example:

ggfun <- function(dat, x.var, y.var){

  ggp <- ggplot(data = dat,
                aes(x = x.var,
                    y = y.var)) +
    geom_point()

  return(ggp)
}


ggfun(dat = mtcars, x.var = drat, y.var = hp)

Would return: wonderful plot

However it returns:

> ggfun(dat = mtcars, x.var = drat, y.var = hp)
Error in eval(expr, envir, enclos) : object 'drat' not found
In addition: Warning message:
In eval(expr, envir, enclos) : restarting interrupted promise evaluation

I know using aes_string instead of aes works, e.g.:

ggfun <- function(dat, x.var, y.var){

  ggp <- ggplot(data = dat,
                aes_string(x = x.var,
                    y = y.var)) +
    geom_point()

  return(ggp)
}

ggfun(dat = mtcars, x.var = "drat", y.var = "hp")

But I'd prefer to avoid using string form.

Other attempts include ggfun(dat = mtcars, x.var = mtcars$drat, y.var = mtcars$hp), which returns the right graph but partially defeats the purpose of the exercise, and produces lables "x.var" and "y.var" instead of "drat" and "hp".

Any known and reasonably simple way around this?

like image 886
Scransom Avatar asked Jun 21 '18 04:06

Scransom


1 Answers

With the devel version of ggplot2, we can pass unquoted arguments, convert it to quosure (with enquo) and evaluate it (!!)

ggfun <- function(dat, x.var, y.var){
  x.var <- enquo(x.var)
  y.var <- enquo(y.var)
  ggp <- ggplot(data = dat,
                aes(x = !! x.var,
                    y = !! y.var)) +
    geom_point()

  return(ggp)
}

ggfun(dat = mtcars, x.var = drat, y.var = hp)

For quoted strings, convert it to symbol with sym (from rlang) and do the evaluation

ggfun <- function(dat, x.var, y.var){
  x.var <- rlang::sym(x.var)
  y.var <- rlang::sym(y.var)
  ggp <- ggplot(data = dat,
                aes(x = !! x.var,
                    y = !! y.var)) +
    geom_point()

  return(ggp)
}

ggfun(dat = mtcars, x.var = "drat", y.var = "hp")

enter image description here


If we want to pass either quoted or unquoted, the quosure is changed to character (quo_name), then to symbol (sym) and evaluate (!!)

ggfun <- function(dat, x.var, y.var){
  x.var <- rlang::sym(quo_name(enquo(x.var)))
  y.var <- rlang::sym(quo_name(enquo(y.var)))
  ggp <- ggplot(data = dat,
                aes(x = !! x.var,
                    y = !! y.var)) +
    geom_point()

  return(ggp)
}

p1 <- ggfun(dat = mtcars, x.var = drat, y.var = hp)
p2 <- ggfun(dat = mtcars, x.var = "drat", y.var = "hp")

all.equal(p1, p2)
#[1] TRUE
like image 75
akrun Avatar answered Sep 23 '22 14:09

akrun