[R] non linear regression with nls
lauramorgana at bluewin.ch
lauramorgana at bluewin.ch
Thu Feb 5 10:14:51 CET 2009
Thank you a lot Mr. Ritz!
I've tried the loop you suggested and I added a list for lower and upper limits of the parameters, but there is still
a problem...
I have a list of functions, which works...
fz1<-function(Portata, a, b){a+(b/Portata)}
fz2<-function(Portata, a, b){a*exp(b*Portata)}
fz3<-function(Portata, a, b, d, e){a+(b/Portata)+d*(Portata^e)}
fz4<-function(Portata, a, b){a*Portata^b}
fz5<-function(Portata, a, b, d){a+b*(Portata^d)}
fctList <- list(fz1, fz2, fz3, fz4, fz5)
as well as lists for starting values, upper and lower values, which work as well:
startList <- list(list(a=10, b=10), list(a=10, b=1), list(a=10, b=10, d=10, e=1), list(a=10, b=1), list(a=10, b=10,
d=1))
lowerList<-list(list(a=0,b=0),list(a=0,b=0), list(a=0,b=0,d=0,e=-50),list(a=0, b=-50), list(a=0, b=0, d=-50))
upperList<-list(list(a=1000, b=1000), list(a=1000, b=1000), list(a=1000,b=1000,d=1000,e=50), list(a=1000,b=50), list
(a=1000, b=1000, d=50))
but if I try to run this for loop
resultList <- list()
for (i in 1:5)
{
resultList[[i]] <- nls(NT.N ~ fctList[[i]](Portata, a,b), data=subset(dati, Fiume=="Laveggio"), start=startList[[i]],
nls.control(maxiter=200), algorithm='port', trace=TRUE, na.action=na.omit, upper=upperList[[i]], lower=lowerList[[i]])
}
I get the following error message:
"Error in fctList[[i]](Portata, a, b) : element 1 is empty;
the part of the args list of '*' being evaluated was:
(d, (Portata^e))"
I realized that the problem is the element after the function, i.e. (Portata, a, b), since fct 3 and 5 have more
parameters (Portata,a,b,d,e).
So I tried to make a list (parList) for this too, i tried 2 versions:
#version1
list("Portata","a", "b")->pf1.2.4
list("Portata","a","b","d","e")->pf3
list("Portata","a","b","d")->pf5
parList<-list(pf1.2.4, pf1.2.4,pf3,pf1.2.4,pf5)
#version 2
parList<-list("Portata,a,b","Portata,a,b","Portata,a,b,d,e", "Portata,a,b","Portata,a,b,d")
and then I tried them (one at a time) in the loop:
resultList <- list()
for (i in 1:5)
{
resultList[[i]] <- nls(NT.N ~ fctList[[i]](parList[[i]]), data=subset(dati, Fiume=="Laveggio"), start=startList
[[i]], nls.control(maxiter=200), algorithm='port', trace=TRUE, na.action=na.omit,upper=upperList[[i]], lower=lowerList
[[i]])
}
but I got this error message: " Error in fctList[[i]](parList[i]) : element 1 is empty;
the part of the args list of '+' being evaluated was:
(a, (b/Portata))"
What can I do to fix it?
I'm also wondering which kind of function (maybe another loop?) I could use to automize the regression not only for
the variable NT.N but for every variable (PTG.P, PO4.P,. ..)
My dataframe look like this (a sample):
Fiume giorno mese anno Portata PTG.P PO4.P NT.N NH4.N NO3.N BOD5 SiO2 data
1 Vedeggio 10 1 1995 0.981 218.40 118.000 9.196 6.5700 2.06 6.080 4.33 34709
2 Vedeggio 7 2 1995 0.965 125.84 54.000 8.701 5.2600 2.31 16.480 4.43 34737
3 Vedeggio 7 3 1995 1.536 37.44 12.000 7.271 5.5600 1.88 5.240 4.15 34765
...
190 Cassarate 29 9 2008 1.240 26.00 20.000 2.480 0.1200 1.79 1.700 4.03 39720
191 Cassarate 13 10 2008 0.860 23.00 16.000 2.720 0.0200 2.13 1.780 3.71 39734
192 Cassarate 10 11 2008 8.840 26.00 14.000 2.900 0.0500 NA 1.400 3.62 39762
193 Cassarate 9 12 2008 2.030 35.00 23.000 2.190 0.0700 1.79 1.950 3.74 39791
...
279 Laveggio 15 1 2002 0.347 77.00 30.000 9.690 0.4300 7.23 1.950 4.17 37271
280 Laveggio 11 2 2002 0.527 54.00 17.000 7.520 0.8800 5.87 2.410 3.58 37298
281 Laveggio 13 3 2002 0.900 34.00 15.000 7.520 0.7100 6.17 6.550 3.03 37328
...
Thanks to anyone that could give me any hint!!
Laura
## a for loop
resultList <- list()
for (i in 1:5)
{
## storing the result as the i'th list component
## notice that the i'th list components in fctList and startList
## are used for the i'th fit
resultList[[i]] <- nls(NT.N ~ fctList[[i]](parList[[i]]), data=subset(dati, Fiume=="Laveggio"), start=startList
[[i]], nls.control(maxiter=200), algorithm='port', trace=TRUE, na.action=na.omit)
}
----Messaggio originale----
Da: ritz at life.ku.dk
Data: 03.02.2009 19.00
A: <lauramorgana at bluewin.ch>
Oggetto: Re: [R] non linear regression with nls
Hi Laura,
I've the following suggestion for you using several lists and a "for" loop:
fz1<-function(Portata, a, b){a+b/Portata}
fz2<-function(Portata, a, b){a*exp(b*Portata)}
fz3<-function(Portata, a, b, d, e){a+b/Portata+d*(Portata^e)}
fz4<-function(Portata, b, d){b*Portata^d}
fz5<-function(Portata, a, b, d){a+b*(Portata^d)}
fctList <- list(fz1, fz2, fz3, fz4, fz5)
startList <- list(list(a=10, b=10), list(a=10, b=1), start=list(a=10, b=10, d=10, e=10),
list(a=10, b=1), list(a=10, b=10, d=1))
## a for loop
resultList <- list()
for (i in 1:5)
{
## storing the result as the i'th list component
## notice that the i'th list components in fctList and startList
## are used for the i'th fit
resultList[[i]] <- nls(NT.N ~ fctList[[i]](Portata, a,b),
data=subset(dati, river.name=="Laveggio"), start=startList[[i]],
nls.control(maxiter=200), algorithm='port', trace=TRUE, na.action=na.omit)
}
summary(resultList[[1]])
plotfit(resultList[[1]])
summary(resultList[[2]])
plotfit(resultList[[2]])
...
I hope you can make it work?
Christian
More information about the R-help
mailing list