R/get_fig_title_suffix_from_ggplot.R

Defines functions get_fig_title_suffix_from_ggplot

Documented in get_fig_title_suffix_from_ggplot

#' Generate Figure Title Suffix with N Range and Optional Download Links
#'
#' @description
#' Creates a formatted suffix for figure titles that includes the sample size (N) range
#' from a ggplot object. Optionally generates markdown download links for both the
#' plot data and the plot image.
#'
#' @param plot A `ggplot2` object, typically created by [makeme()].
#' @param save Logical flag. If `TRUE`, generates download links for the plot data (CSV)
#'   and plot image (PNG). If `FALSE` (default), only returns the N range text.
#' @param n_equals_string String. Prefix text for the sample size display
#'   (default: `"N = "`).
#' @param file_suffixes Character vector. File extensions for the saved plot images
#'   (default: `".png"`). Should include the dot.
#' @param link_prefixes Character vector. Markdown link text prefixes for the plot download links
#'   (default: `"[PNG]("`).
#' @param save_fns List of functions. Functions to save the plot data and images.
#' @param sep String. Separator between N range text and download links
#'   (default: `", "`).
#'
#' @return An `AsIs` object (using [I()]) containing a character string with:
#'   - Sample size range formatted as "\{n_equals_string\}\{range\}"
#'   - If `save = TRUE`: additional download links for plot data and image, separated by `sep`
#'   - Empty string if `plot` is not a valid ggplot object or has no data
#'
#' @details
#' This function is particularly useful for adding informative captions to plots in
#' reports. The N range is calculated using [n_range2()], which extracts the sample
#' size from the plot data. When `save = TRUE`, the function creates downloadable
#' files using [make_link()]:
#' - Plot data as CSV (via `utils::write.csv`)
#' - Plot image as PNG (via [ggsaver()])
#'
#' The function returns an `AsIs` object to prevent automatic character escaping
#' in markdown/HTML contexts.
#'
#' @seealso
#' - [n_range2()] for extracting N range from ggplot objects
#' - [make_link()] for creating download links
#' - [ggsaver()] for saving ggplot objects
#'
#' @export
#'
#' @examples
#' # Create a sample plot
#' plot <- makeme(data = ex_survey, dep = b_1:b_3)
#'
#' # Get just the N range text
#' get_fig_title_suffix_from_ggplot(plot)
#'
#' # Custom N prefix
#' get_fig_title_suffix_from_ggplot(plot, n_equals_string = "Sample size: ")
#'
#' \dontrun{
#' # Generate with download links (saves files to disk)
#' get_fig_title_suffix_from_ggplot(plot, save = TRUE)
#'
#' # Custom separator and link prefix
#' get_fig_title_suffix_from_ggplot(
#'   plot,
#'   save = TRUE,
#'   sep = " | ",
#'   link_prefix = "[Download PNG]("
#' )
#' }
get_fig_title_suffix_from_ggplot <- function(
  plot,
  save = FALSE,
  n_equals_string = "N = ",
  file_suffixes = c(".csv", ".png"),
  link_prefixes = c("[CSV](", "[PNG]("),
  save_fns = list(utils::write.csv, saros::ggsaver),
  sep = ", "
) {
  # Validate plot and data
  if (!ggplot2::is_ggplot(plot)) {
    return(I(""))
  }
  # Check for NULL, waiver, or zero-row data
  if (is.null(plot$data) || !is.data.frame(plot$data) || nrow(plot$data) == 0) {
    return(I(""))
  }

  if (length(save_fns) == 1 && rlang::is_function(save_fns)) {
    save_fns <- list(save_fns)
  }

  # Validate that vectorized parameters have matching lengths
  if (isTRUE(save)) {
    len_suffixes <- length(file_suffixes)
    len_prefixes <- length(link_prefixes)
    len_fns <- length(save_fns)

    if (len_suffixes != len_prefixes || len_suffixes != len_fns) {
      cli::cli_abort(c(
        "Vectorized parameters must have equal lengths.",
        "x" = "file_suffixes has length {len_suffixes}",
        "x" = "link_prefixes has length {len_prefixes}",
        "x" = "save_fns has length {len_fns}",
        "i" = "All three must have the same length."
      ))
    }
  }

  x <- stringi::stri_c(n_equals_string, n_range2(plot))
  if (isTRUE(save)) {
    links <- lapply(seq_along(file_suffixes), function(i) {
      if (file_suffixes[i] %in% c(".png", ".jpg", ".jpeg", ".pdf", ".svg")) {
        dat <- plot
      } else {
        dat <- plot$data
      }
      make_link(
        data = dat,
        file_suffix = file_suffixes[i],
        link_prefix = link_prefixes[i],
        save_fn = save_fns[[i]]
      )
    }) |>
      unlist()
    I(paste0(c(x, links), collapse = sep))
  } else {
    I(x)
  }
}

Try the saros package in your browser

Any scripts or data that you put into this service are public.

saros documentation built on Nov. 10, 2025, 5:06 p.m.