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(){})
Related
warning: I'm pretty new to R, sniny and co ==> I don't realize whether this question is interesting.
update : It turns out that it is a shiny question and it seems to be a frequent problem, that is not obvious. Please read all answers, they don't address the same cases.
I have a Data base in DB. Is there a difference between DBtoto <- reactive({DB()}) and DBtoto <- reactive({DB}) ? If so, what is it ?
In fact I don't see what BD() (with parentheses) means.
Yes, there's a difference. DB() is a call to the function named DB. DB is the function itself. If it's not a function, then DB() doesn't make sense, and will trigger a run-time error (unless there's another object somewhere which is a function).
reactive() is a Shiny function, that says the value of its argument may change over time. Usually it would make more sense to think the value of the function call would change, but it's (remotely) possible that the function itself could change.
I also found the first answer of What is “object of type ‘closure’ is not subsettable” error in Shiny? addresses this question. To summary, everything created with 'reactive()' in shiny must be referred as a function.
In my example, if DB was reactive (for instance DB <- reactive(read_DataBase())), then DB() must be referred with parenthesis. For instance, to get the attribute 'x', you must write BD()$x. In my 'DBtoto' example above the first expression holds in the case DB is itself reactive.
I'm working on a non-linear optimization, with the constrOptim.nl from the alabama package. However, my problem is more related to passing arguments (and the dot-dot-dot (ellipis/"...") and maybe do.call)- so I give first a general example and later refer to the constrOptim.nl function.
Suppose, I have the following functions - from which I only can edit the second and third but not the first.
first<-function (abc, second, third, ...){
second(abc,...)
third(abc,...)
}
second<- function(abc, ttt='nothing special'){
print(abc)
print(ttt)
}
third<- function(abc, zzz="default"){
print(abc)
print(zzz)
}
The output I want is the same I would get when I just run
second("test", ttt='something special')
third("test", zzz="non-default")
This is
"test"
"something special"
"test"
"non-default"
However, the code below doesn't work to do this.
first("test",second=second, third=third, ttt='something special',zzz="non-default")
How can I change the call or the second and third function to make it work?
http://www.r-bloggers.com/r-three-dots-ellipsis/
here I found some advice that do.call could help me but at the moment I'm not capable of understanding how it should work.
I cannot change the first function since this is the constrOptim.nl in my particular problem - and it is designed to be capable of passing more arguments to different functions. However, I can change the second and third function - as they are the restrictions and the function that I want to minimize. Obviously I can also change the call of the function.
So to be more particular, here is my specific problem:
I perform a maximum likelihood estimation with non-linear restrictions:
minimize <- function(Param,VARresiduals){
#Blahblah
for (index in 1:nrow(VARreisduals)){
#Likelihood Blahbla
}
return(LogL)
}
heq<-function(Param,W){
B<-Param[1:16]
restriction[1]<-Lrestriction%*%(diag(4)%x%(solve(W))%*%as.vector(B))
restriction[2:6]<-#BlablaMoreRestrictions
return(restriction)
}
Now I call the constrOptim.nl...
constrOptim.nl(par=rnorm(20), fn=minimize,hin=NULL heq=heq,VARresiduals,W)
...but get the same error, as I receive when I call the first function above - something like: "Error in second(abc, ...) : unused argument (zzz = "non-default")".
How can I change minimize and heq or the call? :) Thanks in Advance
Update after the post got marked as a duplicate:
The answer to the related post changes the first function in my example - as it implements a do.call there, that calls the other functions. However, I cannot change the first function in my example as I want to keep the constrOptim.nl working a variety of different functions. Is there another way?
The solution I came up with is not very elegant but it works.
second_2<- function(abc, extras){
a<-extras[[1]]
print(abc)
print(a)
}
third_2<- function(abc, extras){
a<-extras[[2]]
print(abc)
print(a)
}
extras<-list()
extras[[1]]<-'something special'
extras[[2]]<-"non-default"
extras
first("test",second=second_2, third=third_2, extras)
surprisingly also the following code works, but with a slightly different outcome
first("test",second=second, third=third, extras)
after all, setting default values is now a little clumsy but not infeasible.
Sometimes R throws me errors such as
Error in if (ncol(x) != 2) { : argument is of length zero
with no additional information, when I've written no such code. Is there a general way for finding which function in which package causes an error?
Since most packages come compressed, it isn't trivial to grep /usr/lib/R/library.
You can use traceback() to locate where the last error occurred. Usually it will point you to a call you make in your function. Then I typically put browser() at that point, run the function again and see what is going wrong.
For example, here are two functions:
f2 <- function(x)
{
if (x==1) "foo"
}
f <- function(x)
{
f2(x)
}
Note that f2() assumes an argument of length 1. We can misuse f:
> f(NULL)
Error in if (x == 1) "foo" : argument is of length zero
Now we can use traceback() to locate what went wrong:
> traceback()
2: f2(x) at #3
1: f(NULL)
The number means how deep we are in the nested functions. So we see that f calls f2 and that gives an error at line 3. Pretty clear. We could reassign f with browser placed just before the f2 call now to check it's input. browser() simply allows you to stop executing a function and look around in its environment. Similar to debug and debugonce except that you don't have to execute every line up until the point you know something goes wrong.
Just to add to what #SachaEpskamp has already suggested, setting options(error=recover) and options(show.error.locations=TRUE) can be extremely helpful when debugging unfamiliar code. The first causes R to launch a debugging session on error, giving you the option to invoke the browser at any point in the call stack up to that error. The second option will tell R to include the source line number in the error.
I have problem in using if else inside function, my code is like this:
ConvertWgtZooLS <- function(WgtZoo, LSWay, Pos){
If(LSWay == 0){
NewWgtZoo <- WgtZoo
}else{
BackPos <- BackMatrix(Pos,1)
NewWgtZoo<- Ifelse((Sign(WgtZoo) * Sign(BackPos) * LSWay)>=0, WgtZoo, 0)
}
return(NewWgtZoo)
}
However, when I run that in R, error message appears as:
"Error: unexpected '{' in:
"ConvertWgtZooLS <- function(WgtZoo, LSWay, Pos){
If(LSWay == 0){"
How can I resolve this? What is the syntax problem there? I checked many websites and seems the above if else syntax is correct.
Thanks a lot!
The error in your code is that you have used If instead of if, and R is case-sensitive. Thus, it is possible to have another function named If that does something different from if, and, as #danielkullmann points out, that function is exactly what R is looking for.
The error messages that R produces are not always the most helpful, but in this case, it does point you very close to the problem area. It shows you where it got "confused" but it's up to you to figure out why!
After you've fixed that first problem, you'll find another one (for the same reason) on line 6, where you have written Ifelse instead of ifelse.
One last point: R is pretty whitespace friendly, so it is good practice to leave some space in your code to help improve legibility, particularly with if and else statements. Here's why:
I find if (LSWay == 0) { easier to read than if(LSWay == 0){
When using an actual function, like sum(x), you do not usually add a space, making it easier to spot these conditional statements in large blocks of code.
The Google R Style Guide is an interesting read in this regard.
I have written an R script which includes a loop that retrieves external (web) data. The format of the data are most of the time the same, however sometimes the format changes in an unpredictable way and my loop is crashing (stops running).
Is there a way to continue code execution regardless the error? I am looking for something similar to "On error Resume Next" from VBA.
Thank you in advance.
Use try or tryCatch.
for(i in something)
{
res <- try(expression_to_get_data)
if(inherits(res, "try-error"))
{
#error handling code, maybe just skip this iteration using
next
}
#rest of iteration for case of no error
}
The modern way to do this uses purrr::possibly.
First, write a function that gets your data, get_data().
Then modify the function to return a default value in the case of an error.
get_data2 <- possibly(get_data, otherwise = NA)
Now call the modified function in the loop.
for(i in something) {
res <- get_data2(i)
}
You can use try:
# a has not been defined
for(i in 1:3)
{
if(i==2) try(print(a),silent=TRUE)
else print(i)
}
How about these solutions on this related question :
Is there a way to `source()` and continue after an error?
Either parse(file = "script.R") followed by a loop'd try(eval()) on each expression in the result.
Or the evaluate package.
If all you need to do is a small piece of clean up, then on.exit() may be the simplest option. It will execute the expression "when the current function exits (either naturally or as the result of an error)" (documentation here).
For example, the following will delete my_large_dataframe regardless of whether output_to_save gets created.
on.exit(rm("my_large_dataframe"))
my_large_dataframe = function_that_does_not_error()
output_to_save = function_that_does_error(my_large_dataframe)