Open
Description
Add an internal function to {tmg}
that performs checks for numeric vectors that have the structure: c(value, min, max
).
Some examples are plot_height
, alpha
, ...
The goal is to replace repetitive logic (represented in real examples from {tmg}
below)
checkmate::assert_numeric(plot_height, len = 3, any.missing = FALSE, finite = TRUE)
checkmate::assert_numeric(plot_height[1], lower = plot_height[2], upper = plot_height[3], .var.name = "plot_height")
# Identical to above, but it accepts null
checkmate::assert_numeric(plot_width, len = 3, any.missing = FALSE, null.ok = TRUE, finite = TRUE)
checkmate::assert_numeric(plot_width[1], lower = plot_width[2], upper = plot_width[3], null.ok = TRUE, .var.name = "plot_width")
# This accepts both `alpha = 0.5` and `c(0.5, 0, 1)`
if (length(alpha) == 1) {
checkmate::assert_numeric(alpha, any.missing = FALSE, finite = TRUE)
} else {
checkmate::assert_numeric(alpha, len = 3, any.missing = FALSE, finite = TRUE)
checkmate::assert_numeric(alpha[1], lower = alpha[2], upper = alpha[3], .var.name = "alpha")
}
With:
checkmate::assert(check_range_slider(plot_height), .var.name = "plot_height")
checkmate::assert(
.var.name = "plot_width"
check_range_slider(plot_width),
checkmate::check_null(plot_width)
)
checkmate::assert(
.var.name = "alpha"
check_range_slider(alpha),
checkmate::check_number(alpha)
)
check_range_slider
source
#' Check if an argument is a bounded numeric vector of length 3
#'
#' Must follow form `c(value, min, max)` and `test_fun` must be a function that
#' supports checks on vectorized input
#' @noRd
#'
check_range_slider <- function(value,
lower = -Inf,
upper = Inf,
finite = TRUE,
test_fun = checkmate::test_numeric) {
checkmate::assert_flag(finite)
checkmate::assert_function(test_fun)
checkmate::assert_number(lower)
checkmate::assert_number(upper)
is_numeric <- test_fun(
value,
len = 3,
any.missing = FALSE
)
# Finite is not available in integer tests
if ("finite" %in% names(formals(test_fun))) {
test_fun(value, finite = finite)
}
is_bounded <- is_numeric && test_fun(
value[[1]],
len = 1,
lower = max(lower, value[[2]]),
upper = min(upper, value[[3]])
)
if (isFALSE(is_numeric) || isFALSE(is_bounded)) {
return(
paste(
"Must be a numeric vector of length 3 with `c(value, min, max)`",
"where the `value` must be between `min` and `max`"
)
)
}
TRUE
}