#' Tools for working with parameter ranges
#'
#' Setters, getters, and validators for parameter ranges.
#'
#' @param object An object with class `quant_param`.
#'
#' @param range A two-element numeric vector or list (including `Inf`). Values
#' can include `unknown()` when `ukn_ok = TRUE`.
#'
#' @param ukn_ok A single logical for whether `unknown()` is
#' an acceptable value.
#'
#' @param original A single logical. Should the range values be in the natural
#' units (`TRUE`) or in the transformed space (`FALSE`, if applicable)?
#'
#' @inheritParams new-param
#'
#' @return
#'
#' `range_validate()` returns the new range if it passes the validation
#' process (and throws an error otherwise).
#'
#' `range_get()` returns the current range of the object.
#'
#' `range_set()` returns an updated version of the parameter object with
#' a new range.
#'
#' @examples
#' library(dplyr)
#'
#' my_lambda <- penalty() %>%
#' value_set(-4:-1)
#'
#' try(
#' range_validate(my_lambda, c(-10, NA)),
#' silent = TRUE
#' ) %>%
#' print()
#'
#' range_get(my_lambda)
#'
#' my_lambda %>%
#' range_set(c(-10, 2)) %>%
#' range_get()
#'
#' @export
range_validate <- function(object,
range,
ukn_ok = TRUE,
...,
call = caller_env()
) {
ukn_txt <- if (ukn_ok) {
"`Inf` and `unknown()` are acceptable values."
} else {
""
}
if (length(range) != 2) {
rlang::abort(
paste("`range` must have two values: an upper and lower bound.", ukn_txt),
call = call
)
}
is_unk <- is_unknown(range)
is_na <- is.na(range)
is_num <- map_lgl(range, is.numeric)
if (!ukn_ok) {
if (any(is_unk)) {
rlang::abort(
"Cannot validate ranges when they contains 1+ unknown values.",
call = call
)
}
if (!any(is_num)) {
rlang::abort("`range` should be numeric.", call = call)
}
# TODO check with transform
} else {
if (any(is_na[!is_unk])) {
rlang::abort("Value ranges must be non-missing.", ukn_txt, call = call)
}
if (any(!is_num[!is_unk])) {
rlang::abort("Value ranges must be numeric.", ukn_txt, call = call)
}
}
range
}
#' @export
#' @rdname range_validate
range_get <- function(object, original = TRUE) {
if (original & !is.null(object$trans)) {
res <- map(object$range, inv_wrap, object)
} else {
res <- object$range
}
res
}
#' @export
#' @rdname range_validate
range_set <- function(object, range) {
if (length(range) != 2) {
rlang::abort("`range` should have two elements.")
}
if (inherits(object, "quant_param")) {
object <-
new_quant_param(
type = object$type,
range = range,
inclusive = object$inclusive,
trans = object$trans,
values = object$values,
label = object$label
)
} else {
rlang::abort("`object` should be a 'quant_param' object")
}
object
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.