assertthat provides a drop in replacement forstopifnot() that makes it easy to check the pre- andpost-conditions of a function, while producing useful errormessages.
x<-1:10stopifnot(is.character(x))# Error: is.character(x) is not TRUEassert_that(is.character(x))# Error: x is not a character vectorassert_that(length(x)==5)# Error: length(x) not equal to 5assert_that(is.numeric(x))# [1] TRUEThis is a good defensive programming technique, and is useful assource-code documentation: you can see exactly what your functionexpects when you come back to it in the future. It is partly a responseto the lack of static typing in R, but it allows you to test for generalconditions (likelength(x) == length(y)) that are difficultto express in a type system.
assertthat can be installed either from CRAN:
install.packages('assertthat')or with devtools:
devtools::install_github("hadley/assertthat")As well as all the functions provided by R, assertthat provides a fewmore that I use a lot:
is.flag(x): is xTRUE orFALSE? (a boolean flag)is.string(x): is x a length 1 character vector?has_name(x, nm),x %has_name% nm: doesx have componentnm?has_attr(x, attr),x %has_attr% attr: doesx have attributeattr?is.count(x): is x a single positive integer?are_equal(x, y): arex andyequal?not_empty(x): are all dimensions ofxgreater than 0?noNA(x): isx free from missingvalues?is.dir(path): ispath a directory?is.writeable(path)/is.readable(path): ispath writeable/readable?has_extension(path, extension): doesfilehave givenextension?assert_that,see_if andvalidate_thatThere are three main functions in assertthat:
assert_that() signal an error
see_if() returns a logical value, with the errormessage as an attribute.
validate_that() returnsTRUE onsuccess, otherwise returns the error as a string.
You’ll useassert_that() in your own code, but you’llmostly seesee_if() in the examples (becauseR CMD check requires that examples run without errors). Usevalidate_that() for S4 validate methods.
If you’re writing your own assertions, you can provide custom errormessages using theon_failure() helper:
is_odd<-function(x) {assert_that(is.numeric(x),length(x)==1) x%%2==1}assert_that(is_odd(2))# Error: is_odd(x = 2) is not TRUEon_failure(is_odd)<-function(call, env) {paste0(deparse(call$x)," is even")}assert_that(is_odd(2))# Error: 2 is evenTheon_failure callback is called with two arguments,the unevaluated functioncall (which has already beenstandardised withmatch.call()), andenv, andthe environment in which the assertion was executed. This allows you tochoose between displaying values or names in your error messages. Readtheadvanced Rbook to learn more about working with calls.
Also note the use ofassert_that() in our new function:assertions flow through function calls ensuring that you get a usefulerror message at the top level:
assert_that(is_odd("b"))# Error: x is not a numeric or integer vectorassert_that(is_odd(1:2))# Error: length(x) not equal to 1