Permalink
Fetching contributors…
Cannot retrieve contributors at this time
111 lines (101 sloc) 3.4 KB
#' @param bw The smoothing bandwidth to be used.
#' If numeric, the standard deviation of the smoothing kernel.
#' If character, a rule to choose the bandwidth, as listed in
#' [stats::bw.nrd()].
#' @param adjust A multiplicate bandwidth adjustment. This makes it possible
#' to adjust the bandwidth while still using the a bandwidth estimator.
#' For example, `adjust = 1/2` means use half of the default bandwidth.
#' @param kernel Kernel. See list of available kernels in [density()].
#' @param n number of equally spaced points at which the density is to be
#' estimated, should be a power of two, see [density()] for
#' details
#' @param trim This parameter only matters if you are displaying multiple
#' densities in one plot. If `FALSE`, the default, each density is
#' computed on the full range of the data. If `TRUE`, each density
#' is computed over the range of that group: this typically means the
#' estimated x values will not line-up, and hence you won't be able to
#' stack density values.
#' @section Computed variables:
#' \describe{
#' \item{density}{density estimate}
#' \item{count}{density * number of points - useful for stacked density
#' plots}
#' \item{scaled}{density estimate, scaled to maximum of 1}
#' }
#' @export
#' @rdname geom_density
stat_density <- function(mapping = NULL, data = NULL,
geom = "area", position = "stack",
...,
bw = "nrd0",
adjust = 1,
kernel = "gaussian",
n = 512,
trim = FALSE,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = StatDensity,
geom = geom,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
bw = bw,
adjust = adjust,
kernel = kernel,
n = n,
trim = trim,
na.rm = na.rm,
...
)
)
}
#' @rdname ggplot2-ggproto
#' @format NULL
#' @usage NULL
#' @export
StatDensity <- ggproto("StatDensity", Stat,
required_aes = "x",
default_aes = aes(y = stat(density), fill = NA),
compute_group = function(data, scales, bw = "nrd0", adjust = 1, kernel = "gaussian",
n = 512, trim = FALSE, na.rm = FALSE) {
if (trim) {
range <- range(data$x, na.rm = TRUE)
} else {
range <- scales$x$dimension()
}
compute_density(data$x, data$weight, from = range[1], to = range[2],
bw = bw, adjust = adjust, kernel = kernel, n = n)
}
)
compute_density <- function(x, w, from, to, bw = "nrd0", adjust = 1,
kernel = "gaussian", n = 512) {
nx <- length(x)
if (is.null(w)) {
w <- rep(1 / nx, nx)
}
# if less than 2 points return data frame of NAs and a warning
if (nx < 2) {
warning("Groups with fewer than two data points have been dropped.", call. = FALSE)
return(data.frame(
x = NA_real_,
density = NA_real_,
scaled = NA_real_,
count = NA_real_,
n = NA_integer_
))
}
dens <- stats::density(x, weights = w, bw = bw, adjust = adjust,
kernel = kernel, n = n, from = from, to = to)
data.frame(
x = dens$x,
density = dens$y,
scaled = dens$y / max(dens$y, na.rm = TRUE),
count = dens$y * nx,
n = nx
)
}