Home > R > Be assertive!

Be assertive!

assert_package_is_awesome("assertive") returns TRUE.

assertive, my new package for writing robust code, is now on CRAN. It consists of lots of is functions for checking variables, and corresponding assert functions that throw an error if the condition doesn’t hold. For example, is_a_number checks that the input is numeric and scalar.

is_a_number(1)     #TRUE
is_a_number("a")   #FALSE
is_a_number(1:10)  #FALSE

In the last two cases, the return value of FALSE has an attribute “cause” that indicates the cause of failure. When “a” is the input, the cause is “"a" is not of type 'numeric'.“, whereas for 1:10, the cause is “1:10 does not have length one.“. You can get or set the cause attribute with the cause function.

m <- lm(uptake ~ 1, CO2)
ok <- is_empty_model(m)
if(!ok) cause(ok)

The assert functions call an is function, and if the result is FALSE, they throw an error; otherwise they do nothing.

assert_is_a_number(1)   #OK
assert_is_a_number("a") #Throws an error

There are also some has functions, primarily for checking the presence of attributes.

has_names(c(foo = 1, bar = 4, baz = 9))
has_dims(matrix(1:12, nrow = 3))

Some functions apply to properties of vectors. In this case, the assert functions can check that all the values conform to the condition, or any of the values conform.

x <- -2:2
is_positive(x)              #The last two are TRUE
assert_any_are_positive(x)  #OK
assert_all_are_positive(x)  #Error

“Why would you want to use these functions?”, you may be asking. The dynamic typing and extreme flexibility of R means that it is very easy to have variables that are the wrong format. This is particularly true when you are dealing with user input. So while you know that the sales totals passed to your function should be a vector of non-negative numbers, or that the regular expression should be a single string rather than a character vector, your user may not. You need to check for these invalid conditions, and return an error message that the user can understand. assertive makes it easy to do all this.

Since this is the first public release of assertive, it hasn’t been widely tested. I’ve written a moderately comprehensive unit-test suite, but there are likely to be a few minor bugs here and there. In particular, I suspect there may be one or two typos in the documentation. Please give the package a try, and let me know if you find any errors, or if you want any other functions adding.

  1. 30th May, 2012 at 13:32 pm

    I like it! It’s so readable.

  2. Jan
    30th May, 2012 at 14:53 pm
    • 30th May, 2012 at 15:07 pm

      Interesting library. The syntax looks remarkably like R’s testthat package, so I wonder if it is a descendant of hamcrest.

      • schulzjan
        30th May, 2012 at 15:23 pm

        Ah, that’s why I thought that I have seen a similar R package đŸ™‚ I just wonder why you wouldn’t reuse or extend thestthat? I would guess that the assert_all_are_positive(x) example would become “assert_that(all(are_positive()), x)”. Not quite that readable than your syntax, but more flexible: the any eample just needs on moew method: “assert_that(any(are_positive()), x)”.

        • 30th May, 2012 at 15:51 pm

          testthat has a slightly different purpose: it’s designed for unit testing. So testthat code belongs in the inst/tests folder of your package, whereas as assertive code is designed to be contained inside your R functions (in the R folder). And the main benefit of providing functions that test for specific things is that you can provide more readable error messages. I will have a think about how to make things more general though.

          • 4th June, 2012 at 21:00 pm

            I think there’s some connection, though, in that the conditions you want to check in tests and assertions are similar. I’ve also wondered about some more declarative way to describe assertions, e.g. assert(is.numeric(x) && length(x) == 2), that could still produce nice error messages.

          • 4th June, 2012 at 21:30 pm

            A way of passing in arbitrary conditions to be checked does seem useful. I’ve half an idea of how to implement it, so cross your fingers for the next release.

  3. 30th May, 2012 at 15:39 pm

    looks really good; I’m downloading it now. It seems like it could be really useful for error-proofing code

  4. Tom
    31st May, 2012 at 0:57 am

    While I’m not yet by any stretch writing code for the masses. I am a huge superfan of useful error messages! Thanks!

  5. 8th June, 2012 at 1:29 am

    Ah, lovely error messages. Do you have a github repo anywhere perchange?

    • 11th June, 2012 at 22:17 pm

      The development version is hosted on Bitbucket.


      • 13th June, 2012 at 2:58 am

        Is it open for forking, etc.? I can an authorisation error when I follow your link.

        • 14th June, 2012 at 11:36 am

          Bitbucket doesn’t currently support anonymous access to repositories afaik, so you’ll have to sign up for an account. (Free accounts are available.) Once you log in, you should be able to clone it.

          I’m happy to accept contributions if you have ideas for new functions.

  6. 15th June, 2012 at 0:06 am

    Sorry to turn this thread into a bit-bucket trail, but sadly even when I am logged in with a (free) account I can’t see your repo (or any of your repos): http://imgur.com/a/XNJX8 .

    • 15th June, 2012 at 14:14 pm

      Hmm, seems I’d somehow accidentally marked the repo as private. Try again now; it should work this time.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: