insightsengineering / insightsengineering/teal.modules.general

[Feature Request]: Use common `check` for parameters `c(value, min, max)`

Open
#685 0 comments 0 reactions 0 assignees View on GitHub
core enhancement
Dominant language
R
Stars
16
Forks
23
PR merge metrics
No merged PRs in 30d

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)

```r
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:

```r
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

```r
#' 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
}
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.