ggplot.multistats/0000755000176200001440000000000013555571015013765 5ustar liggesusersggplot.multistats/NAMESPACE0000644000176200001440000000072013540637721015204 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(StatSummariesHex) export(draw_key_hexagon) export(normalize_function_list) export(stat_summaries_hex) importFrom(ggplot2,.pt) importFrom(ggplot2,Stat) importFrom(ggplot2,ggproto) importFrom(ggplot2,layer) importFrom(grid,gpar) importFrom(grid,polygonGrob) importFrom(grid,unit) importFrom(hexbin,hexcoords) importFrom(methods,formalArgs) importFrom(rlang,"%||%") importFrom(rlang,exec) importFrom(scales,alpha) ggplot.multistats/README.md0000644000176200001440000000234113540637675015255 0ustar liggesusersggplot.multistats [![Workflow badge][]](https://github.com/flying-sheep/ggplot.multistats/commits/master) ================= [Workflow badge]: https://github.com/flying-sheep/ggplot.multistats/workflows/Build%20R%20package/badge.svg `ggplot.multistats` currently provides `stat_summaries_hex` and some helpers. `stat_summaries_hex` is similar to [`ggplot2::stat_summary_hex`][stat_summary_2d], but allows specifying multiple stats using the `funs` parameter (see [Example](#Example)). [stat_summary_2d]: https://ggplot2.tidyverse.org/reference/stat_summary_2d.html Installation ------------ `ggplot.multistats` is not yet on [CRAN](https://CRAN.R-project.org). Install it using the `devtools` package from GitHub: ```r # install.packages('devtools') devtools::install_github('flying-sheep/ggplot.multistats') ``` Example ------- Specify a summary variable using the `z` aesthetic and specify a list of `funs` to provide `stat`s for you: ```r library(ggplot2) library(ggplot.multistats) ggplot(iris, aes(Sepal.Width, Sepal.Length)) + stat_summaries_hex( aes(z = Petal.Width, fill = stat(median), alpha = stat(n)), funs = c('median', n = 'length'), bins = 5 ) ``` ![](example.png) ggplot.multistats/man/0000755000176200001440000000000013553620063014534 5ustar liggesusersggplot.multistats/man/draw_key_hexagon.Rd0000644000176200001440000000157613540364061020351 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/draw_key_hexagon.r \name{draw_key_hexagon} \alias{draw_key_hexagon} \title{Draw a Hexagon} \usage{ draw_key_hexagon(data, params, size) } \arguments{ \item{data}{A single row data frame containing the scaled aesthetics to display in this key} \item{params}{A list of additional parameters supplied to the geom.} \item{size}{Width and height of key in mm.} } \value{ A hexagonal \code{\link[grid]{polygonGrob}}. } \description{ The default legend key drawing function for \code{\link{stat_summaries_hex}}. This function can be used as \code{key_glyph} parameter by any layer. } \examples{ library(ggplot2) ggplot(iris, aes(Sepal.Length, Sepal.Width)) + geom_hex(key_glyph = 'hexagon') + guides(fill = 'legend') } \seealso{ The legend key drawing functions built into ggplot: \code{\link[ggplot2]{draw_key}}. } ggplot.multistats/man/normalize_function_list.Rd0000644000176200001440000000150613540364061021764 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/function_list.r \name{normalize_function_list} \alias{normalize_function_list} \title{Normalize a List of Functions} \usage{ normalize_function_list(funs) } \arguments{ \item{funs}{Valid list or vector of function names and/or functions.} } \value{ Named list or character vector of functions. } \description{ Takes a list of functions and function names (or a vector of function names) and names it. Requires all entries with functions to be named and adds names to functions that were specified as names. } \examples{ normalize_function_list(c(value = 'mean')) normalize_function_list(c('median', n = 'length')) normalize_function_list(list('median', n = length)) normalize_function_list(list(Sum = sum, Custom = function(x) sum(nchar(as.character(x))))) } ggplot.multistats/man/stat_summaries_hex.Rd0000644000176200001440000000771413553620063020740 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/stat_summaries_hex.r \name{stat_summaries_hex} \alias{stat_summaries_hex} \alias{StatSummariesHex} \title{Multi-Stat Binning Layer} \format{An object of class \code{StatSummariesHex} (inherits from \code{Stat}, \code{ggproto}, \code{gg}) of length 3.} \usage{ stat_summaries_hex(mapping = NULL, data = NULL, geom = "hex", position = "identity", ..., bins = 30, binwidth = NULL, drop = TRUE, funs = c(value = "mean"), na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, key_glyph = NULL) StatSummariesHex } \arguments{ \item{mapping}{Set of aesthetic mappings created by \code{\link[=aes]{aes()}} or \code{\link[=aes_]{aes_()}}. If specified and \code{inherit.aes = TRUE} (the default), it is combined with the default mapping at the top level of the plot. You must supply \code{mapping} if there is no plot mapping.} \item{data}{The data to be displayed in this layer. There are three options: If \code{NULL}, the default, the data is inherited from the plot data as specified in the call to \code{\link[=ggplot]{ggplot()}}. A \code{data.frame}, or other object, will override the plot data. All objects will be fortified to produce a data frame. See \code{\link[=fortify]{fortify()}} for which variables will be created. A \code{function} will be called with a single argument, the plot data. The return value must be a \code{data.frame}, and will be used as the layer data. A \code{function} can be created from a \code{formula} (e.g. \code{~ head(.x, 10)}).} \item{geom}{The geometric object to use display the data} \item{position}{Position adjustment, either as a string, or the result of a call to a position adjustment function.} \item{...}{Other arguments passed on to \code{\link[=layer]{layer()}}. These are often aesthetics, used to set an aesthetic to a fixed value, like \code{colour = "red"} or \code{size = 3}. They may also be parameters to the paired geom/stat.} \item{bins}{numeric vector giving number of bins in both vertical and horizontal directions. Set to 30 by default.} \item{binwidth}{Numeric vector giving bin width in both vertical and horizontal directions. Overrides \code{bins} if both set.} \item{drop}{drop if the output of \code{fun} is \code{NA}.} \item{funs}{A list or vector of functions and function names. See \code{\link{normalize_function_list}} for details.} \item{na.rm}{If \code{FALSE}, the default, missing values are removed with a warning. If \code{TRUE}, missing values are silently removed.} \item{show.legend}{logical. Should this layer be included in the legends? \code{NA}, the default, includes if any aesthetics are mapped. \code{FALSE} never includes, and \code{TRUE} always includes. It can also be a named logical vector to finely select the aesthetics to display.} \item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, rather than combining with them. This is most useful for helper functions that define both data and aesthetics and shouldn't inherit behaviour from the default plot specification, e.g. \code{\link[=borders]{borders()}}.} \item{key_glyph}{A legend key drawing function or a string providing the function name minus the \code{draw_key_} prefix. The default is \code{\link{draw_key_hexagon}}.} } \description{ Very similar to \code{\link[ggplot2]{stat_summary_hex}}, but allows for multiple stats to be captured using the \code{funs} parameter. } \examples{ library(ggplot2) # Define the variable used for the stats using z ggplot_base <- ggplot(iris, aes(Sepal.Width, Sepal.Length, z = Petal.Width)) # The default is creating `stat(value)` containing the mean ggplot_base + stat_summaries_hex(aes(fill = stat(value)), bins = 5) # but you can specify your own stats ggplot_base + stat_summaries_hex( aes(fill = stat(median), alpha = stat(n)), funs = c('median', n = 'length'), bins = 5) } \seealso{ \code{\link{normalize_function_list}} for the \code{funs} parameter and \code{\link{draw_key_hexagon}} for the legend entry. } \keyword{datasets} ggplot.multistats/DESCRIPTION0000644000176200001440000000202613555571015015473 0ustar liggesusersPackage: ggplot.multistats Title: Multiple Summary Statistics for Binned Stats/Geometries Version: 1.0.0 Authors@R: person(given = "Philipp", family = "Angerer", role = c("aut", "cre"), email = "phil.angerer@gmail.com", comment = c(ORCID = "0000-0002-0369-2888")) Description: Provides the ggplot binning layer stat_summaries_hex(), which functions similar to its singular form, but allows the use of multiple statistics per bin. Those statistics can be mapped to multiple bin aesthetics. URL: https://github.com/flying-sheep/ggplot.multistats BugReports: https://github.com/flying-sheep/ggplot.multistats/issues License: GPL-3 Encoding: UTF-8 LazyData: true Imports: methods, rlang, scales, hexbin, ggplot2 RoxygenNote: 6.1.1 NeedsCompilation: no Packaged: 2019-10-22 15:28:56 UTC; angerer Author: Philipp Angerer [aut, cre] () Maintainer: Philipp Angerer Repository: CRAN Date/Publication: 2019-10-28 13:50:05 UTC ggplot.multistats/R/0000755000176200001440000000000013553620063014162 5ustar liggesusersggplot.multistats/R/draw_key_hexagon.r0000644000176200001440000000237513540364061017671 0ustar liggesusers#' Draw a Hexagon #' #' The default legend key drawing function for \code{\link{stat_summaries_hex}}. #' This function can be used as \code{key_glyph} parameter by any layer. #' #' @inheritParams ggplot2::draw_key_polygon #' @return A hexagonal \code{\link[grid]{polygonGrob}}. #' #' @seealso #' The legend key drawing functions built into ggplot: #' \code{\link[ggplot2]{draw_key}}. #' #' @examples #' library(ggplot2) #' ggplot(iris, aes(Sepal.Length, Sepal.Width)) + #' geom_hex(key_glyph = 'hexagon') + #' guides(fill = 'legend') #' #' @importFrom hexbin hexcoords #' @importFrom grid unit polygonGrob gpar #' @importFrom ggplot2 .pt #' @importFrom scales alpha #' @export draw_key_hexagon <- function(data, params, size) { if (is.null(data$size)) data$size <- .5 lwd <- min(data$size, min(size)/4) dx <- dy <- .5 hexC <- hexcoords(dx, dy / sqrt(3)) x <- y <- unit(.5, 'npc') size <- unit(1, 'npc') - unit(lwd, 'mm') polygonGrob( x = hexC$x * size + x, y = hexC$y * size + y, gp = gpar( col = data$colour %||% NA, fill = alpha(data$fill %||% 'grey20', data$alpha), lty = data$linetype %||% 1, lwd = lwd * .pt, linejoin = params$linejoin %||% 'mitre', lineend = if (identical(params$linejoin, 'round')) 'round' else 'square' ) ) } ggplot.multistats/R/function_list.r0000644000176200001440000000262413540364061017230 0ustar liggesusersmap_lgl <- function(.x, .f, ...) vapply(.x, .f, logical(1L), ...) #' Normalize a List of Functions #' #' Takes a list of functions and function names #' (or a vector of function names) and names it. #' Requires all entries with functions to be named and #' adds names to functions that were specified as names. #' #' @param funs Valid list or vector of function names and/or functions. #' @return Named list or character vector of functions. #' #' @examples #' normalize_function_list(c(value = 'mean')) #' normalize_function_list(c('median', n = 'length')) #' normalize_function_list(list('median', n = length)) #' normalize_function_list(list(Sum = sum, Custom = function(x) sum(nchar(as.character(x))))) #' #' @export normalize_function_list <- function(funs) { fun_or_chr <- function(x) is.function(x) || is.character(x) if (is.function(funs)) return(function(x) list(value = funs(x))) if (!is.character(funs) && !is.list(funs) || !all(map_lgl(funs, fun_or_chr))) stop('You need to provide either a function, a list of functions, or a character vector of function names, not a ', class(funs)) if (is.null(names(funs))) names(funs) <- rep_len('', length(funs)) if (any(map_lgl(funs[names(funs) == ''], is.function))) stop('If providing a list of functions, you need to name functions you pass, e.g. list(myfun = function(x) ..., "mean")') names(funs)[names(funs) == ''] <- funs[names(funs) == ''] funs } ggplot.multistats/R/stat_summaries_hex.r0000644000176200001440000000604413553620063020255 0ustar liggesusers#' Multi-Stat Binning Layer #' #' Very similar to \code{\link[ggplot2]{stat_summary_hex}}, but allows #' for multiple stats to be captured using the \code{funs} parameter. #' #' @inheritParams ggplot2::stat_summary_2d #' @param funs A list or vector of functions and function names. #' See \code{\link{normalize_function_list}} for details. #' @param key_glyph A legend key drawing function or a string providing #' the function name minus the \code{draw_key_} prefix. #' The default is \code{\link{draw_key_hexagon}}. #' #' @seealso #' \code{\link{normalize_function_list}} for the \code{funs} parameter #' and \code{\link{draw_key_hexagon}} for the legend entry. #' #' @examples #' library(ggplot2) #' # Define the variable used for the stats using z #' ggplot_base <- ggplot(iris, aes(Sepal.Width, Sepal.Length, z = Petal.Width)) #' # The default is creating `stat(value)` containing the mean #' ggplot_base + stat_summaries_hex(aes(fill = stat(value)), bins = 5) #' # but you can specify your own stats #' ggplot_base + stat_summaries_hex( #' aes(fill = stat(median), alpha = stat(n)), #' funs = c('median', n = 'length'), #' bins = 5) #' #' @importFrom methods formalArgs #' @importFrom rlang %||% exec #' @importFrom ggplot2 layer #' @export stat_summaries_hex <- function( mapping = NULL, data = NULL, geom = 'hex', position = 'identity', ..., bins = 30, binwidth = NULL, drop = TRUE, funs = c(value = 'mean'), na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, key_glyph = NULL ) { modern_args <- list() if ('key_glyph' %in% formalArgs(layer)) modern_args$key_glyph <- key_glyph %||% draw_key_hexagon exec( layer, data = data, mapping = mapping, stat = StatSummariesHex, geom = geom, position = position, show.legend = show.legend, inherit.aes = inherit.aes, !!!modern_args, params = list( bins = bins, binwidth = binwidth, drop = drop, funs = funs, na.rm = na.rm, ... ) ) } #' @importFrom ggplot2 ggproto Stat #' @name stat_summaries_hex #' @docType NULL #' @export StatSummariesHex <- ggproto( 'StatSummariesHex', Stat, #default_aes = aes(fill = stat(value)), required_aes = c('x', 'y', 'z'), compute_group = function( data, scales, binwidth = NULL, bins = 30, drop = TRUE, funs = c(value = 'mean') ) { if (is.null(binwidth)) binwidth <- ggplot2:::hex_binwidth(bins, scales) if (length(funs) < 1L) stop('You need to provide at least one function') funs <- as.list(normalize_function_list(funs)) # if it was no list before, adding a function makes it one funs$`_dummy` <- function(x) 1 # hexBinSummarise ruins our day if we have less than two items in the list idx_dummy <- names(funs) %in% '_dummy' if (sum(idx_dummy) > 1L) stop('You cannot name a function `_dummy_, sorry.') fun <- function(x) sapply(funs, exec, x, simplify = FALSE) v <- ggplot2:::hexBinSummarise(data$x, data$y, data$z, binwidth, fun = fun, drop = drop) v_new <- do.call(rbind, lapply(v$value, function(line) as.data.frame(line[!idx_dummy]))) v$value <- NULL cbind(v, v_new) } ) ggplot.multistats/MD50000644000176200001440000000074113555571015014277 0ustar liggesusers47916f97485df35fd94f741fc55ed838 *DESCRIPTION f97529155d77c26dbcb3474d36276344 *NAMESPACE a4db2cb234d3e223e097567c1a9063e7 *R/draw_key_hexagon.r b3e78724e6078c0338e8c1222a79df2b *R/function_list.r 7e8eeeb51903167cc1d28d4bee8d9b16 *R/stat_summaries_hex.r ba47a6501b2900d643aa513e210666ab *README.md 2e6e2c6d1d8630395d97a17fbe299b53 *man/draw_key_hexagon.Rd f8cb3b22ab833aba777e6c7547c8c952 *man/normalize_function_list.Rd b54a0790f52de729765827ac747a1771 *man/stat_summaries_hex.Rd