Learn R Programming

assertive

An R package that provides readable check functions to ensure code integrity.

There are times when it is a good idea to check the state of your variables, to ensure that they have the properties that you think they have. For example, if you have a count variable, you might want to check that it is numeric, that all the values are non-negative, and that all the values are whole numbers.

assertive provides lots of functions ("predicates" and "assertions") to provide such checks. It is designed to make your code very easy to read, and to provide highly informative error messages.

Installation

To install the stable version, type:

install.packages("assertive")

To install the development version, you first need the devtools package.

install.packages("devtools")

Then you can install the assertive package using

library(devtools)
install_bitbucket("richierocks/assertive")

How to use the package

assertive contains lots of assert functions ("assertions") that throw errors if conditions aren't met. They are very useful for checking user input to your functions.

For example,

f <- function(x)
{
  assert_is_not_null(x)
  x + 1
}
f(1)
## [1] 2
f(NULL)
## Error in f(NULL) : x is NULL.

(You can think of the assert functions as more specific versions of base::stopifnot that make your code easier to read and give more informative error messages.)

Each assert function has a corresponding is function (a "predicate"). In this case, is_not_null is a wrapper to base-R's !is.null, that gives a more informative error message on failure (in an attribute named cause).

is_not_null(1)
## [1] TRUE

is_not_null(NULL)
## [1] FALSE
## Cause of failure:  NULL is NULL.

Many of the is functions are wrappers to base functions. They all return causes of failure, and they have consistent naming, beginning is_ or has_ (so base::interactive becomes is_interactive, for example.)

Vectorised is functions

Some is functions return a logical vector rather than a single value. In this case the input values are returned in the names to make it easier to see which values succeeded/failed, and the cause attribute is also vectorised.

For example,

is_positive(c(1, 0, -1, NA))
## There were 3 failures:
##   Position Value   Cause
## 1        2     0 too low
## 2        3    -1 too low
## 3        4  <NA> missing

Using unclass, you can see that this is just a logical vector, with a cause attribute.

unclass(is_positive(c(1, 0, -1, NA)))
##     1     0    -1  <NA> 
##  TRUE FALSE FALSE    NA 
## attr(,"cause")
## [1]         too low too low missing

There are two corresponding assert functions for these vectorised is functions.

assert_any_are_positive(c(1, 0, -1, NA)) # test passed since 1 is positive
assert_all_are_positive(c(1, 0, -1, NA))
## Error: c(1, 0, -1, NA) contains non-positive values.
## There were 3 failures:
##   Position Value   Cause
## 1        2     0 too low
## 2        3    -1 too low
## 3        4  <NA> missing

Can't I just use testthat?

testthat is an excellent package for writing unit tests, and I recommend that you use it. Unit tests are a form of development-time testing. That is, you write the tests while you develop your code in order to check that you haven't made any mistakes.

assertive, and assertions in general, are for run-time testing. That is, you include them in your code to check that the user hasn't made a mistake while running your code.

The virtual package system

assertive is a virtual package; it does not contain any functions, but merely reexports them from lower-level packages. For a complete reference, see the individual package pages.

assertive.base contains the core functionality. For example, is_true checks when inputs return TRUE. It also contains some utility functions, such as use_first, which returns the first value of a vector, warning you if it was longer than length one.

assertive.properties contains checks on properties of variables. For example, is_scalar checks for values that have length one, and has_duplicates checks for the presence of duplicate values.

assertive.types contains checks for types of variables. For example, is_character wraps the base is.character, while is_a_string combines that check with is_scalar to check for single strings.

assertive.numbers contains checks for numbers. For example, is_in_range checks if a number is in a numeric range.

assertive.strings contains checks for strings. For example, is_an_empty_string checks if a character vector contains a single empty string.

assertive.datetimes contains checks for dates and times. For example, is_in_past checks if a Date or POSIXt obejct is in the past.

assertive.files contains checks for files and connections. For example, is_readable_file checks if a path points to a file that R has permission to read, and is_file_connection check if an object is a file connection.

assertive.sets contains checks for sets. For example, is_subset checks if a vector is a subset of another vector.

assertive.matrices contains checks for matrices. For example, is_symmetric_matrix checks if a matrix is symmetric.

assertive.models contains checks for models. For example, is_empty_model checks if a model is the empty model (no factors).

assertive.data contains checks for complex data types. For example, is_credit_card_number checks a character vector for valid credit card numbers.

assertive.data.uk contains checks for UK-specific complex data types. For example, is_uk_postcode checks a character vector for valid UK postcodes.

assertive.data.us contains checks for US-specific complex data types. For example, is_us_telephone_number checks a character vector for valid US telephone numbers.

assertive.reflection contains checks on the state of R. For example, is_solaris tests for that operating system, and is_rstudio tests for that IDE.

assertive.code contains checks for code. For example, is_valid_variable_name checks whether a character vector contains valid variable names.

I hate this; what's the alternative?

There are at least five other R packages for doing assertions. In alphabetical order of package:

I want to know more

There are several vignettes with more details on how to use the package, including case studies and exercises. Find them using

browseVignettes()

I want to help

The assertive packages are in the process of being translated into many languages. If you speak a language other than English, and have an hour or two spare, your translation skills would be appreciated.

assertive is also currently lacking assertions for time series, spatial data, personal data for countries other than the UK and US, and industry-sector-specific data. If you want to contribute a package for these data types, let me know and I can talk you through how to do it.

Copy Link

Version

Install

install.packages('assertive')

Monthly Downloads

262

Version

0.3-6

License

GPL (>= 3)

Maintainer

Last Published

August 1st, 2020

Functions in assertive (0.3-6)

