Nothing
grates_month_env <- new.env(parent = emptyenv())
# -------------------------------------------------------------------------
#' Month scale
#'
# -------------------------------------------------------------------------
#' ggplot2 scale for a month vector.
#'
# -------------------------------------------------------------------------
#' @param breaks
#'
#' A `<grates_month>` vector of the desired breaks.
#'
#' @param n.breaks `[integer]`
#'
#' Approximate number of breaks calculated using `scales::breaks_pretty`
#' (default 6L).
#'
#' Will only have an effect if `breaks = waiver()`.
#'
#' @param format
#'
#' Format to use if "Date" scales are required.
#'
#' If NULL then labels are centralised and of the form "lower category bound to
#' upper category bound".
#'
#' If not NULL then the value is used by `format.Date()` and can be any input
#' acceptable by that function (defaults to "%Y-%m-%d).
#'
#' @param bounds_format
#'
#' Format to use for grouped date labels. Only used if `format` is NULL.
#'
#' @param sep `[character]`
#'
#' Separator to use for grouped date labels.
#'
#' @param n `[integer]`
#'
#' Number of months used for the original grouping.
#'
#' @param ...
#'
#' Not currently used.
#'
# -------------------------------------------------------------------------
#' @return
#' A scale for use with ggplot2.
#'
# -------------------------------------------------------------------------
#' @examplesIf requireNamespace("outbreaks") && requireNamespace("ggplot2")
#'
#' # use simulated linelist data from the outbreaks package
#' linelist <- outbreaks::ebola_sim_clean$linelist
#'
#' # calculate the bimonthly number of cases
#' x <- as_month(linelist$date_of_infection, n = 2)
#' (dat <- aggregate(list(cases = x), by = list(group = x), FUN = length))
#'
#' # by default lower date bounds are used for the x axis
#' (bimonth_plot <-
#' ggplot2::ggplot(dat, ggplot2::aes(group, cases)) +
#' ggplot2::geom_col(width = 1, colour = "white") +
#' ggplot2::theme_bw() +
#' ggplot2::theme(
#' axis.text.x = ggplot2::element_text(
#' angle = 45,
#' hjust = 1
#' )
#' ) +
#' ggplot2::xlab(""))
#'
#' # To obtain centred labels you must explicitly set the format to NULL
#' # in the scale:
#' bimonth_plot + scale_x_grates_month(format = NULL, n = 2)
#'
# -------------------------------------------------------------------------
#' @export
scale_x_grates_month <- function(
...,
breaks = ggplot2::waiver(),
n.breaks = 6L,
format = "%Y-%m-%d",
bounds_format = "%Y-%b",
sep = "to",
n
) {
.check_suggests("ggplot2")
.check_suggests("scales") # precautionary but overkill as currently a dependency of ggplot2
if (missing(n))
n <- grates_month_env$n
if (is.null(n))
stop("Please specify the `n` of the grate_month input")
if (!is.integer(n)) {
if (!.is_whole(n))
stop("`n` must be an integer of length 1.")
n <- as.integer(n)
}
if (n <= 1L)
stop("`n` must be greater than 1. Did you mean to call scale_x_grates_yearmonth?")
# set environment variables to NULL so they don't mess other plots up
grates_month_env$n <- NULL
# ggplot2 3.5.0 deprecated the `trans` argument in favour of `transform`.
# We could just force a minimum ggplot2 version and avoid this branching
# but it's relatively low effort so leaving for now.
# TODO - revisit.
if (utils::packageVersion("ggplot2") < '3.5.0') {
ggplot2::scale_x_continuous(
trans = .grates_month_trans(
breaks = breaks,
n.breaks = n.breaks,
format = format,
bounds_format = bounds_format,
sep = sep,
n = n
)
)
} else {
ggplot2::scale_x_continuous(
transform = .grates_month_trans(
breaks = breaks,
n.breaks = n.breaks,
format = format,
bounds_format = bounds_format,
sep = sep,
n = n
)
)
}
}
# ------------------------------------------------------------------------- #
#' @exportS3Method ggplot2::scale_type
scale_type.grates_month <- function(x) {
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
# TODO - remove this if https://github.com/tidyverse/ggplot2/issues/4705
# gets resolved
if (!"grates" %in% .packages())
stop("<grates_month> object found, but grates package is not attached.\n Please attach via `library(grates)`.")
# -------------------------------------------------------------------------
# -------------------------------------------------------------------------
grates_month_env$n <- attr(x, "n")
"grates_month"
}
# ------------------------------------------------------------------------- #
# ------------------------------------------------------------------------- #
# -------------------------------- INTERNALS ------------------------------ #
# ------------------------------------------------------------------------- #
# ------------------------------------------------------------------------- #
.grates_month_trans <- function(breaks, n.breaks, format, bounds_format, sep, n) {
shift <- if (is.null(format)) 0 else 0.5
# breaks function
brks <- function(x) {
if (inherits(breaks, "waiver")) {
dat <- scales::breaks_pretty(n.breaks)(as.numeric(x))
dat <- as.integer(floor(dat))
dat <- as.numeric(new_month(dat, n = n))
} else {
dat <- as.numeric(breaks)
}
dat - shift
}
# format function
fmt <- function(x) {
x <- new_month(x + shift, n)
if (is.null(format)) {
format.grates_month(x, format = bounds_format, sep = sep)
} else {
x <- as.Date.grates_month(x)
format(x, format)
}
}
scales::trans_new(
"grates_month",
transform = as.numeric,
inverse = as.numeric,
breaks = brks,
format = fmt
)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.