Hi, I've got the following data: x<-c(1,3,5,7) y<-c(37.98,11.68,3.65,3.93) penetrationks28<-dataframe(x=x,y=y) now I need to fit a non linear function so I did: fit <- nls(y ~ I(a+b*exp(1)^(-c * x)), data = penetrationks28, start list(a=0,b = 1,c=1), trace = T) The error message I get is: Error in nls(y ~ I(a + b * exp(1)^(-c * x)), data = penetrationks28, start list(a = 0, : singular gradient I've tried to change the startervalues but it always gives the same error I've also tried the following adjustment hoping that the c value would be negative: fit <- nls(y ~ I(a+b*exp(1)^(c * x)), data = penetrationks28, start = list(a = 1,b = 1,c=1), trace = T) but then the error message is: Error in nls(y ~ I(a + b * exp(1)^(c * x)), data = penetrationks28, start list(a = 1, : number of iterations exceeded maximum of 50 What can I do ? Thanks in advance -- View this message in context: http://r.789695.n4.nabble.com/nls-function-tp4546791p4546791.html Sent from the R help mailing list archive at Nabble.com.
On Apr 10, 2012, at 4:03 PM, nerak13 wrote:> Hi, > > I've got the following data: > > x<-c(1,3,5,7) > y<-c(37.98,11.68,3.65,3.93) > penetrationks28<-dataframe(x=x,y=y) > > now I need to fit a non linear function so I did: > > fit <- nls(y ~ I(a+b*exp(1)^(-c * x)), data = penetrationks28, start > list(a=0,b = 1,c=1), trace = T) > > The error message I get is: > Error in nls(y ~ I(a + b * exp(1)^(-c * x)), data = penetrationks28, > start > list(a = 0, : > singular gradient > > I've tried to change the startervalues but it always gives the same > error > > I've also tried the following adjustment hoping that the c value > would be > negative: > > fit <- nls(y ~ I(a+b*exp(1)^(c * x)), data = penetrationks28, start > = list(a > = 1,b = 1,c=1), trace = T) > > but then the error message is: > Error in nls(y ~ I(a + b * exp(1)^(c * x)), data = penetrationks28, > start > list(a = 1, : > number of iterations exceeded maximum of 50 > > What can I do ? >?nls "Warning: Do not use nls on artificial "zero-residual" data." Get more data. (with 3 coefficients and 4 data points you have created a zero-residual situation even if it's not "artificial".) -- David Winsemius, MD West Hartford, CT
On Apr 10, 2012, at 22:03 , nerak13 wrote:> Hi, > > I've got the following data: > > x<-c(1,3,5,7) > y<-c(37.98,11.68,3.65,3.93) > penetrationks28<-dataframe(x=x,y=y) > > now I need to fit a non linear function so I did: > > fit <- nls(y ~ I(a+b*exp(1)^(-c * x)), data = penetrationks28, start > list(a=0,b = 1,c=1), trace = T)That's the second time you have been posting code with that weird sort of formula. Please: y ~ a + b * exp(-c * x) I() is only needed for linear models where arithmetic operators have special meaning, and exp(1)^x for exp(x) just hurts our eyes. Apart from that, you just need better starting values, it seems:> fit <- nls(y ~ a + b * exp(-c * x),data = penetrationks28, start + list(a=3,b = 15,c=1), trace = T)932.0747 : 3 15 1 310.2288 : 2.9756409 25.5127564 0.3610715 137.811 : 5.6501434 42.5276986 0.6921207 2.187083 : 2.6843590 71.7142051 0.7180404 1.9709 : 2.6657517 71.6213474 0.7058412 1.970713 : 2.6726912 71.6839169 0.7069178 1.970712 : 2.6719547 71.6797621 0.7068432 1.970712 : 2.6720049 71.6800584 0.7068484> summary(fit)Formula: y ~ a + b * exp(-c * x) Parameters: Estimate Std. Error t value Pr(>|t|) a 2.6720 1.4758 1.811 0.3212 b 71.6801 7.7101 9.297 0.0682 . c 0.7068 0.1207 5.856 0.1077 --- Signif. codes: 0 ?***? 0.001 ?**? 0.01 ?*? 0.05 ?.? 0.1 ? ? 1 Residual standard error: 1.404 on 1 degrees of freedom Number of iterations to convergence: 7 Achieved convergence tolerance: 3.067e-06> fitted(fit)[1] 38.024329 11.271188 4.763691 3.180792 attr(,"label") [1] "Fitted values" .......... As David points out, three parameters to 4 data values is a bit absurd. Although not technically infeasible, I would not trust those 1 df t-tests at all. Concerning the starting values, finding them is a bit of an art, but you clearly need something better than grabbing values out of thin air. Various techniques for finding starting values can be extracted by looking at the code for the self-start routines that come with nls() (the ones with names starting with SS). In the present case, you might try guessing a as the asymptote for large x so a value somewhat lower than the last value of y should do, say a=3. Subtract a from both sides and you get y-a = b*exp(-c*x) which you can make linear as log(y-a) = log(b) - c*x. So fit this using> lm(log(y-3)~x,data=penetrationks28)Call: lm(formula = log(y - 3) ~ x, data = penetrationks28) Coefficients: (Intercept) x 3.9979 -0.6737 which suggests that a=3, b=exp(4), c=.67 might work, and it does, even though the starting values aren't exactly spot on:> fit <- nls(y ~ a + b * exp(-c * x),data = penetrationks28, start + list(a=3,b = exp(4),c=.67), trace = T)53.23186 : 3.00000 54.59815 0.67000 2.188135 : 2.7131685 71.6770898 0.7187123 1.970939 : 2.6654559 71.6169034 0.7057594 ... -- Peter Dalgaard, Professor, Center for Statistics, Copenhagen Business School Solbjerg Plads 3, 2000 Frederiksberg, Denmark Phone: (+45)38153501 Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com
nls() often gives this message, which is misleading in that it is the Jacobian that is not of full rank in the solution of J * delta ~ - residuals or in more conventional Gauss-Newton J' * J delta = -g = - J' * residuals. My view is that the gradient itself cannot be "singular". It's just the slope of the sum of squares w.r.t. the parameters. I'm separately sending you an experimental code that does get an answer. It is in the package nlmrt on R-forge https://r-forge.r-project.org/R/?group_id=395 which is under development. Note that the I() function doesn't seem to be defined. I left it out to get an answer. John Nash On 04/11/2012 06:00 AM, r-help-request at r-project.org wrote:> Message: 83 > Date: Tue, 10 Apr 2012 13:03:58 -0700 (PDT) > From: nerak13 <karen.vandepoel at gmail.com> > To: r-help at r-project.org > Subject: [R] nls function > Message-ID: <1334088238773-4546791.post at n4.nabble.com> > Content-Type: text/plain; charset=us-ascii > > Hi, > > I've got the following data: > > x<-c(1,3,5,7) > y<-c(37.98,11.68,3.65,3.93) > penetrationks28<-dataframe(x=x,y=y) > > now I need to fit a non linear function so I did: > > fit <- nls(y ~ I(a+b*exp(1)^(-c * x)), data = penetrationks28, start > list(a=0,b = 1,c=1), trace = T) > > The error message I get is: > Error in nls(y ~ I(a + b * exp(1)^(-c * x)), data = penetrationks28, start > list(a = 0, : > singular gradient > > I've tried to change the startervalues but it always gives the same error > > I've also tried the following adjustment hoping that the c value would be > negative: > > fit <- nls(y ~ I(a+b*exp(1)^(c * x)), data = penetrationks28, start = list(a > = 1,b = 1,c=1), trace = T) > > but then the error message is: > Error in nls(y ~ I(a + b * exp(1)^(c * x)), data = penetrationks28, start > list(a = 1, : > number of iterations exceeded maximum of 50 > > What can I do ? > > Thanks in advance > > -- > View this message in context: http://r.789695.n4.nabble.com/nls-function-tp4546791p4546791.html > Sent from the R help mailing list archive at Nabble.com. >
Possibly Parallel Threads
- nls.control( ) has no influence on nls( ) !
- 'singular gradient matrix’ when using nls() and how to make the program skip nls( ) and run on
- predict.nls - gives error but only on some nls objects
- nls() error
- How to get the parameters of nls(...) for later use