R/fmt_int.R

Defines functions fmt_int

Documented in fmt_int

# ---------------------------------------------------------------------------- #
#' Convert integers into same-length strings
#'
#' Converts an integer value or vector of integer values into string(s) without
#' any decimal point, padding them with a leading character to ensure they are
#' all the same length.
#'
#' @param num An integer vector of values to be converted (these do not need to
#'   be of class \code{integer} but they do need to \emph{be} 'integerish', i.e.
#'   without any digits after the decimal points).
#' @param tol The numerical tolerance used to check whether a double can be
#'   safely converted to an integer.
#' @param pad_char The character to use for (left) padding to ensure same-length
#'   output.
#' @param preserve_names TRUE to preserve names from the input vector, FALSE
#'   otherwise.
#'
#' @returns A character vector of formatted integer values, left-padded to the
#'   length of the largest value with the specified padding character.
#'
#' @examples
#' fmt_int(2) # => "2"
#' fmt_int(2.0) # => "2"
#' fmt_int(2.00001, tol = 1.0e-4) # => "2"
#' fmt_int(c(2, 467, 25)) # => [1] "  2" "467" " 25"
#' fmt_int(c(2, 467, 25), pad_char=".") # => [1] "..2" "467" ".25"
#' fmt_int(c(a = 1, b = 20), preserve_names = TRUE)
#'
#' @export
#'
fmt_int <- function(num, tol = 1.0e-8, pad_char = " ", preserve_names = FALSE) {
  if (!checkmate::test_integerish(num, tol = tol)) {
    cli_abort(c(
      "{.var num} must be an integer (or convertible to integer) vector",
      "x" = "You've supplied a {.cls {typeof(num)}} vector.",
      "i" = "Your vector: ({style_cli_vec(num)})."
    ),
    class = "jute_error"
    )
  }

  res <- format(as.integer(num), drop0trailing = TRUE)
  if (preserve_names) {
    names(res) <- names(num)
  }

  if (pad_char != " ") {
    res <- vapply(res, function(x) {
      # Use fixed = TRUE to use exact matching (i.e. string rather than regex)
      gsub(" ", pad_char, x, fixed = TRUE)
    },
    FUN.VALUE = character(1), USE.NAMES = preserve_names
    )
  }

  res
}

# ---------------------------------------------------------------------------- #
toniprice/jute documentation built on Jan. 11, 2023, 8:23 a.m.