#' Automatically scale a ggplot graph x axis for time
#'
#' \code{scale_x_time} formats a ggplot graph x axis to have breaks that make
#' sense for the user-specified time units and adds a minor tick between the
#' labels. It optionally adds padding to the left and right sides of the x axis.
#'
#' @param time_range time range to show for the graph. Options: \describe{
#'
#' \item{NA}{(default) entire time range of data}
#'
#' \item{a start time and end time in hours}{only data in that range, e.g.
#' \code{time_range = c(24, 48)}. Note that there are no quotes around numeric
#' data.}}
#' @param impose_limits TRUE (default) or FALSE to actually \emph{set} the
#' limits listed in \code{time_range}. Why on earth would you \emph{not}
#' impose limits on the graph here? Behind the scenes, \code{scale_x_time}
#' uses the ggplot2 function \code{\link{ggplot::scale_x_continuous}}, which
#' filters out all data beyond the limits you specify. That means that you
#' can, in some situations, get graphs where lines are cut off abruptly. This
#' is set up with the idea that you can set the time range here to get
#' reasonable x axis intervals, but then you can add a call to
#' \code{\link{ggplot::coord_cartesian}} to limit the range without the abrupt
#' cut off.
#' @param time_units the units of time in the graph. Options are "hours"
#' (default), "minutes", "days", or "weeks".
#' @param x_axis_interval optionally set the x-axis major tick-mark interval.
#' Acceptable input: any number or leave as NA to accept default values, which
#' are generally reasonable guesses as to aesthetically pleasing and
#' time-relevant intervals.
#' @param pad_x_axis optionally add a smidge of padding to the the x axis
#' (default is TRUE, which includes some generally reasonable padding). If
#' changed to FALSE, the y axis will be placed right at the beginning of your
#' time range and all data will end \emph{exactly} at the end of the time
#' range specified. If you want a \emph{specific} amount of x-axis padding,
#' set this to a number; the default is \code{c(0.02, 0.04)}, which adds 2\%
#' more space to the left side and 4\% more to the right side of the x axis.
#' If you only specify one number, we'll assume that's the percent you want
#' added to the left side.
#'
#' @return a ggplot2 graph scale for the x axis (replaces scale_x_continuous in
#' a graph)
#' @export
#'
#' @examples
#' MyData <- data.frame(Time = 0:168,
#' Conc = rnorm(n = 169, mean = 100))
#' ggplot(MyData, aes(x = Time, y = Conc)) +
#' geom_point() + scale_x_time()
#'
#' ggplot(MyData, aes(x = Time, y = Conc)) +
#' geom_point() + scale_x_time(time_range = c(24, 48))
#'
#' # You don't have to name the column with your x-axis data "Time".
#' MyAltData <- data.frame(Mango = 0:24,
#' Conc = rnorm(n = 25, mean = 100))
#'
#' ggplot(MyAltData, aes(x = Mango, y = Conc)) +
#' geom_point() + scale_x_time()
#'
#'
scale_x_time <- function(time_range = NA,
impose_limits = TRUE,
time_units = "hours",
x_axis_interval = NA,
pad_x_axis = TRUE){
# Error catching --------------------------------------------------------
if(all(complete.cases(time_range)) && class(time_range) == "numeric" &
time_range[1] >= time_range[2]){
warning("The 1st value for 'time_range' must be less than the 2nd value. We'll use the full time range instead.",
call. = FALSE)
time_range <- NA
}
# Main body of function ------------------------------------------------
Setup <- scale_x_time_setup(time_range = time_range,
time_units = time_units,
x_axis_interval = x_axis_interval,
pad_x_axis = pad_x_axis)
return(scale_x_continuous(breaks = Setup$xbreaks,
labels = Setup$xlabels,
limits = switch(as.character(impose_limits),
"TRUE" = Setup$limits,
"FALSE" = NULL),
expand = Setup$expand))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.