I am working on updating some older R code to make it use ggplot2's aes() now that aes_string() is deprecated. I admit I don't understand all of the details of tidy evaluation, but from what I do understand it seems like the replacement for aes_string(shape=shapevar) would be aes(shape=.data[[shapevar]]), or possibly aes(shape=!!sym(shapevar)).
The problem with these replacements is that they do not work when shapevar is NULL, as shown in the example below:
library('ggplot2')
set.seed(1)
dat <- data.frame(x=rnorm(25),y=rnorm(25),othervar=factor(sample(1:3,25,replace=T)))
make_scatter_string <- function(plotdat,outfile,xvar='x',yvar='y',colorvar=NULL,shapevar=NULL) {
plt <- ggplot(plotdat,aes_string(x=xvar,y=yvar,color=colorvar,shape=shapevar)) + geom_point()
ggsave(outfile,plt)
}
make_scatter_data <- function(plotdat,outfile,xvar='x',yvar='y',colorvar=NULL,shapevar=NULL) {
plt <- ggplot(plotdat,aes(x=.data[[xvar]],y=.data[[yvar]],color=.data[[colorvar]],shape=.data[[shapevar]])) + geom_point()
ggsave(outfile,plt)
}
make_scatter_sym <- function(plotdat,outfile,xvar='x',yvar='y',colorvar=NULL,shapevar=NULL) {
plt <- ggplot(plotdat,aes(x=!!sym(xvar),y=!!sym(yvar),color=!!sym(colorvar),shape=!!sym(shapevar))) + geom_point()
ggsave(outfile,plt)
}
make_scatter_string(dat,'test1.png',colorvar='othervar') # Works, aes_string can handle shapevar being NULL
make_scatter_data(dat,'test2.png',colorvar='othervar') # Gives error message "Error in `.data[[NULL]]`: ! Must subset the data pronoun with a string, not NULL."
make_scatter_sym(dat,'test3.png',colorvar='othervar') # Gives error message "Error in `sym()`: ! Can't convert NULL to a symbol."
What is the correct way to give aes() a variable like shapevar that may contain the name of a variable in the data or may be NULL? Or is there some other value that should be used to say "don't use this aesthetic" instead of NULL?
Adapting my answer on How to replace the deprecated ggplot2 function aes_string: accepting an arbitrary number of named strings to specify aesthetic mappings?, a flexible and generalized approach of the one by @r2evans may look like so.
Basically I renamed the functions arguments to the names of the aesthetics and used ...
to allow to pass additional aesthetics and which also works with NULL
:
library(ggplot2)
make_scatter_sym <- function(plotdat, outfile, x = "x", y = "y", ...) {
args <- lapply(list(x = x, y = y, ...), function(x) if (!is.null(x)) sym(x))
plt <- ggplot(plotdat, aes(!!!args)) +
geom_point()
ggsave(outfile, plt)
plt
}
make_scatter_sym(dat, "test1.png", color = "othervar")
#> Saving 7 x 5 in image
make_scatter_sym(dat, "test1.png", color = NULL, shape = NULL)
#> Saving 7 x 5 in image