Search code examples
rggplot2funcnse

Call to ggplot in a function with NSE


The idea is to patch a call to ggplot in a function.

The example:

library(dplyr)
library(ggplot2)
library(lazyeval)

df <- data.frame(A=letters[1:10], B=2:11, C=3:12))

func <- function(name, dat=df) {

  output <- dat %>%
    select_(~A,name) %>%
    arrange_(interp(~desc(var), var=as.name(name)))

  plot <- 
    ggplot(output, aes_string(x=reorder(~A,-name), y=B)) +
    geom_bar(stat='identity')

  print(plot)
  return(plot)

}

result <- func("B")

Compiling gives:

Error in -name : invalid argument to unary operator.

I tried deparse and substitute. Not sure I got the right combo. Any ideas?


Solution

  • Reorder the data before passing it to ggplot. The following code also moves some of the column names around in the ggplot call, because otherwise you’d always be plotting A against B, regardless of the name argument — or was that intentional?

    function (dat, name) {
        var = as.name(name)
        reord = list(interp(~ reorder(var, -var), var = var))
        output = dat %>%
            select_(~A, name) %>% # Not actually necessary.
            arrange_(interp(~ desc(var), var = var)) %>%
            mutate_(.dots = setNames(reord, name))
    
        plot = ggplot(output, aes_string(x = 'A', y = name)) +
            geom_bar(stat = 'identity')
    
        plot(plot)
        plot
    }
    
    func(df, 'B')
    

    I’m using the mutate_(.dots = …) form here. Have a look at dplyr’s “NSE” vignette for more information on its usage.