In my r script, I do perform an nls to get a fit value:
fit <- nls(...)
and then after that, I test if the nls succeeded by doing this:
if(is.na(fit)) {
print("succeeded")
}
but I get warnings:
the condition has length > 1 and only the first element will be used
am I doing this wrong? if so, what should I do? if not, how do I remove the warning? thanks!
nls induces an error if the fitting failed. So, is.null after try(nls(...)) is the correct way.
here is a piece of code I used when using nls fit for uncertain data:
fit <- NULL
while (TRUE) {
start <- list(...) # try somewhat randomized initial parameter
try(fit <- nls(..., start = start)) # performe nls
if (!is.null(fit)) break;
}
Related
I have developed new probability model using generalized technique of mixturing.
Now i want it's fitting on discrete data set.
But i am getting error that
Error in seq.default(0, x) : 'to' must be of length 1
I don't understand, how to handle this.
R code is below:
# rm(list=ls(all=TRUE))
obs=rep(seq(0,6),c(260,87,32,4,1,0,0))
NBWED<-function(x,r,alpha,beta){
j=seq(0,x)
C=function(n,x){
factorial(n)/(factorial(n-x)*factorial(x))
}
C(x+r-1,x)*sum(C(x,j)*(-1)^j*(alpha^2/(alpha+beta))*((r+j+alpha)+beta)/(r+j+alpha)^2)
}
library(MASS)
fit09=fitdistr(x = obs,densfun = NBWED,start = list(r=1,alpha=0.5,beta=9.4),lower = list(a = 0.1,0.001,0.001),upper=c(Inf,Inf,Inf))
fit09
seq(0,n) creates a vector from 0 to n. Probably, your x is a vector or something similar, therefore it throws an error.
Just try: seq(0,5) and see the result. It would help.
Issue 1
I have an objective function, gFun(modelOutput,l,u), which returns 0 if the simulated output is in interval [l,u], otherwise it returns a positive(!) number.
OFfun <- function(params) {
out <- simulate(params)
OF <- gFun(out,0,5)
return(OF)
}
The objective function is called from the optim function with some tolerance settings.
fitval=optim(par=parms,fn=OFfun,method="SANN",control = list(abstol = 1e-2))
summary(fitval)
My issue is that the optimization doesn't stop if the OFfun == 0.
I have tried with the condition below:
if (OF == 0){
opt <- options(show.error.messages=FALSE)
on.exit(options(opt))
stop()
}
it works but it doesn't return the OF back to optim and therefore I don't get the fitval info with estimated parameters.
Issue 2
Another issue is that the solver sometimes crashes and aborts the entire optimisation. I would like to harvest many solution sets for different initial guesses - so I need to handle failed simulations. probably related to issue 1.
Any advice would be very appreciated.
I'm running a bunch of logit models, some of them with perfect separation which returns a glm warning. Here a dataset that shows the problem:
DT <- iris
str(DT)
DT$binary <- as.numeric(DT$Petal.Width>1)
DT$dummy <- as.numeric(as.numeric(DT$Species)>2)
mylogit <- glm(binary~Sepal.Length+dummy,data = DT, family=binomial(link='logit'))
I'm collecting estimates, model fit, etc from mylogit inside an apply function and would like to add a dummy showing if this warning was returned. However, I don't understand the tryCatch() syntax enough and the examples I find are mostly aimed at returning warnings etc. I'm looking for something like:
if(warning is returned){x <- 1}
Is tryCatch() the wrong approach?
Yes, tryCatch is the right function to use:
x <- 0
tryCatch(
mylogit <- glm(binary~Sepal.Length+dummy,data = DT, family=binomial(link='logit')),
warning = function(w) { x <<- x + 1 }
)
The <<- is necessary, as you are assigning to a variable that is outside the scope of the function. (Usually that is a bad idea but here it is necessary.)
If you want to do something with the warning text, use conditionMessage(w).
tryCatch would be the correct approach. I agree with you that some examples are not as clear and had some trouble with tryCatch in the past myself as well. I always find the following SO answer a helpful reference: How to write trycatch in R
I realized a strange behavior today with in my R code.
I tried a package {boot.StepAIC} which includes a bootstrap function for the results of the stepwise regression with the AIC. However I do not think the statistical background is here the problem (I hope so).
I can use the function at the top level of R. This is my example code.
require(MASS)
require(boot.StepAIC)
n<-100
x<-rnorm(n); y<-rnorm(n,sd=2); z<-rnorm(n,sd=3); res<-x+y+z+rnorm(n,sd=0.1)
dat.test<-as.data.frame(cbind(x,y,z,res))
form.1<-as.formula(res~x+y+z)
boot.stepAIC(lm(form.1, dat.test),dat.test) # should be OK - works at me
However, I wanted to wrap that in an own function. I pass the data and the formula to that function. But I get an error within boot.stepAIC() saying:
the model fit failed in 100 bootstrap samples Error in
strsplit(nam.vars, ":") : non-character argument
# custom function
fun.boot.lm.stepAIC<-function(dat,form) {
if(!inherits(form, "formula")) stop("No formula given")
fit.lm<-lm(formula=form,data=dat)
return(boot.stepAIC(object=fit.lm,data=dat))
}
fun.boot.lm.stepAIC(dat=dat.test,form=form.1)
# results in an error
So where is the mistake? I suppose it must have something to do with the local and global environment, doesn't it?
Using do.call as in anova test fails on lme fits created with pasted formula provides the answer.
boot.stepAIC doesn't have access to form when run within a function; that can be recreated in the global environment like this; we see that lm is using form.1 as the formula, and removing it makes boot.stepAIC fail.
> form.1<-as.formula(res~x+y+z)
> mm <- lm(form.1, dat.test)
> mm$call
lm(formula = form.1, data = dat.test)
> rm(form.1)
> boot.stepAIC(mm,dat.test)
# same error as OP
Using do.call does work. Here I use as.name as well; otherwise the mm object carries around the entire dataset instead of just the name of it.
> form.1<-as.formula(res~x+y+z)
> mm <- do.call("lm", list(form.1, data=as.name("dat.test")))
> mm$call
lm(formula = res ~ x + y + z, data = dat.test)
> rm(form.1)
> boot.stepAIC(mm,dat.test)
To apply this to the original problem, I'd do this:
fun.boot.lm.stepAIC<-function(dat,form) {
if(!inherits(form, "formula")) stop("No formula given")
mm <- do.call("lm", list(form, data=as.name(dat)))
do.call("boot.stepAIC", list(mm,data=as.name(dat)))
}
form.1<-as.formula(res~x+y+z)
fun.boot.lm.stepAIC(dat="dat.test",form=form1)
This works too but the entire data set gets included in the final output object, and the final output to console, as well.
fun.boot.lm.stepAIC<-function(dat,form) {
if(!inherits(form, "formula")) stop("No formula given")
mm <- do.call("lm", list(form, data=dat))
boot.stepAIC(mm,data=dat)
}
form.1<-as.formula(res~x+y+z)
fun.boot.lm.stepAIC(dat=dat.test,form=form.1)
I'm fitting some exponential data using nls.
The code I'm using is:
fit <- nls(y ~ expFit(times, A, tau, C), start = c(A=100, tau=-3, C=0))
expFit is defined as
expFit <- function(t, A, tau, C)
{
expFit <- A*(exp(-t/tau))+C
}
This works well for most of my data, for which the starting parameters provided (100, -3 and 0) work well. Sometimes, though, I have data that doesn't go well with those parameters and I get errors from nls (e.g. "singular gradient" or things like that). How do I "catch" these errors?
I tried to do something like
fit <- NULL
fit <- nls(...)
if (is.null(fit))
{
// Try nls with other starting parameters
}
But this won't work because nls seems to stop the execution and the code after nls will not execute...
Any ideas?
Thanks
nico
I usually use this trick:
params<-... # setup default params.
while(TRUE){
fit<-NULL
try(fit<-nls(...)); # does not stop in the case of error
if(!is.null(fit))break; # if nls works, then quit from the loop
params<-... # change the params for nls
}