forgive me if I missed the right way to do this here, but I can't seem to make progress. Skipping error in for-loop helped a lot, as did some of the other answers related to tryCatch, but I'm still struggling. using tryCatch() in R to assign error values in loop didn't work for me, or I'm missing something.
I am running a for loop with tryCatch, but if I get an error, I would like to record it as a row in the resulting matrix. I can't seem to get the error function output up one level to the loop to be recorded. Here is a simple version of what I'm trying:
collectem <- function(eList){
tmpList <- NULL
for (e in eList){
tryCatch({
tmpVar <- c("foo", e)
if (e==3) stop("BLAH!")
}, error=function(d){c("No",d) -> tmpVar})
tmpList <- rbind(tmpList, tmpVar)
}
return(tmpList)
}
Call:
x <- collectem(1:10)
Which results in:
> x
[,1] [,2]
tmpVar "foo" "1"
tmpVar "foo" "2"
tmpVar "foo" "3"
tmpVar "foo" "4"
tmpVar "foo" "5"
tmpVar "foo" "6"
tmpVar "foo" "7"
tmpVar "foo" "8"
tmpVar "foo" "9"
tmpVar "foo" "10"
But I'm looking for this:
x
[,1] [,2]
tmpVar "foo" "1"
tmpVar "foo" "2"
tmpVar "No" "BLAH!"
tmpVar "foo" "4"
tmpVar "foo" "5"
tmpVar "foo" "6"
tmpVar "foo" "7"
tmpVar "foo" "8"
tmpVar "foo" "9"
tmpVar "foo" "10"
Thanks!!
You may use the pattern of returning whatever tuple you want from the error and/or warning handler functions of tryCatch
:
collectem <- function(eList) {
tmpList <- NULL
for (e in eList) {
tmpVar <- tryCatch(
{
if (e == 3) stop("**BLAH!**")
c("foo", e)
},
error = function(d) {
return(c("No", sub(".*\\*\\*(.*?)\\*\\*.*", "\\1", d)))
}
)
print(tmpVar)
tmpList <- rbind(tmpList, tmpVar)
}
return(tmpList)
}
eList <- c(1:10)
collectem(eList)
[,1] [,2]
tmpVar "foo" "1"
tmpVar "foo" "2"
tmpVar "No" "BLAH!"
tmpVar "foo" "4"
tmpVar "foo" "5"
tmpVar "foo" "6"
tmpVar "foo" "7"
tmpVar "foo" "8"
tmpVar "foo" "9"
tmpVar "foo" "10"
What I learned here is that tryCatch
indeed returns a value when calling it. However, the value returned for the try
block is just the implicit statement which executes. Calling return
from the try
block will cause the entire function to return, which is not what we want. On the other hand, we can (and arguably should) use an explicit return
for the error
and warning
blocks. In this case, the return
just returns from the call to tryCatch
, and not from the entire enclosing function.
Here a pattern using try
collectem <- function(eList){
#browser()
tmpList <- NULL
for (e in eList){
flag <- try(if (e==3) stop("BLAH!"),silent = TRUE)
if(!is.null(flag) && class(flag)=="try-error"){
#tmpVar <- c("No","BLAH!")
d <- gsub('.*\\: (.*)\n','\\1',flag)
tmpVar <- c("No",d)
} else {tmpVar <- c("foo", e)}
tmpList <- rbind(tmpList, tmpVar)
}
return(tmpList)
}
When we hit e=3 flag
will be
flag
[1] "Error in try(if (e == 3) stop(\"BLAH!\"), silent = TRUE) : BLAH!\n"
attr(,"class")
[1] "try-error"
attr(,"condition")
<simpleError in doTryCatch(return(expr), name, parentenv, handler): BLAH!>
So we can extract anything after :
and before \\n
as the Error message using gsub
and grouping. Here what we will get
gsub('.*\\: (.*)\n','\\1',flag)
[1] "BLAH!"
attr(,"class")
[1] "try-error"
attr(,"condition")
<simpleError in doTryCatch(return(expr), name, parentenv, handler): BLAH!>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.