Home > Mobile >  ggplot2 mappings changing when using tidy evaluation and aes() instead of aes_string()
ggplot2 mappings changing when using tidy evaluation and aes() instead of aes_string()

Time:01-24

I am trying to update some older plot-making code that gives the message:

Warning message: `aes_string()` was deprecated in ggplot2 3.0.0. Please use tidy evaluation ideoms with `aes()`

When I replace aes_string() with aes() and the unquoting !!, I start getting the message "Error: Discrete value supplied to continuous scale" in unexpected places.

Here is a simplified reproducible example:

# Make some test data
set.seed(1)
dat <- data.frame(x=rnorm(100),y=rnorm(100),value=rnorm(100))
xvar <- 'x'
yvar <- 'y'
cvar <- 'value'

# This works, but gives a deprecated warning for use of aes_string()
ggplot(dat,aes_string(x=xvar,y=yvar,color=cvar))   geom_point()   scale_color_gradientn(colors = rainbow(10))

# This changes the plot to use aes() with !! instead of using aes_string()
# It fails with "Error: Discrete value supplied to continuous scale"
ggplot(dat,aes(x=!!xvar,y=!!yvar,color=!!cvar))   geom_point()   scale_color_gradientn(colors = rainbow(10))

I haven't been able to get to the bottom of what's causing this, but it looks like the mappings themselves are being handled differently in ggplot - with aes_string() the variable names show up with a ~ at the beginning, and with aes() and !! they do not:

# Capture each plot so it can be examined
plt_working <- ggplot(dat,aes_string(x=xvar,y=yvar,color=cvar))   geom_point()   scale_color_gradientn(colors = rainbow(10))
plt_broken <- ggplot(dat,aes(x=!!xvar,y=!!yvar,color=!!cvar))   geom_point()   scale_color_gradientn(colors = rainbow(10))

summary(plt_working) # The second line says "mapping:  colour = ~value, x = ~x, y = ~y"
summary(plt_broken) # The second line says "mapping:  x = x, y = y, colour = value" (no ~s)

What does the ~ mean? In this context it doesn't seem likely to have anything to do with formulas or facets.

Why does this change make the plot code stop working, and what would be the correct way to update the code so it will still work?

CodePudding user response:

You need to wrap your strings in sym(), then use !! to unwrap them inside aes():

set.seed(1)
dat <- data.frame(x=rnorm(100),y=rnorm(100),value=rnorm(100))
xvar <- sym('x')
yvar <- sym('y')
cvar <- sym('value')

ggplot(dat,aes(x=!!xvar,y=!!yvar,color=!!cvar))   geom_point()   scale_color_gradientn(colors = rainbow(10))

Alternately, you can access the somewhat hidden .data object and select its columns via string values:

xvar <- 'x'
yvar <- 'y'
cvar <- 'value'

ggplot(dat,aes(x = .data[[xvar]], y = .data[[yvar]], color = .data[[cvar]]))   geom_point()   scale_color_gradientn(colors = rainbow(10))

CodePudding user response:

When using ggplot2, the aes() function is typically used to define the mapping between variables in the data and the aesthetics of the plot. However, when using tidy evaluation, the aes() function can sometimes produce unexpected results. This is because the aes() function uses non-standard evaluation (NSE) to evaluate the variable names, which can lead to confusion when working with tidy evaluation. To avoid this issue, it is recommended to use aes_string() instead of aes() when working with tidy evaluation. This function uses standard evaluation (SE) to evaluate the variable names, which eliminates the confusion caused by NSE.

  • Related