Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
153 lines (143 sloc) 5.87 KB
#' @param binwidth The width of the bins. Can be specified as a numeric value
#' or as a function that calculates width from unscaled x. Here, "unscaled x"
#' refers to the original x values in the data, before application of any
#' scale transformation. When specifying a function along with a grouping
#' structure, the function will be called once per group.
#' The default is to use the number of bins in `bins`,
#' covering the range of the data. You should always override
#' this value, exploring multiple widths to find the best to illustrate the
#' stories in your data.
#'
#' The bin width of a date variable is the number of days in each time; the
#' bin width of a time variable is the number of seconds.
#' @param bins Number of bins. Overridden by `binwidth`. Defaults to 30.
#' @param center,boundary bin position specifiers. Only one, `center` or
#' `boundary`, may be specified for a single plot. `center` specifies the
#' center of one of the bins. `boundary` specifies the boundary between two
#' bins. Note that if either is above or below the range of the data, things
#' will be shifted by the appropriate integer multiple of `width`.
#' For example, to center on integers use `width = 1` and `center = 0`, even
#' if `0` is outside the range of the data. Alternatively, this same alignment
#' can be specified with `width = 1` and `boundary = 0.5`, even if `0.5` is
#' outside the range of the data.
#' @param breaks Alternatively, you can supply a numeric vector giving
#' the bin boundaries. Overrides `binwidth`, `bins`, `center`,
#' and `boundary`.
#' @param closed One of `"right"` or `"left"` indicating whether right
#' or left edges of bins are included in the bin.
#' @param pad If `TRUE`, adds empty bins at either end of x. This ensures
#' frequency polygons touch 0. Defaults to `FALSE`.
#' @section Computed variables:
#' \describe{
#' \item{count}{number of points in bin}
#' \item{density}{density of points in bin, scaled to integrate to 1}
#' \item{ncount}{count, scaled to maximum of 1}
#' \item{ndensity}{density, scaled to maximum of 1}
#' }
#'
#' @seealso [stat_count()], which counts the number of cases at each x
#' position, without binning. It is suitable for both discrete and continuous
#' x data, whereas `stat_bin()` is suitable only for continuous x data.
#' @export
#' @rdname geom_histogram
stat_bin <- function(mapping = NULL, data = NULL,
geom = "bar", position = "stack",
...,
binwidth = NULL,
bins = NULL,
center = NULL,
boundary = NULL,
breaks = NULL,
closed = c("right", "left"),
pad = FALSE,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE) {
layer(
data = data,
mapping = mapping,
stat = StatBin,
geom = geom,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
binwidth = binwidth,
bins = bins,
center = center,
boundary = boundary,
breaks = breaks,
closed = closed,
pad = pad,
na.rm = na.rm,
...
)
)
}
#' @rdname ggplot2-ggproto
#' @format NULL
#' @usage NULL
#' @export
StatBin <- ggproto("StatBin", Stat,
setup_params = function(data, params) {
if (!is.null(data$y) || !is.null(params$y)) {
stop("stat_bin() must not be used with a y aesthetic.", call. = FALSE)
}
if (is.integer(data$x)) {
stop('StatBin requires a continuous x variable: the x variable is discrete. Perhaps you want stat="count"?',
call. = FALSE)
}
if (!is.null(params$drop)) {
warning("`drop` is deprecated. Please use `pad` instead.", call. = FALSE)
params$drop <- NULL
}
if (!is.null(params$origin)) {
warning("`origin` is deprecated. Please use `boundary` instead.", call. = FALSE)
params$boundary <- params$origin
params$origin <- NULL
}
if (!is.null(params$right)) {
warning("`right` is deprecated. Please use `closed` instead.", call. = FALSE)
params$closed <- if (params$right) "right" else "left"
params$right <- NULL
}
if (!is.null(params$width)) {
stop("`width` is deprecated. Do you want `geom_bar()`?", call. = FALSE)
}
if (!is.null(params$boundary) && !is.null(params$center)) {
stop("Only one of `boundary` and `center` may be specified.", call. = FALSE)
}
if (is.null(params$breaks) && is.null(params$binwidth) && is.null(params$bins)) {
message_wrap("`stat_bin()` using `bins = 30`. Pick better value with `binwidth`.")
params$bins <- 30
}
params
},
compute_group = function(data, scales, binwidth = NULL, bins = NULL,
center = NULL, boundary = NULL,
closed = c("right", "left"), pad = FALSE,
breaks = NULL,
# The following arguments are not used, but must
# be listed so parameters are computed correctly
origin = NULL, right = NULL, drop = NULL,
width = NULL) {
if (!is.null(breaks)) {
if (!scales$x$is_discrete()){
breaks <- scales$x$transform(breaks)
}
bins <- bin_breaks(breaks, closed)
} else if (!is.null(binwidth)) {
if (is.function(binwidth)) {
binwidth <- binwidth(data$x)
}
bins <- bin_breaks_width(scales$x$dimension(), binwidth,
center = center, boundary = boundary, closed = closed)
} else {
bins <- bin_breaks_bins(scales$x$dimension(), bins, center = center,
boundary = boundary, closed = closed)
}
bin_vector(data$x, bins, weight = data$weight, pad = pad)
},
default_aes = aes(y = stat(count), weight = 1),
required_aes = c("x")
)
You can’t perform that action at this time.