174

How does one "throw" an error in R? I have a function that takes a data frame and some column names and does stuff with them. If the columns don't exist, I want the function to stop and to stop all functions depending on it.

I have looked at recover and browse and traceback but, well, they seemed to be close but not what I am looking for.

jogo
  • 12,469
  • 11
  • 37
  • 42
forkandwait
  • 5,041
  • 7
  • 23
  • 22
  • 2
    Right, recover, browser, and traceback are for debugging, while try/catch systems are for handling errors in production code. – Harlan Oct 22 '09 at 18:15
  • 22
    I love it when question askers use the name of the function they're looking for multiple times in a question ;) – hadley Sep 08 '11 at 00:00
  • I think there is a reason this question has more upvotes than the top answer. Even though [this other question](https://stackoverflow.com/questions/2622777/exception-handling-in-r?noredirect=1&lq=1) is technically off-topic, it is that kind of excellently tight summary of an unfamiliar topic that Stack Overflow is famous for. – Josiah Yoder Jul 24 '20 at 14:45

5 Answers5

142

See help(tryCatch):

Conditions are signaled by 'signalCondition'. In addition, the
'stop' and 'warning' functions have been modified to also accept
condition arguments.

and later under 'See Also':

'stop' and 'warning' signal conditions, and 'try' is essentially a simplified version of 'tryCatch'.

so you probably want stop.

Roman Luštrik
  • 69,533
  • 24
  • 154
  • 197
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725
  • 33
    That works perfectly. R is so weird, through no fault of their own -- it was designed long before we ironed out good interpreted language design. – forkandwait Oct 22 '09 at 16:24
  • 7
    According to the authors, it was heavily influenced by Scheme, which is both old and good. R is 'lispy' but with funky data structures. The "interesting" parts in R is probably related to that a lot of conventions differs from other languages, notably the C-language family that it is syntactically close too. I would guess because the language was evolved by a bunch of statisticians that needed a good tool, rather than developers needing a good tool. Just the fact that the 'dot' is just a character took a long time to take in. – KarlP Mar 28 '16 at 21:23
  • 8
    Some basic examples here would be great, not only have citations. Here http://stackoverflow.com/a/23917007/54964 – Léo Léopold Hertz 준영 Oct 30 '16 at 10:51
  • 1
    I came to this question when searching how to rethrow an error in R with a saner error message, but keeping the trace intact (as in, you execute `traceback()` after the error to see what went wrong). Using `stop` in `error` argument of `tryCatch` will mess up the trace. However, the `finally` argument will allow throwing an additional message and keep the trace useful. Not exactly on-topic, but, I feel, important enough to warrant a few minuses and a threat of moderation kicking this comment out of the window. :-) – Mali Remorker Jul 27 '20 at 09:06
63

Simple example:

f <- function(a, b){ 

    if (a == 0){ 
            stop("error message")
    }
 }
8

Beyond the base functions that Dirk mentions:

The R.oo package has additional exception handling functionality, including a throw() function which is very useful. You can catch exceptions with the usual try or trycatch functions:

> try(throw("Division by zero.")); print("It's ok!");
Error: [2009-10-22 10:24:07] Exception: Division by zero.
[1] "It's ok!"

You can read more about it here: http://www1.maths.lth.se/help/R/R.oo/

Shane
  • 98,550
  • 35
  • 224
  • 217
  • 8
    Hehe. R isn't funky enough without OO? Sorry to be flip, and definitely thanks for the interesting answer, but I will go with plain old stop() above. – forkandwait Oct 26 '09 at 20:52
  • 2
    There's even more OO now. :) – Iterator Nov 01 '11 at 20:32
  • 3
    @ws. What's so funky about R? `plot` plots a function, `try` `stop` `warn` all work as you'd expect, and almost everything I want to do is a one-liner. – isomorphismes Nov 11 '11 at 12:07
  • 4
    Often "power of one-liners" isn't a good metric for a language. For many of us readable, understandable code trumps fewer lines. Indeed, much is unintelligible to me because I'm a beginner, and I try to calibrate expectations accordingly. But other languages make it fairly intuitive to go from 0 to getting stuff done. R also seems to have developed a culture of clever, difficult to read one-liners. I would argue for a culture of maximally English-like code, which could often also be one-liners, like Ruby. – Philip Jun 13 '15 at 00:44
7

Actually the function stopifnot is very convenient to implement sanity checks in your code. It takes in several logical expressions and returns an error if any of them evaluates to false.

Example: To check if column 'c' exists in the dataframe 'df':

df <- data.frame(a = numeric(), b = numeric())
stopifnot(!is.null(df$c))

This will throw the following error:

Error: !is.null(df$c) is not TRUE
Chris
  • 445
  • 6
  • 11
  • If you want to change the error message from the default one produced by `stopifnot`, you can wrap it with `tryCatch` as in: ```tryCatch(error = function(cnd) "your message here", stopifnot(your_condition)``` – ESELIA Sep 09 '21 at 13:47
1

You can check if the column exists and do whatever your want.
Suppose a data.frame named df1 and checking if column col1 exists:

if(! any(grepl('^col1$',colnames(df1)))) stop("nonexistent column")

or

if(! any(grepl('^col1$',colnames(df1)))) return(-1)

For instance

xm1
  • 1,663
  • 1
  • 17
  • 28