pluke
pluke

Reputation: 4356

using ifelse statement to set aes y value in ggplot

I want to use an if statement to change the focus of the y aesthetic in ggplot:

ggplot(diamonds, aes(x = cut, y = ifelse(TRUE, sym("clarity"), sym("price")))) +
  geom_col(position = "dodge")

But it gives me the following:

Don't know how to automatically pick scale for object of type . Defaulting to continuous. Error in geom_col(): ! Problem while computing aesthetics. ℹ Error occurred in the 1st layer. Caused by error in compute_aesthetics(): ! Aesthetics are not valid data columns. ✖ The following aesthetics are invalid: ✖ y = ifelse(TRUE, sym("clarity"), sym("price")) ℹ Did you mistype the name of a data column or forget to add after_stat()?

Upvotes: 3

Views: 281

Answers (1)

MrFlick
MrFlick

Reputation: 206496

It's not clear why you are using sym here. If you take that part out, you can use one of these two options

ggplot(diamonds, aes(x = cut, y = ifelse(TRUE, clarity, price))) +
  geom_col(position = "dodge")

# or 

ggplot(diamonds, aes(x = cut, y = if(TRUE) clarity else price)) +
  geom_col(position = "dodge")

The issue is that sym("clarity") isn't exactly the same as clarity. The former needs to be evaluated to become the latter. Because aes() uses non-standard evaluation. you can't directly call something like

ggplot(diamonds, aes(x = cut, y = sym("clarity"))) +
  geom_col(position = "dodge")

Rather you need to inject the value into the call with !!

ggplot(diamonds, aes(x = cut, y = !!sym("clarity"))) +
  geom_col(position = "dodge")

so I guess if you really wanted to use sym you could just inject that value into the expression

ggplot(diamonds, aes(x = cut, y = !!ifelse(TRUE, sym("clarity"), sym("price")))) +
  geom_col(position = "dodge")

Note that this doesn't work with dplyr's more cautious dplyr::if_else because normally you don't make a vector of symbols. Since you are not working with a vector or values, but just symbol names, it would be better to use if that ifelse since that's more about control flow rather than transforming vectors.

ggplot(diamonds, aes(x = cut, y = !!(if(TRUE) sym("clarity") else sym("price")))) +
  geom_col(position = "dodge")

Upvotes: 4

Related Questions