try or tryCatch with boot R - r

I'm using boot to bootstrap an optimization function in order to estimate standard errors. Unfortunately, on rare occasions the optimization function returns an error which stops the boot function. The error's are not critical to estimation and i would like to skip that iteration and continue to the next.
I have tried to find a solution with try and tryCatch but haven't been able to use either correctly. When wrapping the optimization function within statistici have managed to skip the errors. However, this results in the number of estimations within boot being less than the initial number of iterations and returning an error.
A basic example of my code is below
Any help is appreciated,
Thanks
bootfun = function(bootdata, i, d, C1) {
C1 = cov (bootdata[i])
ans = constrOptim(...) #This function returns an error
return(ans$par [d])
}
bootres = boot(bootdata, statistic = bootfun, 500)
EDIT: I have managed to find an acceptable solution to my problem. However, if a function gives errors often this may not be acceptable as each error replaces a bootstrap replication with NA.
bootfun = function(bootdata, i, d, C1) {
C1 = cov(bootresid[i])
tryCatch({
ans = constrOptim(...)
return(ans$par[1:18] [d]) },
error=function(err) {rep(NA,18)} )
}

This is not an answer with your specific code, but a more general demonstration of tryCatch for the situation you describe. If you want to simply remove entries that cause errors, have the function return nothing on error and then remove NULL values from the results:
testfun <- function(i) {
tryCatch({
d <- rbinom(1,1,.3) # generate an error 30% of the time
if(d==1)
error("test stop")
else
return(1:10) # return your actual values
},
error = function(err) {return()} # return NULL on error
)
}
x <- sapply(1:20, FUN=testfun) # run demo 20 times
x <- x[-(which(sapply(x,is.null),arr.ind=TRUE))]
# when errors happen, x is shorter than 20
The final line removes NULL entries from the list (based on this: https://stackoverflow.com/a/3336726/2338862).

Related

R - how to locate fail in parallel loop (pblapply)

I'm working in R, and using the function pblapply() to make parallel processing. I love this function because it shows a progress bar (very useful for estimate very long execution).
Let's say I have a huge dataset, that I split in 500 smaller subdatasets. I will share them through different threads for parallel processing. But if one subdataset generate an error, the whole pblapply() loop failed, and I don't know which of the 500 small subdatasets generated the error. I have to check them one by one. When I do such loop with the R base for() function, I can add print(i) that will help me locate the error.
Q) Can I do something similar with pblapply(), display a value to tell me which subdataset is currently executing (even if several are displayed at the same time, as several subdatasets are manipulated at the same time by the different threads). It will save my time.
# The example below generate an error, we can guess where because it's very simple.
# With the **pblapply()**, I can't know which part generate the error,
# whereas with the loop, testing one by one, I can find it, but it could be very long with more complex operation.
library(parallel)
library(pbapply)
dataset <- list(1,1,1,'1',1,1,1,1,1,1)
myfunction <- function(x){
print(x)
5 / dataset[[x]]
}
cl <- makeCluster(2)
clusterExport(cl = cl, varlist = c('dataset', 'myfunction'), envir = environment())
result <- pblapply(
cl = cl,
X = 1:length(dataset),
FUN = function(i){ myfunction(i) }
)
stopCluster()
# Error in checkForRemotErrors(vaL) :
# one node produced errors: non-numeric argument to binary operator
for(i in 1:length(dataset)){ myfunction(i) }
# [1] 1
# [1] 2
# [1] 3
# [1] 4
# Error in 5/dataset[[x]] : non-numeric argument to binary operator
One simple way would be to use tryCatch on the part that can cause an error, e.g.:
myfunction <- function(x){
print(x)
tryCatch( 5 / dataset[[x]] , error=function(e) NULL)
}
This way, you get NULL (or whatever you choose) for cases with an error, and can deal with that later in your code.
which(lengths(result)==0)
would tell you which list elements had an error.
You could then examine what happened exactly and implement code that properly identifies and deals with (or prevents) problematic input.

Created a for loop in R to (ggplot) multiple columns with one corresponding column (x), how to stop when it sees a 0 and move on to the next column?

