Learn R Programming

zmisc

Vector Look-Ups and Safer Sampling

A collection of utility functions that facilitate looking up vector values from a lookup table, annotate values in a table for clearer viewing, and support a safer approach to vector sampling, sequence generation, and aggregation. Also included is a family of argument checks which return their input so that they compose nicely in a pipe.

Installation

Install the released version from CRAN:

install.packages("zmisc")

Or the development version from GitHub, using pak:

pak::pak("torfason/zmisc")

Usage

library(zmisc)

Quick and easy value lookups

lookup() looks up values (such as variable names) in a lookup table that maps keys onto values (such as variable labels). The table can be a two-column data.frame, a named vector, or a list. Values that are not found are returned unchanged, or replaced by .default.

fruit_lookup_vector <- c(a = "Apple", b = "Banana", c = "Cherry")
lookup(letters[1:5], fruit_lookup_vector)
#> [1] "Apple"  "Banana" "Cherry" "d"      "e"
lookup(letters[1:5], fruit_lookup_vector, .default = NA)
#> [1] "Apple"  "Banana" "Cherry" NA       NA

lookuper() returns a function that does the same lookup, with the table embedded in the function itself. That is useful wherever a character->character function is expected but there is no good way to pass the table along with it.

lookup_fruits <- lookuper(list(a = "Apple", b = "Banana", c = "Cherry"))
lookup_fruits(letters[1:5])
#> [1] "Apple"  "Banana" "Cherry" "d"      "e"

Safer sampling, sequencing and aggregation

zample(), zeq() and zingle() make code less likely to break in mysterious ways at awkward boundary conditions.

zample() is sample() without the user-friendliness of switching to 1:n when the input happens to have length 1.

# For vectors of length 2 or more, zample() and sample() are identical
set.seed(42); zample(7:11)
#> [1]  7 11 10  9  8
set.seed(42); sample(7:11)
#> [1]  7 11 10  9  8

# For length 1, sample() "magically" switches to sampling from 1:n
set.seed(42); zample(7)
#> [1] 7
set.seed(42); sample(7)
#> [1] 1 5 7 6 2 3 4

zeq() is gives a strictly increasing integer sequence. A second argument one below the first gives an empty sequence, anything lower is an error.

zeq(11, 15)
#> [1] 11 12 13 14 15
zeq(11, 10)
#> integer(0)
tryCatch(zeq(11, 9), error = wrap_error)
#> #E> `to` must not be smaller than `from` - 1 (got
#> #E> from = 11, to = 9)

zingle() returns the single distinct value in a vector, and errors if there is more than one. This is useful in aggregations where all values in a group should be identical, but where the assumption is worth checking.

zingle(c("Alpha", "Alpha", "Alpha"))
#> [1] "Alpha"
tryCatch(zingle(c("Alpha", "Beta", "Alpha")), error = wrap_error)
#> #E> `x` must contain a single unique value, but found
#> #E> 2 distinct values.

# zingle() is useful to ensure an data.frame summary is well formed
if (require("dplyr", quietly = TRUE, warn.conflicts = FALSE)) {
  d <- data.frame(
    id    = c(1, 2, 1),
    name  = c("James", "Jack", "James"),
    fouls = c(3, 2, 4))

  d |>
    group_by(id) |>
    summarise(name = zingle(name), total_fouls = sum(fouls))
}
#> # A tibble: 2 × 3
#>      id name  total_fouls
#>   <dbl> <chr>       <dbl>
#> 1     1 James           7
#> 2     2 Jack            2

Checks with rlang-style errors

The chk_*() functions check the type and shape of an argument and, on failure, raise an rlang-style error naming the argument as the caller wrote it. Each function returns its input, so a check can sit in the middle of a pipe, and each is cheap enough on the passing path to leave at the top of any function. The checking is backed by the checkmate package.

# The check returns its input, so it composes in a pipe
c(2, 4, 6) |> chk_numeric(length = 3) |> sum()
#> [1] 12

# On failure, the error names the argument as the caller wrote it
my_mean <- function(x) {
  chk_numeric(x)
  sum(x) / length(x)
}
tryCatch(my_mean("seven"), error = wrap_error)
#> #E> Assertion on `x` failed: • Must be of type
#> #E> 'numeric', not 'character'

There are checks for every atomic type in scalar and vector form, for lists and composite objects, and for classes and arbitrary conditions. See vignette("chk") for the full set and the shared parameters.

Getting a better view on variables

notate() annotates factor and labelled variables so that both values and labels are visible at once, which neither printing nor View() manages on its own.

d <- data.frame(
  chr = letters[1:4],
  fct = factor(c("alpha", "bravo", "chrly", "delta")),
  lbl = ll_labelled(c(1, 2, 3, NA),
                    labels = c(one = 1, two = 2),
                    label = "A labelled vector")
)
notate(d)
#>   chr       fct     lbl
#> 1   a [1] alpha [1] one
#> 2   b [2] bravo [2] two
#> 3   c [3] chrly     [3]
#> 4   d [4] delta    <NA>
# View(notate(d))

Other utilities

  • glue_vector() applies a glue() template element-wise to a vector, for pipe-friendly interpolation outside a data.frame.
  • asciify() transliterates accented characters to ASCII.
  • yencode() encodes arbitrary strings into a restricted character set, and ydecode() reverses it.

Copy Link

Version

Install

install.packages('zmisc')

Monthly Downloads

286

Version

0.3.0

License

MIT + file LICENSE

Issues

Pull Requests

Stars

Forks

Maintainer

Magnus Torfason

Last Published

September 27th, 2026

Functions in zmisc (0.3.0)

zingle

Return the single (unique) value found in a vector
zample

Sample from a vector in a safe way
zmisc-package

zmisc: Vector Look-Ups and Safer Sampling
zeq

Generate sequence in a safe way
chk_other

Various other check functions
asciify

Convert non-ASCII characters to their ASCII equivalents
chk_atomic

Checks for scalars and atomic vectors
glue_vector

Glue interpolation vectors in pipes
chk_composite

Checks for lists and composite objects
ll_labelled

Create a labelled variable
.yencode_map

Compile an encoding table for yencode
import_all_chk

Generate imports for all assertions functions
ddply_helper

Apply a function to each column of a data.frame
yencode

Yet (another urlencode compatible) encoding scheme
wrap_error

Utility function to output an error
ll_chk_labelled

Verify that x is a valid labelled variable
threadbare

Return a threadbare version of a vector
ll_var_label

Get or set variable label of a labelled variable
standardize_lookup_table

Helper function to standardize the lookup_table.
lookup

Lookup values from a lookup table
notate

Embed factor levels and value labels in values.
ll_val_labels

Get or set value labels of a labelled variable
reexports

Objects exported from other packages
ll_to_character

Get the character representation of a labelled variable