tryCatch() does not suppress the error messages - r

I would like to create a function that does not print any error messages.
Let's say I have the following data:
library(fitdistrplus)
vec <- rnorm(100)
Then the following gives an error message:
fitdist(vec, "exp")
#> Error in computing default starting values.
#> Error in manageparam(start.arg = start, fix.arg = fix.arg, obs = data, : Error in start.arg.default(obs, distname) :
#> values must be positive to fit an exponential distribution
Now I would like to create a function that does return NULL. I tried this with tryCatch(). The problem is that fit_fn() still returns the error 'Error in computing default starting values':
fit_fn <- function(x){
tryCatch(fitdist(x, "exp"), error = function(e){ NULL })
}
fit_fn(vec)
#> Error in computing default starting values.
#> NULL
What is the way to do this? Only NULL should be printed here:
fit_fn(vec)
#> NULL
Created on 2021-11-02 by the reprex package (v2.0.1)

Desipte the fact that it says it's an error, the message that's being displayed is done not via the error mechanism, but the output is being printed directly to the console because it's already in it's own error handler. If you want to suppress that message, you'll need to capture the output of the function. Then you can ignore that output.
You can do that with
fit_fn <- function(x){
capture.output(result <- tryCatch(fitdist(x, "exp"),
error = function(e){ NULL }))
result
}
fit_fn(vec)
# NULL

Related

Error in eval(expr, p): object 'X' not found; predict (BayesARIMAX)

