Callum25252
Callum25252

Reputation: 33

Why does nls return "Missing value or an infinity produced when evaluating the model" in this instance?

I'm trying to fit an exponential model to a set of data I have using R's nls method. The model in question is:

y=ae^(bx)

I get estimated start points by taking logs of both sides then finding the coefficients from a linear regression model, then pass them into nls. When I do this, nls throws up the "Missing value or an infinity produced when evaluating the model" error.

The model worked when I tested it with values that I'd set manually (a=1, b=1) but I want my code to work with more than just the test data. I've tried swapping the values of a and b around and also tried using selfStart methods (although I didn't fully understand them).

This is my code so far:

csvfile <- read.csv("testdata.csv")
col1<-unlist(lapply(csvfile[colnames(csvfile)[1]], log))
col2<-unlist(lapply(csvfile[colnames(csvfile)[2]], log))
a_start<-as.numeric(summary(lm(col2~col1))$coefficients[2])
b_start<-as.numeric(summary(lm(col2~col1))$coefficients[4])
f=as.formula(paste(as.name(colnames(csvfile)[1]),"~I(a*exp(b*",as.name(colnames(csvfile[2])),"))"))
expo<-nls(f,data=csvfile, start=list(a=a_start,b=b_start))

and this is the content of testdata.csv:

"x","y"
1,7
2,10
3,24
4,47
5,96

I was expecting to get a result back such that a=2.78545 and b=0.707868, which was what I got when I manually entered the start values.

Any and all help/advice is appreciated, thanks.

Upvotes: 2

Views: 452

Answers (1)

ekstroem
ekstroem

Reputation: 6191

Welcome to SO.

I think this is due to a minor typing error. When you generate your formula with

f=as.formula(paste(as.name(colnames(csvfile)[1]),"~I(a*exp(b*",as.name(colnames(csvfile[2])),"))"))

then you are actually producing the formula

> f
x ~ I(a * exp(b * y))

I think you have swapped the x and the y around and the starting value for a needs to be back-transformed. At least, when you create the starting values from the logged variables then you model log(y) as a function of log(x). If you do the following instead then it appears to work

> f=as.formula(paste(as.name(colnames(csvfile)[2]),"~I(a*exp(b*",as.name(colnames(csvfile[1])),"))"))
> expo<-nls(f,data=csvfile, start=list(a=exp(a_start),b=b_start))
> expo
Nonlinear regression model
  model: y ~ I(a * exp(b * x))
   data: csvfile
     a      b 
2.7854 0.7079 
 residual sum-of-squares: 4.569

Number of iterations to convergence: 7 
Achieved convergence tolerance: 1.099e-08

A few other comments: Why do you log the x's? log(a exp(bx)) = log(a) + bx

Also, you can write it more compact as

initial_model <- lm(log(y) ~ x, data=csvfile)
f <- as.formula(paste(as.name(colnames(csvfile)[2]),"~I(a*exp(b*",as.name(colnames(csvfile[1])),"))"))
expo <- nls(f, data=csvfile, start=list(a=exp(coef(initial_model)[1]),b=coef(initial_model)[2]))

Upvotes: 1

Related Questions