vetr (version 0.2.4)

vet: Verify Objects Meet Structural Requirements

Description

Use vetting expressions to enforce structural requirements for objects. tev is a version of vet compatible with magrittr pipes.

Usage

vet(target, current, env = parent.frame(), format = "text", stop = FALSE,
  settings = NULL)

tev(current, target, env = parent.frame(), format = "text", stop = FALSE, settings = NULL)

Arguments

target

a template, a vetting expression, or a compound expression

current

an object to vet

env

the environment to match calls and evaluate vetting expressions in; will be ignored if an environment is also specified via vetr_settings(). Defaults to calling frame.

format

character(1L), controls the format of the return value for vet, in case of failure. One of:

  • "text": (default) character(1L) message for use elsewhere in code

  • "full": character(1L) the full error message used in "stop" mode, but actually returned instead of thrown as an error

  • "raw": character(N) least processed version of the error message with none of the formatting or surrounding verbiage

stop

TRUE or FALSE whether to call stop() on failure or not (default)

settings

a settings list as produced by vetr_settings(), or NULL to use the default settings

Value

TRUE if validation succeeds, otherwise varies according to value chosen with parameter stop

Vetting Expressions

Vetting expressions can be template tokens, standard tokens, or any combination of template and standard tokens combined with && and/or ||. Template tokens are R objects that define the required structure, much like the FUN.VALUE argument to vapply(). Standard tokens are tokens that contain the . symbol and are used to vet values.

See vignette('vetr', package='vetr') and examples for details on how to craft vetting expressions.

Details

tev just reverses the target and current arguments for better integration with magrittr. There are two major caveats:

  • error messages will be less useful since you will get . instead of the deparsed call

  • x \%>\% tev(y) is much slower than vet(y, x) (or even tev(x, y))

See Also

vetr() for a version optimized to vet function arguments, alike() for how templates are used, vet_token() for how to specify custom error messages and also for predefined validation tokens for common use cases, all_bw() for fast bounds checks.

Examples

Run this code
# NOT RUN {
## template vetting
vet(numeric(2L), runif(2))
vet(numeric(2L), runif(3))
vet(numeric(2L), letters)
try(vet(numeric(2L), letters, stop=TRUE))

## `tev` just reverses target and current for use with maggrittr
# }
# NOT RUN {
if(require(magrittr)) {
  runif(2) %>% tev(numeric(2L))
  runif(3) %>% tev(numeric(2L))
}
# }
# NOT RUN {
## Zero length templates are wild cards
vet(numeric(), runif(2))
vet(numeric(), runif(100))
vet(numeric(), letters)

## This extends to data.frames
iris.tpl <- iris[0,]   # zero row matches any # of rows
iris.1 <- iris[1:10,]
iris.2 <- iris[1:10, c(1,2,3,5,4)]  # change col order
vet(iris.tpl, iris.1)
vet(iris.tpl, iris.2)

## Short (<100 length) integer-like numerics will
## pass for integer
vet(integer(), c(1, 2, 3))
vet(integer(), c(1, 2, 3) + 0.1)

## Nested templates; note, in packages you should consider
## defining templates outside of `vet` or `vetr` so that
## they are computed on load rather that at runtime
tpl <- list(numeric(1L), matrix(integer(), 3))
val.1 <- list(runif(1), rbind(1:10, 1:10, 1:10))
val.2 <- list(runif(1), cbind(1:10, 1:10, 1:10))
vet(tpl, val.1)
vet(tpl, val.2)

## See `example(alike)` for more template examples

## Standard tokens allow you to check values
vet(. > 0, runif(10))
vet(. > 0, -runif(10))

## Zero length token results are considered TRUE,
## as is the case with `all(logical(0))`
vet(. > 0, numeric())

## `all_bw` is like `isTRUE(all(. >= x & . <= y))`, but
## ~10x faster for long vectors:
vet(all_bw(., 0, 1), runif(1e6) + .1)

## You can combine templates and standard tokens with
## `&&` and/or `||`
vet(numeric(2L) && . > 0, runif(2))
vet(numeric(2L) && . > 0, runif(10))
vet(numeric(2L) && . > 0, -runif(2))

## Using pre-defined tokens (see `?vet_token`)
vet(INT.1, 1)
vet(INT.1, 1:2)
vet(INT.1 && . %in% 0:1 || LGL.1, TRUE)
vet(INT.1 && . %in% 0:1 || LGL.1, 1)
vet(INT.1 && . %in% 0:1 || LGL.1, NA)

## Vetting expressions can be assembled from previously
## defined tokens
scalar.num.pos <- quote(numeric(1L) && . > 0)
foo.or.bar <- quote(character(1L) && . %in% c('foo', 'bar'))
vet.exp <- quote(scalar.num.pos || foo.or.bar)

vet(vet.exp, 42)
vet(scalar.num.pos || foo.or.bar, 42)  # equivalently
vet(vet.exp, "foo")
vet(vet.exp, "baz")
# }

Run the code above in your browser using DataCamp Workspace