I am trying to use BayesARIMAX to model and predict us gdp (you can find the data here: https://fred.stlouisfed.org/series/GDP).I followed the example (https://cran.r-project.org/web/packages/BayesARIMAX/BayesARIMAX.pdf) to build my model. I didnt have any major issue to build the model(used error handling to overcome Getting chol.default error when using BayesARIMAX in R issue). However could not get the prediction of the model. I tried to look for solution and there is no example of predicting the model that is build using BayesARIMAX. Every time that I run the "predict" I get the following error:
"Error in eval(expr, p) : object 'X' not found"
Here is my code.
library(xts)
library(zoo)
library(tseries)
library(tidyverse)
library(fpp2)
gdp <- read.csv("GDP.csv", head = T)
date.q <- as.Date(gdp[, 1], "%Y-%m-%d")
gdp <- xts(gdp[,2],date.q)
train.row <- 248
number.row <- dim(merge.data)[1]
gdp.train <- gdp[1:train.row]
gdp.test <- gdp[(train.row+1):number.row]
date.test <- date.q[(train.row+1):number.row]
library(BayesARIMAX)
#wrote this function to handle randomly procuded error due to MCMC simulation
test_function <- function(a,b,P=1,Q=1,D=1,error_count = 0)
{
tryCatch(
{
model = BayesARIMAX(Y=a,X = b,p=P,q=Q,d=D)
return(model)
},
error = function(cond)
{
error_count=error_count+1
if (error_count <40)
{
test_function(a,b,P,Q,D,error_count = error_count)
}
else
{
print(paste("Model doesnt converge for ARIMA(",P,D,Q,")"))
print(cond)
}
}
)
}
set.seed(1)
x = rnorm(length(gdp.train),4,1)
bayes_arima_model <- test_function(a = gdp.train,b=x,P = 3,D = 2,Q = 2)
bayes_arima_pred <- xts(predict(bayes_arima_model[[1]],newxreg = x[1:3])$pred,date.test)
and here is the error code
Error in eval(expr, p) : object 'X' not found
Here is how I resolve the issue after reading through the BayesARIMAX code (https://rdrr.io/cran/BayesARIMAX/src/R/BayesianARIMAX.R) . I basically created the variable "X" and passed it to predict function to get the result. You just have to set the length of X variable equal to number of prediction.
here is the solution code for prediction.
X <- c(1:3)
bayes_arima_pred <- xts(predict(bayes_arima_model[[1]],newxreg = X[1:3])$pred,date.test)
which gave me the following results.
bayes_arima_pred
[,1]
2009-01-01 14462.24
2009-04-01 14459.73
2009-07-01 14457.23

How to use Trycatch to skip errors in data downloading in R

I am trying to download data from the USGS website using the dataRetrieval package of R.
For that purpose, I have generated a function called getstreamflow in R that works fine when I ran for example.
siteNumber <- c("094985005","09498501","09489500","09489499","09498502")
Streamflow = getstreamflow(siteNumber)
The output of the function is a list of data frames
I could run the function when there is no issue downloading the data, but for some stations, I got the following error:
Request failed [404]. Retrying in 1.1 seconds...
Request failed [404]. Retrying in 3.3 seconds...
For: https://waterservices.usgs.gov/nwis/site/?siteOutput=Expanded&format=rdb&site=0946666666
To avoid that the function stops when encounters an error, I am trying to use tryCatch as in the following code:
Streamflow = tryCatch(
expr = {
getstreamflow(siteNumber)
},
error = function(e) {
message(paste(siteNumber," there was an error"))
})
I want the function to skip the station and go to the next when encountering an error. Currently, the output I got is the one presented below, that obviously is wrong, because it says that for all the stations there was an error:
094985005 there was an error09498501 there was an error09489500 there was an error09489499 there was an error09498502 there was an error09511300 there was an error09498400 there was an error09498500 there was an error09489700 there was an error09500500 there was an error09489082 there was an error09510200 there was an error09489100 there was an error09490500 there was an error09510180 there was an error09494000 there was an error09490000 there was an error09489086 there was an error09489089 there was an error09489200 there was an error09489078 there was an error09510170 there was an error09493500 there was an error09493000 there was an error09498503 there was an error09497500 there was an error09510000 there was an error09509502 there was an error09509500 there was an error09492400 there was an error09492500 there was an error09497980 there was an error09497850 there was an error09492000 there was an error09497800 there was an error09510150 there was an error09499500 there was an error... <truncated>
What I am doing wrong using the tryCatch?
Answer
You wrote the tryCatch outside of getstreamflow. Hence, if one site fails, then getstreamflow will return an error and nothing else. You should either supply 1 site at a time, or put the tryCatch inside getstreamflow.
Example
x <- 1:5
fun <- function(x) {
for (i in x) if (i == 5) stop("ERROR")
return(x^2)
}
tryCatch(fun(x), error = function(e) paste0("wrong", x))
This returns:
[1] "wrong1" "wrong2" "wrong3" "wrong4" "wrong5"
Multiple arguments
You indicated that you have both siteNumber and datatype to iterate over.
Using Map, we can define a function that takes two inputs:
Map(function(x, y) tryCatch(fun(x, y),
error = function(e) message(paste(x, " there was an error"))),
x = siteNumber,
y = datatype)
Using a for-loop, we can just iterate over them:
Streamflow <- vector(mode = "list", length = length(siteNumber))
for (i in seq_along(siteNumber)) {
Streamflow[[i]] <- tryCatch(getstreamflow(siteNumber[i], datatype), error = function(e) message(paste(x, " there was an error")))
}
Or, as suggested, just modify getstreamflow.

Rpart Error with Anova: `Error in !isord : invalid argument type`

I'm running below code to call rpart function but it keeps giving me error Error in !isord : invalid argument type
# set arguments for rpart function
group.target.metric <- "loan_amount"
group.data.variables <- c(data.config$dict[is_group == TRUE, variable_name_modeling], group.target.metric)
print(group.data.variables)
group.training.data <- complete.data[, ..group.data.variables]
# run main code
group.tree <- rpart(formula = paste(group.target.metric, "~." ),
data = group.training.data,
method = "anova")
Can anyone please guide what this could be about?
Rpart version I'm using is 4.1-15
The issue was while creating data.config$dict it had missing definitions/datatypes for one variable I was using in the model. To check & update datatype in complete.data table use query:
complete.data <- UpdateDataTypes(complete.data, data.config$dict)

How to capture particular warning message and execute call

Lately when I run my code that uses coxph in the survival package
coxph(frml,data = data), I am now getting warning messages of the following type
1: In model.matrix.default(Terms, mf, contrasts = contrast.arg) :
partial argument match of 'contrasts' to 'contrasts.arg'
2: In seq.default(along = temp) :
partial argument match of 'along' to 'along.with'"
I'm not exactly sure why all of a sudden these partial argument match warnings started popping up, but I don't think they effect me.
However, when I get the following warning message, I want coxph(frml,data = data) = NA
3: In fitter(X, Y, strats, offset, init, control, weights = weights, :
Loglik converged before variable 2 ; beta may be infinite.
6: In coxph(frml, data = data) :
X matrix deemed to be singular; variable 1 3 4
I used tryCatch when I wasn't getting the partial argument match warning using this code where if the nested tryCatch got either a warning or error message it would return NA
coxphfit = tryCatch(tryCatch(coxph(frml,data = data), error=function(w) return(NA)), warning=function(w) return(NA))
However, now that I am getting the partial argument match warnings, I need to only return an NA if there is an error or if I get the above warning messages 3 and 4 . Any idea about how to capture these particular warning messages and return an NA in those instances?
It's actually interesting question, if you are looking for quick and dirty way of capturing warnings you could simply do:
withCallingHandlers({
warning("hello")
1 + 2
}, warning = function(w) {
w ->> w
}) -> res
In this example the object w created in parent environment would be:
>> w
<simpleWarning in withCallingHandlers({ warning("hello") 1 + 2}, warning = function(w) { w <<- w}): hello>
You could then interrogate it:
grepl(x = w$message, pattern = "hello")
# [1] TRUE
as
>> w$message
# [1] "hello"
Object res would contain your desired results:
>> res
[1] 3
It's not the super tidy way but I reckon you could always reference object w and check if the warning message has the phrase you are interested in.

Error Handling in R when implementing association test

I am implementing a zero-inflated negative binomial in R. The code is here:
> ICHP<-read.table("ichip_data_recodeA.raw",header=TRUE)
ICHPdt<-data.table(ICHP)
covfile<-read.table("sorted.covfile.to.glm.out",header=TRUE)
covfiledt<-data.table(covfile)
library(pscl)
fhandle<-file("ichip_zi_nb_model_scoretest.csv","a")
for (i in seq(7, ncol(ICHPdt), 1)) {
notna<-which(!is.na(ICHPdt[[i]]))
string<-eval(parse(text = paste("ICHPdt$", colnames(ICHPdt)[i], sep="")))
nullglmmod<-zeroinfl(formula=OverllTot0[notna] ~ EurAdmix[notna] + Sex[notna] + DisDurMonths[notna] + BMI[notna] + Group[notna] + SmokingStatus[notna], data=covfiledt, dist="negbin")
nullsum<-coef(summary(nullglmmod))
glmmod<-zeroinfl(formula=OverllTot0[notna] ~ EurAdmix[notna] + Sex[notna] + DisDurMonths[notna] + BMI[notna] + Group[notna] + SmokingStatus[notna] + ICHPdt[[i]][notna], data=covfiledt, dist="negbin")
summ <- coef(summary(glmmod))
rownames(summ$zero)[8] <- paste0("ICHPdt$", colnames(ICHPdt)[i])
rownames(summ$count)[8] <- paste0("ICHPdt$", colnames(ICHPdt)[i])
writeLines("zero", con=fhandle)
writeLines(colnames(ICHPdt)[i], fhandle)
write.table(round(summ$zero, 4), file=fhandle)
writeLines("count", con=fhandle)
writeLines(colnames(ICHPdt)[i], fhandle)
write.table(round(summ$count, 4), file=fhandle)
}
The script errors when i=9246, and issues the following:
Error in solve.default(as.matrix(fit$hessian)) :
system is computationally singular: reciprocal condition number = 1.12288e-19
Overall, I need to go through ~100,000 markers, so I should expect ~11 such errors.
I would like to help implementing options, for instance with tryCatch() for catching such an error, skipping that marker, and moving on.
I recommend reading this page for a quick primer and this page for a more complete explanation of error handling, and you should eventually read ?conditions, but in short, there are two ways to handle errors. The first is with a try-catch, as in:
AS.NUMERIC <- function(x){
# for use in the warning handler
expectedWarning <- FALSE
result = tryCatch({
# a calculation that might raise an error or warning
as.numeric(x)
}, warning = function(w) {
# the typical way to identify the type of
# warning is via it's message attribure
if(grepl('^NAs introduced by coercion',w$message)){
cat('an expected warning was issued\n')
# assign the expected value using the scoping assignment
expectedWarning <<- TRUE
}else
cat('an unexpected warning was issued\n')
# reissue the warning
warning(w)
}, error = function(e) {
cat('an error occured\n')
# similar things go here but for handling errors
}, finally = {
# stuff goes here that should happen no matter what,
# such as closing connections or resetting global
# options such as par(ask), etc.
})
# you can handle errors similarly
if(expectedWarning)
result <- 5
return(result)
}
AS.NUMERIC('5')
#> [1] 5
AS.NUMERIC('five') # raises a warning
#> an expected warning was issued
#> [1] 5
#> Warning message:
#> In doTryCatch(return(expr), name, parentenv, handler) :
#> NAs introduced by coercion
The second way is to use try(), which is less nuanced:
x = try(stop('arbitrary error'),# raise an error
silent=TRUE)
# if there is an error, x will be an object with class 'try-error'
if(inherits(x,'try-error'))
# set the default value for x here
x = 5

Resources