has_any_attributes

Does the input have any attributes?
is_closure_function

Is the input a closure, builtin or special function?
is_array

Is the input an array or matrix?
is_class

Is the input the name of a (formally defined) class?
is_existing

is_existing_file

Does the file exist?
has_arg

is_atomic

Is the input atomic/recursive/vector?
is_debugged

is_date_string

Does the character vector contain dates?
has_attributes

Does the input have the specified attributes?
call_and_name

Call a function, and give the result names.
is_s3_generic

Is the input an S3 generic or method?
is_ip_address

Does the character vector contain IP addresses?
is_empty

Is the input empty/scalar?
is_monotonic_increasing

Is the vector monotonically increasing or decreasing?
is_nan

Is the input (not) NaN?
is_empty_character

Does the input contain empty or missing strings?
has_cols

Does the input have rows/columns?
assertionError

Condition classes
is_isbn_code

Does the character vector contain ISBN book codes?
cause

Get or set the "cause" attribute
false

FALSE, with a cause of failure
has_slot

Does the S4 input have a slot?
has_names

Does the input have names?
coerce_to

Coerce variable to a different class
is_batch_mode

How is R running?
is_complex

Is the input complex?
has_dims

Does the input have dimensions?
dont_stop

Run code without stopping
has_duplicates

Does the input have duplicates?
is_binding_locked

is_diagonal_matrix

Is the input a diagonal matrix?
is_externalptr

Is the input an external pointer?
is_connection

Is the input a connection?
is_s4

Is the input an S4 object?
changes

Important changes to assertive
is_credit_card_number

Does the character vector contain credit card numbers?
get_name_in_parent

Get the name of a variable in the parent frame
is_symmetric_matrix

Is the input a symmetric matrix?
is_empty_file

Is a file too big or small?
is_dir

Is the path a directory?
is_date

Is the input a date?
is_data.frame

Is the input is a data.frame?
is_data.table

Is the input a data.table?
is_honorific

Is the string an honorific?
is_error_free

is_executable_file

Is the file accessible?
is_identity_matrix

Is the input an identity matrix?
is_list

Is the input a list?
is_library

Is the directory a known R library?
is_empty_model

Is the input the empty model?
is_in_range

Is the input in range?
is_function

Is the input a function?
is_factor

Is the input a factor?
is_hex_color

Does the character vector contain hex colors?
is_inherited_from

Does the object inherit from some class?
is_valid_variable_name

is_table

Is the input a table?
is_whole_number

Is the input a whole number?
is_lower_triangular_matrix

Is the matrix upper/lower triangular?
character_to_list_of_integer_vectors

is_on_os_path

Is the path on the OS path?
is_numeric_string

is_rstudio_current

Is RStudio the current version?
is_matching_fixed

is_single_character

is_rstudio_desktop

Is RStudio running in desktop or server mode?
is_real

Is the input real/imaginary?
is_relistable

Is the input relistable?
is_in_past

Is the input in the past/future?
is_if_condition

is2

Alternative version of is
has_terms

Does the input have terms?
is_cas_number

Does the character vector contain CAS registry numbers?
is_square_matrix

Is the input a square matrix?
is_email_address

Does the character vector contain email addresses?
is_character

Is the input of type character?
is_divisible_by

Is the input divisible by a number?
is_us_zip_code

Is the string a valid US zip code?
is_valid_r_code

r_can_find_tools

Can R find tools?
is_environment

Is the input an environment?
is_logical

Is the input logical?
is_loaded

is_language

Is the input a language object?
is_tbl

Is the input a tbl?
is_equal_to

How does the input relate to a value?
is_internal_function

Is the input an internal function?
is_formula

Is the input a formula?
is_integer

Is the input an integer?
is_null

Checks to see if the input is (not) null.
is_finite

Are the inputs (in)finite?
is_uk_national_insurance_number

Is the string a valid UK national insurance number?
is_uk_postcode

Is the string a valid UK postcode?
r_has_jpeg_capability

Does R have a capability?
is_numeric

Is the input numeric?
is_r

Are you running R?
is_windows

What OS is running?
is_package_current

Is the installed version of a package current?
is_zero_matrix

Is the input a zero matrix?
merge_dots_with_list

Merge ellipsis args with a list.
is_qr

Is the input a QR decomposition of a matrix?
is_leaf

Is the input a (dendrogram) leaf?
is_xxx_for_decimal_point

What does the current locale specify for the decimal point?
is_r_current

Is this version of R up to date?
is_raster

Is the input a raster?
is_raw

Is the input raw?
use_first

Only use the first element of a vector
safe_deparse

Safe version of deparse
is_try_error

Is the input a condition?
set_cause

Set a cause and return the input
is_ts

Is the input a time series?
is_uk_telephone_number

Is the string a valid UK telephone number?
is_uk_car_licence

Is the string a valid UK car licence plate number?
na

NA, with a cause of failure
is_us_telephone_number

Is the string a valid US telephone number?
is_us_social_security_number

Is the string a valid US SSN?
n_elements

Get the number of elements
strip_attributes

Strip all attributes from a variable
sys_get_locale

Get or set the system locale
parenthesize

Wrap a string in brackets
print_and_capture

Print a variable and capture the output
is_unsorted

Is the input unsorted?
are_set_equal

Set comparisons
Truth

Is the input TRUE/FALSE/NA?
bapply

Wrapper to vapply that returns booleans.
assert_is_all_of

Does x belong to these classes?
assertive

Readable check functions to ensure code integrity.
DIM

Get the dimensions of an object
assert_engine

Throws an error if a condition isn't met
are_identical

Are the inputs identical?
are_same_length

Are the inputs the same length/dimension?