I created a a time v. concentration model in R for ggplot, the first set of data points did not have 0's so I thought'd it be ok. I then created one sheet with my Elapsed Days (x) and Concentrations (y) and created a for loop. The for loop comes up with an error because there are values inside some columns that have 0s. Id like for it to stop plotting when it hits a 0 in the for loop and move on to the next set of data points
Any help would be appreciated!
for(i in 1:24){
i = i + 2
x <- alldata1$Elapsed.Days
y <- as.matrix(alldata1[i])
df <- data.frame(x, y)
myFunction(x, y, df)
}
Error in lm.fit(x, y, offset = offset, singular.ok = singular.ok, ...) :
NA/NaN/Inf in 'y'
since there are zero values, but Im a bit unsure.
You have to add an if condition for where it finds 0 and move to next
ex:
for(n in c(1,2,4,0,6,0,8,0)) {
if(n==0) next # skip wherever it gets 0 to next iteration
print(n)
}
Output
1
2
4
6
8
Geekzeus' answer is perfectly fine, I would just like to bring to your attention that there are also slightly more formal ways of dealing with errors and warnings. If you would have a look at the code below:
output <- tryCatch({myFunction(x, y, df)},
warning = function(cond) {NULL},
error = function(cond) {NULL})
if (is.null(output)) {
next()
} else {
return(output)
}
What will happen here is that R tries to evaluate myFunction(x, y, df), when it encounters an error it will provide the error condition to the function(cond){NULL}, which will do nothing with cond but instead assigns NULL to output. Subsequently the code will continue.
Here is an example to play around with:
foo <- function(i) {if (i == 3) stop("Error")}
for(i in 1:5) {
print(i)
out <- tryCatch({foo(i)}, error = function(cond){NULL})
if (is.null(out)) next()
}
The above will print all 5 numbers, even though it encountered an error when i == 3.
Its a good way to specify what should happen when your code encounters an error, but is not a substitute for debugging your code to prevent errors in the first place.

How to check if a try error happened (possibly using testthat) when it is not desired to return the error value?

I want the function to produce an error in a try block if a condition is faced, and output one of the inputs without any change in the case of this error. Please note that I do not wish to create a list output or anything as I need to have consistent output. My question is how can I check that the error does occur for some values using testthat? For example, for the below function:
myfunc = function(x,y){
try({
if(x<0)
stop("Negative X")
y = y+x
})
return(y)
}
I want to test and ensure error does occur for x=-1:
I have tried:
library(testthat)
expect_error(myfunc(-1,2))
But I get:
Error in try({ : Negative X
Error: `myfunc(-1, 2)` did not throw an error.

How to substitute function errors with NA output in R?

Is there an elegant way to force the execution of a function and return a NA consistent with its normal output type if any error is encountered?
For example, to have lm batch process data in R, and pick just a single estimate, avoiding stop on errors using tryCatch:
lmCoeff <- function(beta, ...) {
tryCatch(ifelse(is.numeric(a <- lm(...)$coefficient[beta]), a, as.numeric(NA)),
error = function(e) {
return(as.numeric(NA))
} )
}
# test with 3 cases
(good <- lmCoeff(beta="cyl", mpg ~ cyl, mtcars))
(bad <- lmCoeff(beta="bad", mpg ~ cyl, mtcars))
(ugly <- lmCoeff(beta="cyl", ugly))
# output should always be of the same type:
str(good)
str(bad)
str(ugly)
The question is whether there a more elegant and less idiosyncratic way to do this.
As stated, tryCatch can be used to catch all errors and output an NA of numeric type if any error is found. In the case where you know what errors are to be expected, then you could directly check for them using a if statement.
For example, I can think of two possible errors: user enters invalid data object, or the formula is not valid. So a neater (and imo more responsible solution) would be:
lmCoeff <- function(beta, ...) {
if(<data does not exist>){
a <- NA
warning("data not found")
} else if (<formula invalid>){
a <- NA
warning("formula invalid")
} else {
lapply(..., function(x) print(str(x))))
a <- lm(...)$coefficient[beta]
}
as.numeric(a)
}
}
Of course in practice if it is too complicated to write conditions to check that the data does not exist, or the formula is invalid, then for simplicity you can use tryCatch.

how to "test" a function and repeat it if is not executed? in R

I have to run a function over a list of elements (in R). This function estimates the parameters of a model by maximum likelihood. To run the function, I need to give a set of initial parameter values, which then will be optimised by the algorithm.
Then here is my problem:
I want to randomise the initial parameter values every time I execute the function over each element of my list. I do it with the function runif(). HOWEVER, not all combinations of the initial parameters seem to work (it gives an error). In this case, I would like to execute again and again the function over that element of the list, trying different starting values, until I get the combination of initial parameter values that make the function work. Only then the loop can continue to the next element of the list.
Could you please give me some ideas of how can I tackle this problem?
thank very much in advance.
Tina.
Wrap the call that generates the error in try or tryCatch.
In pseudo code:
out <- vector(mode = "list", length = 10)
for (i in seq_along(out)) {
res <- try(...function call here...)
## res contains the actual error msg in object of class "try-error"
while(inherits(res, "try-error")) {
res <- try(...function call here...)
}
out[[i]] <- res
}
or using repeat
out <- vector(mode = "list", length = 10)
for (i in seq_along(out)) {
repreat {
res <- try(...function call here...)
if(!inherits(res, "try-error"))
break
}
out[[i]] <- res
}
You'll need to arrange out to be the required length or type of object to hold the results, as you see fit, and whether you need to record if the function failed (as the example above does with NA) or not will depend on what you are doing. Without an explicit example, that is the best you'll get.
Read ?try and also look at ?tryCatch, the latter is a more general mechanism for trapping errors. try itself is implemented using tryCatch for example...

Resources