Is there any function in R, whose return is identical to the return of excel’s SEERRO() function?

Asked

Viewed 50 times

0

I am trying to generate a general function, which runs several regression models. The problem is that when a model gives error, the main function stops. I would like to use a parole that in case of error, skip to the next step:

Example: when trying to run a model nls(), presents this message described below, as this function is one of which I am testing within a general function, it locks the function at this point.

an example, when I want to load some package, I usually do so:

if(!require(nome do pacote)){install.packages("nome do pacote")}

in my intention is like this: if(there is no such package){ install the package} so here I inform that "!" would represent the "error".

assuming I create a function:

melhor.ajuste<-function(df,x,y){
n1<-nls(y~x+c/e*x^d,start=....,data=df)
n2<-nls(y~x-b*e^d/log(x),start=....,data=df)
n3<-nls(y~x+a*b/c^x,start=....,data=df)
list(modelo1=n1,modelo2=n2,modelo3=n3)}

if for example the function N2 shows any error, as an example:

stop(simpleError("Error in nlsModel(formula, mf, start, wts) :\n matriz gradiente singular com estimativas de parâmetros iniciais"))

my function does not present me any value, because there was a mistake!

what I wish was something like:

if(!nls(y~x+c/e*x^d,start=....,data=df)){n1=0}else{n1<-nls(y~x+c/e*x^d,start=....,data=df)}
if(!nls(y~x+a*b/c^x,start=....,data=df)){n2=0}else{n1<-nls(y~x+a*b/c^x,start=....,data=df)}
if(!nls(y~x+a*b/c^x,start=....,data=df)){n3=0}else{n1<-nls(y~x+a*b/c^x,start=....,data=df)}

someone knows somehow I do it! excel does, by the SEERRO() function, where I go (if I make a mistake; do this), in my case it would be, se(seerro(nls(y~x+a*b/c^x,start=....,data=df);0)==0;n1=0;n1=nls(y~x+a*b/c^x,start=....,data=df)), or would be a parole that identifies error, within a conditional.

Making it clear, that at no time, my main objective is to find out what the mistake is and try to fix it, because I will apply the function in more than 50 models, knowing that some do not fit even, because it is a singular matrix, for bursting the minFactor, and something like that. my goal, is to find a way that if the function presents error it concatene 0 to the object, and pass to the next model.

and at the end provide me the list of all models.

  • Have you tried using the try?

1 answer

3


Perhaps this artificial example, as is said in one of the examples of help("nls") in which you are inspired, you can give a helping hand. It shows how you can try several templates and continue even if there are errors in any of them. This is done using the function tryCatch error, a list of two members.

Data at the end.

regr <- "a + b*x"
resp <- grep("^y", names(dados), value = TRUE)

fit_list <- lapply(resp, function(y){
  fmla <- paste(y, regr, sep = "~")
  fmla <- as.formula(fmla)
  tryCatch(
    nls(fmla, start = list(a = 0.12345, b = 0.54321)),
    error = function(e) e
  )
})

err <- sapply(fit_list, inherits, "error")

Now we can see what the error structure is.

str(fit_list[err][[1]])
#List of 2
# $ message: chr "number of iterations exceeded maximum of 50"
# $ call   : language nls(fmla, start = list(a = 0.12345, b = 0.54321))
# - attr(*, "class")= chr [1:3] "simpleError" "error" "condition"

And get the member "message" for each of the list errors fit_list[err].

lapply(fit_list[err], "[[", "message")
#[[1]]
#[1] "number of iterations exceeded maximum of 50"
#
#[[2]]
#[1] "number of iterations exceeded maximum of 50"

As for the models that went well, one can extract the information available also with cycles lapply.

lapply(fit_list[!err], coef)
lapply(fit_list[!err], AIC)
lapply(fit_list[!err], summary)

With a for, the code has some changes but the call to tryCatch is the same.

The change is how to store the results. The best way is to create a list beforehand and assign the output of trCatch to each member of that list.

fit_list_for_loop <- vector("list", length = length(resp))

for(i in seq_along(resp)){
  fmla <- paste(resp[i], regr, sep = "~")
  fmla <- as.formula(fmla)
  fit_list_for_loop[[i]] <- tryCatch(
    nls(fmla, start = list(a = 0.12345, b = 0.54321)),
    error = function(e) e
  )
}

all.equal(fit_list, fit_list_for_loop)
#[1] TRUE

Test data

set.seed(2021)
x <- 1:10
y1 <- 2*x + 3                              # perfect fit
y1eps <- y1 + rnorm(length(y1), sd = 0.01) # added noise
y2 <- 3*x - 2                              # perfect fit
y2eps <- y2 + rnorm(length(y2), sd = 0.01) # added noise
dados <- data.frame(x, y1, y1eps, y2, y2eps)
  • I couldn’t reproduce, the y ! but remembering that I have no interest in capturing error, I would like a form of conditional, case: if(função(x,...)==erro){NULL} else {função(x,...)}.

  • @Jeankarlos What’s the mistake you make? You can make a mistake print(fmla) just before tryCatch?

  • I didn’t understand anything, I just commented that the y on your data, so I can’t reproduce any code that you posted, to try to understand what your script would do, and if that could suit me, and I just remembered, that I don’t care what the mistake is, after all I’m going to test over 60 models, what I want is a way that if, the data presents singular matrix, or that minFactor burst, or any other error that may appear, let it skip the model and move to the next, making it clear, I do not want to understand the error!!!!

  • @Jeankarlos With the data I posted the code find the y. But in relation to the question, we cannot say how to run all models despite the mistakes, there is no code in the question that allows us to know what to fix. You can edit the question with an example of code and data?

  • To run your script I need to generate the data. dados, for this in the 4th line you ask y, para criar o objeto y1eps`, so I can’t run your scripit since it’s based on the given object.

  • @Jeankarlos is right :(. It was y1 and y2 instead of y. Corrected.

  • Finally, I got time to see, and yes, it kind of does what I need, I actually have to use one more conditioner after kkkk, but it already suits me! Thank you!

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.