How to catch an error/exception in R? [duplicate] - r

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Exception handling in R
Does anyone have idea on how to catch an error or an exception in R?

Like Joshua said: use tryCatch. Include an error argument, which should be a function accepting one parameter (the error, typically called e).
tryCatch(
stop("you threw an error"),
error = function(e)
{
print(e$message) # or whatever error handling code you want
}
)

It really depends on what you mean by "catch". Look at tryCatch and withCallingHandlers.

Have you looked into stop?
This will allow you to catch exceptions that you define.

Related

if...else (with exists()) in R function returning "unused argument" error

I am trying to learn to make different variations of basic functions on my own. However, despite my test statement defining "x" within if, the returning results did not execute the else correctly. I googled various tutorial sites such as DataCamp and Khan. The syntax, from what I can see, is correct. Was hoping someone out there may see differently and could explain why?
p <- function() {
if (!exists("x")) {
x <- "there is no number"
} else {
x <- "what do you want to add?"
}
x
}
Below is the screen shot of my console:
function with returning Error "Error in p(4) : unused argument (4)"
Various attempts:
I tried removing the "x" framing in my exists() but when I try to run p() , I get a Error in exists(x) : object 'x' not found and with p(4), it returned a Error in p(4) : unused argument (4)
I adjusted p <- function(x) as well, but then received for p() an Error in exists(x) : argument "x" is missing, with no default With p(4), an Error in exists(x) : invalid first argument
Removing the ! negation in exists() yielded a p() return of "what do you want to add?" and with p(4) an Error in p(4) : unused argument (4) again.
Should I not use exists() within the test statement after all? Did I make this unnecessarily complicated on myself?
Anna
So you definitely need to have an argument in your function. Plus I don't think you have to do all that assigning within the if/else statements. I think this gets what you're looking for, but not sure:
p <- function(some_object) {
if (!exists(some_object)) {
"there is no number"
} else
"what do you want to add?"
}
x <- 1 + 1
p("x")
It looks like a collaboration of both Bill and Ben's answers worked!
I gave up on using exists() and tabled it to master on another day. Meantime, with both codes merged, I got this:
p <- function(x) {
if (missing(x)) {
"there is no number"
} else
"what do you want to add?"
}
missing() was definitely a far friendlier function to use. I achieved the results I aimed for. p() returned a "there is no number" and p(4) returned a "what do you want to add?" At last!
Thank you both for helping me tackling what I thought was going to be a simple function. Clearly not! I'm going to tackle missing() and exists() ad nauseum and master this.
Much gratitude for the advice! I'm going to post the answer here in case another encounters the same snag.
Gratefully Yours,
Anna

Making a throwable response to exception handling in R

I've turned my hand to R after many years of Java/C++. I am struggling to protect my operational flow using exception handling. Perhaps, I am looking at this with too much of a Java hat on.
Essentially, I am looking for a throw operator at the start of a function if a partiular argument to that function is incorrectly typed. An example for the structure (not functioning code) I am looking for:
myFunction <- function(someListArgument) {
if(class(someListArgument) != "List") {
throw(paste("Argument not a list: ", class(someListArgument)))
}
}
tryCatch({myFunction(c("whoops!"))},
error = function(cond) {},
....
)
I would really like the compartmentalisation of code as I am writing an R->MySQL DBMS API and I would like to keep well controlled and informative error reporting if incorrect datatypes are provided.

How to target exception-handling to specific exceptions?

