assert is a lightweight toolkit of assertion helpers for checking the inputs and outputs of your functions. Drop a few assertions at the top of a function and get a clear, immediate error when an argument is the wrong type, shape, or value.
Why
Every assertion follows the same simple contract:
- Checks one thing. Each function tests a single, explicit condition.
- Returns its input invisibly. Checks can be stacked, one per line, reading like a checklist of preconditions.
-
Fails loudly and clearly. On failure it throws an error that names the offending argument and points at your function, not at
assert’s internals. -
Explicit, readable names.
assert_scalar_character(), notassert_chr().
Installation
assert is not on CRAN; install it from GitHub with renv:
# first install renv itself if you don't have it: install.packages("renv")
renv::install("dereckscompany/assert")Usage
Write assertions at the top of a function. If one fails, it throws an error and the function stops immediately.
box::use(
assert[
assert_numeric,
assert_no_missing_values,
assert_all_positive,
assert_same_length
]
)
average_price <- function(prices, weights) {
assert_numeric(prices)
assert_no_missing_values(prices)
assert_all_positive(prices)
assert_same_length(prices, weights)
return(sum(prices * weights) / sum(weights))
}
average_price(c(10, 20, 30), c(1, 1, 2))
#> [1] 22.5When an input is invalid, the error names the argument and the calling function:
average_price(c(10, -5, 30), c(1, 1, 2))
#> Error in `average_price()`:
#> ! `prices` must contain only positive values (greater than zero).Optional arguments
Arguments that default to NULL are optional. Pass null_ok = TRUE to let the assertion accept NULL while still checking any value that is supplied:
box::use(assert[assert_scalar_character, assert_scalar_integer])
connect <- function(host, port = NULL) {
assert_scalar_character(host)
assert_scalar_integer(port, null_ok = TRUE)
return(invisible(TRUE))
}
connect("localhost") # port omitted — fine
connect("localhost", 8080L) # port supplied and valid — fineStacking checks with the pipe
Because every assertion returns its input invisibly, checks compose naturally with the native pipe |>. Each one validates the value and hands it to the next, so a chain reads like a list of guarantees about the same object:
box::use(assert[assert_data_frame, assert_has_columns, assert_column_types])
people <- data.frame(name = c("Ada", "Alan"), age = c(36L, 41L))
people |>
assert_data_frame() |>
assert_has_columns(c("name", "age")) |>
assert_column_types("character", "name") |>
assert_column_types("integer", "age") |>
invisible()What it covers
See vignette("assert") for a tour.
License
MIT © Dereck Mezquita. See LICENSE for details.
Citation
If you use assert in your work, please cite it:
Mezquita, D. (2026). assert. https://github.com/dereckscompany/assert. ORCID: 0000-0002-9307-6762
