How can I write a function for ggplot2's scale in a dplyr workflow?

Viewed 66

I would like to set the labels in ggplot2::scale_x_discrete() (or similar) dynamically in one pipe workflow and since I am failing, it seems I have a misunderstanding of how pipes work. I illustrate my question in two examples below, example 1 works fine, and example 2 is my desired way to write code. I would like to manipulate the labels of a mutated variable in one move.

library(dplyr)
library(ggplot2)

What works is the following. As you see, I can manipulate the levels of disp by referring to the intermediate data.frame df

# Example 1
df <- 
  mtcars %>% 
  mutate(disp = cut(disp, breaks = 5)) 

df %>%   
  ggplot(aes(disp, hp)) +
  geom_point() + 
  scale_x_discrete(labels = substring(levels(df$disp), 2, 4))

But what I would like to write is something like below (doesn't work)

# Example 2
mtcars %>% 
  mutate(disp = cut(disp, breaks = 5)) %>%
  ggplot(aes(disp, hp)) +
  geom_point() + 
  scale_x_discrete(labels = substring(levels(.data$disp), 2, 4))

What do I need to write instead of .data$disp?

2 Answers

You can use braces to make the whole ggplot into one expression

mtcars %>% 
  mutate(disp = cut(disp, breaks = 5)) %>%
  {
    ggplot(data = ., aes(disp, hp)) +
    geom_point() + 
    scale_x_discrete(labels = substring(levels(.$disp), 2, 4))
  }

You can then refer to the data as . throughout.

You can pass a function to labels argument :

library(dplyr)
library(ggplot2)

mtcars %>% 
  mutate(disp = cut(disp, breaks = 5)) %>%
  ggplot() + aes(disp, hp) + 
  geom_point() + 
  scale_x_discrete(labels = function(x) substring(x, 2, 4))

enter image description here

Related