Does R provide any support for targetting exception handling to only specific exceptions?
In Python, for example, one can narrow down exception-handling to specific exception types; e.g.:
try:
return frobozz[i]
except IndexError:
return DEFAULT
In this example, the exception handling will kick in only if i is an integer such that i >= len(frobozz) or i < -len(frobozz), but will not catch the exception resulting from, e.g., the case where i is the string "0" (which would be a TypeError, rather than an IndexError).
Wellllll...yes and no, and mostly no.
Every Python exception is wrapped in a particular error class which derives from Error, and Python modules are supposed to raise the "right" kinds of errors. For instance, an index out of range error should throw IndexError. The base language knows about these errors and so you can catch the appropriate error type in your except... clause.
R doesn't do that. Errors are untyped; there's no essential difference between an index out of bounds error and any other error.
That said, you can cheat under certain, very limited, circumstances.
> y <- tryCatch(x[[2]], error = function(e) e)
> y
<simpleError in x[[2]]: subscript out of bounds>
> y$message
[1] "subscript out of bounds"
The key here is the use of the tryCatch function and the error clause. The error clause in a tryCatch is a function of one variable which can perform arbitrary operations on e, which is an object of type 'simpleError' and contains an item named "message". You can parse message and handle interesting cases separately
> y <- tryCatch(x[[2]],
error = function(e) {
if ('subscript out of bounds' == e$message) return(NA) else stop(e))
})
> y
[1] NA
This only works if you can actually detect the error string you want to look for, and that isn't guaranteed. (Then again, it also isn't guaranteed in Python, so things aren't really much different from one another.)
Final question, though: why in Heaven's name are you doing this? What are you really trying to do?

