36

Often I use ggplot2 in my work and build wrapper functions to speed up my work flow. The use of the non-standard evaluation (NSE) aes forces me to use the actual variable names rather than passing character strings. So I copy and rename dataframes and variable names to appease ggplot2. There's got to be a better way. How can I make ggplot2 accept unknown dataframes and column names via a function wrapper without replicating the dataframe and using generic column names?

This works:

ggplot(mtcars, aes(x=mpg, y=hp)) +
    geom_point()

This does not:

FUN <- function(dat, x, y) {
    ggplot(dat, aes(x = x, y = y)) +
        geom_point()
}

FUN(mtcars, "mpg", "hp")
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • 2
    Tired of hunting for duplicates? :) – joran Nov 07 '13 at 01:35
  • 1
    @Joran I know this has to be a duplicate but couldn't find it. I hope the title is likely to lead a searcher here. If someone has a better title or additional tags feel free to edit. – Tyler Rinker Nov 07 '13 at 01:39
  • 1
    I'm with Tyler. If the Masters of the SO Universe want to reward dupe-hunting, it is in their power to ordain such. As far as I can tell that is not the case. For this one I can remember hunting quite a while within the none-too-complete help pages for ggplot2 before I found this item. Has anyone else followed the "see _facet_" only to be extremely dissappointed at the nothingness one finds there? – IRTFM Nov 07 '13 at 05:08
  • 3
    For future searchers: There is a small description of ```aes_string()``` in page 15 of the [Documentation](http://cran.r-project.org/web/packages/ggplot2/ggplot2.pdf). **Description** Aesthetic mappings describe how variables in the data are mapped to visual properties (aesthetics) of geoms. Compared to aes this function operates on strings rather than expressions. **Details** aes_string is particularly useful when writing functions that create plots because you can use strings to define the aesthetic mappings, rather than having to mess around with expressions. – marbel Jan 03 '14 at 17:34

2 Answers2

51

There's the aes_string function, that I don't really see given prominence, which does exactly this:

FUN <- function(dat, x, y) {
    ggplot(dat, aes_string(x = x, y = y)) +
        geom_point()
}

FUN(mtcars, "mpg", "hp")
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • 4
    `aes_string` is soft deprecated. See https://stackoverflow.com/a/55133909/5477070 for a more up to date answer. – jarauh Feb 22 '21 at 18:27
18

It is now recommended to use .data pronoun

FUN <- function(dat, x, y) {
  ggplot(dat, aes(x = .data[[x]], y = .data[[y]])) +
    geom_point()
}

FUN(mtcars, "mpg", "hp")

enter image description here

Couple of other alternatives -

#Using get
FUN <- function(dat, x, y) {
  ggplot(dat, aes(x = get(x), y = get(y))) +
    geom_point()
}

#Using sym

FUN <- function(dat, x, y) {
  ggplot(dat, aes(x = !!sym(x), y = !!sym(y))) +
    geom_point()
}
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213