Intro Thoughts

extending ggplot2 w stats is really flexible and lets you compute to different x and y vals

but when you want a factor scale for x or y aesthetics, where the factor is not the original input, I’m not sure what tools to use.

What extensions already do this?

Status Quo: Do computation yourself, and plot with factor variables that you create.

library(tidyverse)

mtcars |> 
  mutate(side_of_mean_mpg = mpg > mean(mpg)) |>
  mutate(side_of_mean_mpg = ifelse(side_of_mean_mpg, "greater", " less")) |>
  count(side_of_mean_mpg) |>
  ggplot() + 
  aes(x = side_of_mean_mpg, y = n) + 
  geom_col()

Want to do: Have layer do this computation for us.

First look at numeric only x creation… We produce almost the same plot, but x var values are 0 and 1

compute_group_rel_to_mean <- function(data, scales){
  
  data |> 
  mutate(x = as.numeric(x > mean(x))) |>
  # mutate(x = factor(ifelse(x, "greater", " less"))) |>
  count(x) |>
  mutate(y = n)
  
}

mtcars |>
  rename(x = mpg) |>
  compute_group_rel_to_mean()
##   x  n  y
## 1 0 18 18
## 2 1 14 14
StatReltomean <- ggproto(`_class` = "StatReltomean", 
                         `_inherit` = ggplot2::Stat,
                         compute_group = compute_group_rel_to_mean)


stat_rel_to_mean <- function(geom = ggplot2::GeomCol, 
  mapping = NULL,
  data = NULL,
  position = "identity",
  na.rm = FALSE,
  show.legend = NA,
  inherit.aes = TRUE, ...) {
  
  ggplot2::layer(
    stat = StatReltomean,  # proto object from step 2
    geom = geom,  # inherit other behavior
    data = data,
    mapping = mapping,
    position = position,
    show.legend = show.legend,
    inherit.aes = inherit.aes,
    params = list(na.rm = na.rm, ...)
  )
  
}

ggplot(mtcars) + 
  aes(x = mpg) + 
  stat_rel_to_mean()

Second, we try to convert x, to factor, by plot fails.

compute_group_rel_to_mean_mod <- function(data, scales){
  
  data |> 
  mutate(x = x > mean(x)) |>
  mutate(x = factor(ifelse(x, "greater", " less"))) |>
  count(x) |>
  mutate(y = n)
  
}


StatReltomean$compute_group <- compute_group_rel_to_mean_mod


ggplot(mtcars) + 
  aes(x = mpg) + 
  stat_rel_to_mean()
## Error in `stat_rel_to_mean()`:
## ! Problem while setting up geom.
## ℹ Error occurred in the 1st layer.
## Caused by error in `Summary.factor()`:
## ! 'range' not meaningful for factors