knitr::opts_chunk$set(error=TRUE) library(vetr)
Fast #rstats bounds checks with vetr::all_bw
https://github.com/brodieG/vetr;
10x improvement over primitives (1/3):
~30% of speedup is avoiding 3x1e6 temp logical vecs, rest is dedicated loops for input permutations (num/int/char, nas, infs, etc.) (2/3).
Peeling back abstraction layer is eye-opening. Massive complexity to implement something seemingly so simple in optimized manner (3/3).
~1/3 of speedup is avoiding 3 logical(1e6) intermediate vectors, rest is stripping inner loops to bare minimum:
Declarative structural guarantees for #rstats S3 objects via templates with new pkg #vetr https://github.com/brodieG/vetr (1/4)
Declarative checks via templates, much like vapply
:
vet(numeric(1L), 1:3) vet(numeric(1L), "hello") vet(numeric(1L), 42)
vet(matrix(integer(), ncol=3), matrix(1:12, 4)) vet(matrix(integer(), ncol=3), matrix(1:12, 3))
Even recursive ones:
iris.template <- abstract(iris) levels(iris$Species)[3] <- 'Sibirica' # corrupt iris
vet(iris.template, iris[1:10,])
Note the useful error messages.
We made vetr
fast to mitigate overhead concerns. There is a
dedicated mode for fun param vetting (2/4)
Comparable in performance to stopifnot
for simple checks, and faster for
complex ones:
mx.3.col.num <- matrix(numeric(), ncol=3) mx1 <- matrix(1:12, 4) bench_mark(times=1e4, vet(mx.3.col.num, mx1), stopifnot(is.matrix(mx1), is.numeric(mx1), ncol(mx1) == 3) )
vetr()
streamlines function parameter vetting:
fun <- function(x, y) { vetr(integer(), character(1L) || NULL) } fun(1, 'hello') fun(1, NULL) fun(1, 2)
Create complex vetting expressions with intuitively programmable non-standard-evaluation (3/4)
vetr
implements programmable NSE via recursive substitution of language
objects. This allows you to construct complex vetting expressions from simple
ones:
a <- quote(integer() && . > 0) b <- quote(logical(1L) && !is.na(.))
vet(a || b, 1:3) vet(a || b, -1)
c <- quote(a || b) # equivalently
vet(c, -1)
On CRAN, 100% coverage with #covr https://github.com/jimhester/covr and #unitizer https://github.com/brodieG/unitizer, but under dev so feedback welcome (4/4)
Announcing New Package vetr on CRAN
vetr
implements a declarative template-based approach to verify that objects
meet structural requirements, and auto-compose error messages when they do not.
This package is intended to simplify a more formal use of S3 objects.
The template concept is borrowed from vapply
:
vet(numeric(1L), 1:3) [1] "
1:3
should be length 1 (is 3)" vet(numeric(1L), "hello") [1] "\"hello\"
should be type \"numeric\" (is \"character\")" vet(numeric(1L), 42) [1] TRUE
There is no limit on template complexity:
vet(matrix(integer(), ncol=3), matrix(1:12, 3)) [1] "
matrix(1:12, 3)
should have 3 columns (has 4)"iris.template <- abstract(iris) levels(iris$Species)[3] <- 'sibirica' vet(iris.template, iris[1:10,]) [1] "
levels((iris[1:10, ])$Species)[3]
should be \"virginica\" (is \"sibirica\")"
vetr
implements programmable non-standard evaluation via recursive
substitution of language objects:
a <- quote(integer() && . > 0) b <- quote(logical(1L) && !is.na(.)) c <- quote(a || b) vet(c, -1) [1] "At least one of these should pass:" [2] " -
-1 > 0
is not TRUE (FALSE)" [3] " --1
should be type \"logical\" (is \"double\")"
Performance is comparable to stopifnot
for simple checks, and is faster for
complex (template based) ones. There is a mode that further streamlines
parameter vetting in functions.
The package is still under development, but the features should be mostly stable. Feedback welcome (https://github.com/brodieG/vetr).
Best regards,
Brodie.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.