Intro Thoughts

Status Quo

library(tidyverse)

Experiment

#' @rdname Stat
#' @format NULL
#' @usage NULL
#' @export
StatManual <- ggproto(
  "StatManual", Stat,

  setup_params = function(data, params) {
    params[["fun"]] <- allow_lambda(params[["fun"]])
    check_function(params[["fun"]], arg = "fun")
    params
  },

  compute_group = function(data, scales, fun = identity, args = list()) {
    as_gg_data_frame(inject(fun(data, !!!args)))
  }
)


 p <- ggplot(mtcars, aes(disp, mpg, colour = factor(cyl))) +
   geom_point()

 # The default just displays points as-is
 p + stat_manual()

 # Using a custom function
 make_hull <- function(data) {
   hull <- chull(x = data$x, y = data$y)
   data.frame(x = data$x[hull], y = data$y[hull])
   data.frame(x = mean(data$x),
              y = mean(data$y))
 }

 p + stat_manual(
   geom = "point",
   fun  = make_hull,
   fill = NA,
   size = 4
 )

 # Using the `with` function with quoting
 p + stat_manual(
   fun  = with,
   args = list(expr = quote({
     hull <- chull(x, y)
     list(x = x[hull], y = y[hull])
   })),
   geom = "polygon", fill = NA
 )

 # Using the `transform` function with quoting
 p + stat_manual(
   geom = "segment",
   fun  = transform,
   args = list(
     xend = quote(mean(x)),
     yend = quote(mean(y))
   )
 )

 # Using dplyr verbs with `vars()`
 if (requireNamespace("dplyr", quietly = TRUE)) {

   # Get centroids with `summarise()`
   p + stat_manual(
     size = 10, shape = 21,
     fun  = dplyr::summarise,
     args = vars(x = mean(x), y = mean(y))
   )

   # Connect to centroid with `mutate`
   p + stat_manual(
     geom = "segment",
     fun  = dplyr::mutate,
     args = vars(xend = mean(x), yend = mean(y))
   )

   # Computing hull with `reframe()`
   p + stat_manual(
     geom = "polygon", fill = NA,
     fun  = dplyr::reframe,
     args = vars(hull = chull(x, y), x = x[hull], y = y[hull])
   )
 }

stat_manual <- make_constructor(StatManual, geom = "point")

Closing remarks, Other Relevant Work, Caveats