The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Condition handling

Colin Fay

2020-05-03

warnings and messages

The stop_if(), warn_if() and message_if() are easy to use functions that send an error, a warning or a message if a condition is met. Each function has its counterpart with _not that returns a message if the condition is not met.

stop_if_not() is quite the same as assert_that() from the {assertthat} package, except that it can takes mappers. It is not the same as base stopifnot(), as it doesn’t take a list of expression.

These functions are also flexible as you can pass base predicates (is.numeric, is.character…), a custom predicate built with mappers, or even your own predicate function.

You can either choose a custom message or just let the built-in messages be printed:

x <- 12
# Stop if .x is numeric
stop_if(.x = x, 
        .p = is.numeric)

y <- "20"
# stop if .x is not numeric
stop_if_not(.x = y, 
            .p = is.numeric, 
            msg = "y should be numeric")
a  <- "this is not numeric"
# Warn if .x is charcter
warn_if(.x = a, 
        .p = is.character)

b  <- 20
# Warn if .x is not equal to 10
warn_if_not(.x = b, 
        .p = ~ .x == 10 , 
        msg = "b should be 10")

c <- "a"
# Message if c is a character
message_if(.x = c, 
           .p = is.character, 
           msg = "You entered a character element")

# Build more complex predicates
d <- 100
message_if(.x = d, 
           .p = ~ sqrt(.x) < 42, 
           msg = "The square root of your element must be more than 42")

# Or, if you're kind of old school, you can still pass classic functions

e <- 30
message_if(.x = e, 
           .p = function(vec){
             return(sqrt(vec) < 42)
           }, 
           msg = "The square root of your element must be more than 42")

If you need to call a function that takes no argument at .p (like curl::has_internet()), use this function as .x.

stop_if(.x = curl::has_internet(), msg = "You shouldn't have internet to do that")

warn_if(.x = curl::has_internet(), 
            msg = "You shouldn't have internet to do that")

message_if(.x = curl::has_internet(), 
            msg = "Huray, you have internet \\o/")

If you don’t specify a .p, the default test is isTRUE().

a <- is.na(airquality$Ozone)
message_if_any(a, msg = "NA found")

In function

That can come really handy inside a function:

my_fun <- function(x){
  stop_if_not(.x = curl::has_internet(), 
              msg = "You should have internet to do that")
  warn_if_not(x, 
          is.character, 
          msg =  "x is not a character vector. The output may not be what you're expecting.")
  paste(x, "is the value.")
}

my_fun(head(iris))

none, all, any

stop_if(), warn_if() and message_if() all have complementary tests with _all, _any and _none, which combine the if_* and the warn_*, stop_* and message_* seen before. They take a list as first argument, and a predicate. They test if any, all or none of the elements validate the predicate.

stop_if_any(iris, is.factor, msg = "Factors here. This might be due to stringsAsFactors.")

warn_if_none(1:10, ~ .x < 0, msg = "You need to have at least one number under zero.")

message_if_all(1:100, is.numeric, msg = "That makes a lot of numbers.")

on_error()

on_error() behaves as on.exit() except it happens only when there is an error in the function.

y <- function(x){
  on_error(~ print("ouch"))
  log(x)
}
y(12)
[1] 2.484907
y("a")
Error in log(x) : non-numeric argument to mathematical function
[1] "ouch"

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.