10

I have been trying to understand tidy eval or how to use variables within tidyverse for a while, but I never seem to fully grasp it.

For example, I am trying to use ggplot with variable mappings. This would the base R version:

library(ggplot2)
var1 = "wt"
var2 = "mpg"
ggplot(mtcars, aes(x = get(var1), y = get(var2))) + geom_point()

However, based on all the documentation and discussion I have seen, the "proper" quasiquotation way would be:

ggplot(mtcars, aes(x = !!sym(var1), y = !!sym(var2))) + geom_point()

Maybe that is more comparable to:

ggplot(mtcars, aes(x = !!as.symbol(var1), y = !!as.symbol(var2))) + geom_point()

The get() method is shorter and more readable to me. Why is it shunned by the tidyverse community?

burger
  • 5,683
  • 9
  • 40
  • 63
  • 2
    fwiw, the "old" sanctioned way of using ggplot with aesthetic mappings stored in characters was to use `aes_string()` not `get()`. – joran Apr 30 '19 at 22:43
  • One difference is that your x and y axis labels are `get(var1)` and `get(var2)`. I suspect https://adv-r.hadley.nz/evaluation.html#quosures is related. – Raoul Duke Apr 30 '19 at 23:46
  • @joran I did not mention the `aes_` functions since they are now soft-deprecated, so at least there is some reason not to use them. – burger May 01 '19 at 00:36
  • I think perhaps part of what's going on here is that ggplot itself was rewritten to use quosures; I feel like when I first learned ggplot using `get` in this fashion would break in unanticipated ways bc the evaluation scheme was more fragile. – joran May 01 '19 at 01:11

2 Answers2

4

If the data frame contains a var1 or var2 column, those will be picked up by get() instead of the objects in your environment.

Also you'll get better auto-labelling of the expression with quasiquotation, as you're modifying the captured expression directly.

Lionel Henry
  • 6,652
  • 27
  • 33
2

I'm not super familiar with tidyeval and I could be wrong about this. My understanding is that tidy evaluation is more useful for slightly more complicated exercises such as combining dplyr or tidyr with ggplot2, or handling multiple arguments (dot-dot-dot). Here’s a function which takes grouped variables passed by ..., calculates the mean for .summary_var then plot the results:

library(tidyverse)
gg_dummy_func <- function(.data, .summary_var, ...) {

  summary_var <- enquo(.summary_var)
  group_vars <- enquos(...)

  sum_data <- .data %>%
    group_by(!!!group_vars) %>%
    summarise(mean=mean(!!summary_var))

  gg <- ggplot(sum_data, aes(x=!!sym(names(sum_data)[1]), 
                             y=!!sym(names(sum_data)[2]),
                             color=mean)) +
    geom_point()
  print(gg)
}


gg_dummy_func(mtcars, mpg, wt, cyl)

enter image description here