Define a S3 function using UseMethod [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am new to the programming R. I defined a function called liw.mstreeClass and I defined as below, but when I run the program I am keep getting the following errors:
# define method: lcosts(generic dispatch)
liw.mstreeClass <- function(nb, data, method, p) UseMethod("nbcosts"){
Error: unexpected '{' in "liw.mstreeClass <- function(nb, data, method, p) UseMethod("nbcosts"){"
if(method=="penrose") { liw <- mat2listw(penroseDis.mstreeClass((scale(data))))
return(liw)}
Error: object 'method' not found
}
Error: unexpected '}' in " }"
# liw.mstreeClass <- function(nb, data, method, p) UseMethod("nbcosts"){
# Error: unexpected '{' in "liw.mstreeClass <- function(nb, data, method, p)
Well, to start with, you've got a syntax error here. You can group several expressions with curly brackets but not start curly brackets after an expression.
Compare...
mean(1)
... with ...
mean(1){
# error!!
Secondly, in S3 you define methods for already existing generic functions. So if you have a function "liw" that could be applied to several classes, then liw.mstreeClass would define the way to do the "liw" for a class called "mstreeClass". So you first have to define liw as a generic function:
liw<-function(x,...){
UseMethod("liw")
}
Notice that you must have "liw" as an argument to UseMethod, not some random crap. (Take a look at the manual to understand why.) You would rarely have a lot of code besides the call to UseMethod in a generic function's body.
And having done that, you can define an mstreeClass method for liw. For example,
liw.mstreeClass<-function(x, y, z){
paste("liw equals ", x + y + z)
}
Note that as method dispatch in S3 is based on the first argument, your x must have class "mstreeClass" - only in that case, liw(x) will be directed to liw.mstreeClass(x). And I think if your generic has x as the first argument then the first argument of all methods must be called x too.
UseMethod("nbcosts"){"
if(method=="penrose") { liw <- mat2listw(penroseDis.mstreeClass((scale(data))))
return(liw)}
Error: object 'method' not found
}
Error: unexpected '}' in " }"
Umm.. sorry, these lines don't make a lot of sense. See above or the manuals on how to use UseMethod.

Exception handling in R [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Does anyone have examples/tutorials of exception handling in R? The official documentation is very terse.
Basically you want to use the tryCatch() function. Look at help("tryCatch") for more details.
Here's a trivial example (keep in mind that you can do whatever you want with an error):
vari <- 1
tryCatch(print("passes"), error = function(e) print(vari), finally=print("finished"))
tryCatch(stop("fails"), error = function(e) print(vari), finally=print("finished"))
Have a look at these related questions:
Equivalent of "throw" in R
catching an error and then branching logic
https://stackoverflow.com/search?q=[r]+trycatch
Besides Shane's answer pointing you to other StackOverflow discussions, you could try a code search feature. This original answer pointed to Google's Code Search has since been discontinued, but you can try
Github search as e.g. in this query for tryCatch in language=R;
Ohloh/Blackduck Code search eg this query for tryCatch in R files
the Debian code search engine on top of the whole Debian archive
Just for the record, there is also try but tryCatch may be preferable. I tried a quick count at Google Code Search but try gets too many false positives for the verb itself -- yet it seems tryCatch is more widely used.
This result from a related google search helped me: http://biocodenv.com/wordpress/?p=15.
for(i in 1:16){
result <- try(nonlinear_modeling(i));
if(class(result) == "try-error") next;
}
The function trycatch() is fairly straight forward, and there are plenty of good tutorials on that. A excellent explanation of error handling in R can be found in Hadley Wickham's book Advanced-R, and what follows is a very basic intro to withCallingHandlers() and withRestarts() in as few words as possible:
Lets say a low level programmer writes a function to calculate the absolute
value. He isn't sure how to calculate it, but knows how to construct an
error and
diligently conveys his naiveté:
low_level_ABS <- function(x){
if(x<0){
#construct an error
negative_value_error <- structure(
# with class `negative_value`
class = c("negative_value","error", "condition"),
list(message = "Not Sure what to with a negative value",
call = sys.call(),
# and include the offending parameter in the error object
x=x))
# raise the error
stop(negative_value_error)
}
cat("Returning from low_level_ABS()\n")
return(x)
}
A mid-level programmer also writes a function to calculate the absolute value, making use of the woefully incomplete low_level_ABS function. He knows that the low level code throws a negative_value
error when the value of x is negative and suggests an solution to the problem, by
establishing a restart which allows users of mid_level_ABS to control the
way in which mid_level_ABS recovers (or doesn't) from a negative_value error.
mid_level_ABS <- function(y){
abs_y <- withRestarts(low_level_ABS(y),
# establish a restart called 'negative_value'
# which returns the negative of it's argument
negative_value_restart=function(z){-z})
cat("Returning from mid_level_ABS()\n")
return(abs_y)
}
Finally, a high level programmer uses the mid_level_ABS function to calculate
the absolute value, and establishes a condition handler which tells the
mid_level_ABS to recover from a negative_value error by using the restart
handler.
high_level_ABS <- function(z){
abs_z <- withCallingHandlers(
# call this function
mid_level_ABS(z) ,
# and if an `error` occurres
error = function(err){
# and the `error` is a `negative_value` error
if(inherits(err,"negative_value")){
# invoke the restart called 'negative_value_restart'
invokeRestart('negative_value_restart',
# and invoke it with this parameter
err$x)
}else{
# otherwise re-raise the error
stop(err)
}
})
cat("Returning from high_level_ABS()\n")
return(abs_z)
}
The point of all this is that by using withRestarts() and withCallingHandlers(), the function
high_level_ABS was able to tell mid_level_ABS how to recover from errors
raised by low_level_ABS error without stopping the execution of
mid_level_ABS, which is something you can't do with tryCatch():
> high_level_ABS(3)
Returning from low_level_ABS()
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
> high_level_ABS(-3)
Returning from mid_level_ABS()
Returning from high_level_ABS()
[1] 3
In practice, low_level_ABS represents a function that mid_level_ABS calls a
lot (maybe even millions of times), for which the correct method of error
handling may vary by situation, and choice of how to handle specific errors is
left to higher level functions (high_level_ABS).
The restart function is very important in R inherited from Lisp. It is useful if you want to call some function in the loop body and you just want the program to continue if the function call collapses. Try this code:
for (i in 1:20) withRestarts(tryCatch(
if((a <- runif(1))>0.5) print(a) else stop(a),
finally = print("loop body finished!")),
abort = function(){})

Resources