[R] Comparing Von Bertalanffy Growth Curves

Ben Bolker bbolker at gmail.com
Tue Sep 4 23:58:08 CEST 2012


April Lindeman <aprillindeman <at> yahoo.com> writes:


> I am trying to compare Vbert growth curves from several years of
> fish data. I am following the code provided by:
> http://www.ncfaculty.net/dogle/fishR/gnrlex/VonBertalanffy/VonBertalanffy.pdf.
> Specifically the section on VBGM Comparisons between groups.


> This code is pretty cut and dry. I am able to run it perfectly with
> the "fake" data that is provided. But when I run it with my own data
> I get stuck with this line: fitGen <-
> nls(vbGen,data=LMB,start=svGen)

> I get this error code: Error in numericDeriv(form[[3L]], names(ind), env) :
Missing value or an infinity
> produced when evaluating the model.

> Does anyone know how to fix it? I have no missing values and do not know how
to fix the infinity produced. 

> Here is my data set: structure(list(Age = c(1L, 2L, 3L, 5L, 1L, 2L,
> 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L,
> 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L), MM =
> c(155.79, 296.37, 325.77, 374.65, 181.46, 258.31, 321.88, 355.6,
> 139.75, 230.72, 319.61, 344.84, 130.92, 236.34, 290.53, 360.33,
> 400.61, 155.33, 240.87, 315.46, 345.05, 378.2, 134.71, 256.66,
> 333.71, 362.99, 381.46, 153.91, 217.21, 287.8, 357.28, 385.62,
> 222.25, 288.93, 294.05, 332.79, 367.39), Year = c(2005L, 2005L,
> 2005L, 2005L, 2006L, 2006L, 2006L, 2006L, 2007L, 2007L, 2007L,
> 2007L, 2008L, 2008L, 2008L, 2008L, 2008L, 2009L, 2009L, 2009L,
> 2009L, 2009L, 2010L, 2010L, 2010L, 2010L, 2010L, 2011L, 2011L,
> 2011L, 2011L, 2011L, 2012L, 2012L, 2012L, 2012L, 2012L)), .Names =
> c("Age", "MM", "Year"), class = "data.frame", row.names = c(NA,
> -37L))

> In case it's helpful here is all my code before this point: 
> str(LMB) 
> MMi=as.integer(MM) 
> Yearf=as.factor(Year) 
> Agei=as.integer(Age) 
> ( svCom <- vbStarts(MMi~Agei,data=LMB)) 
> ( svGen <- lapply(svCom,rep,2) ) 
> vbGen <- MMi~Linf[Yearf]*(1-exp(-K[Yearf]*(Age-t0[Yearf]))+error) 
> fitGen <- nls(vbGen,data=LMB,start=svGen) 


  I believe that the reason you're running into trouble is that
you have a very small number of data points per year.  You're trying
to fit a three-parameter model to at *most* 5 data points per year,
and at least 4 (2005-2007 have only 4 ages, 2008-2012 have 5 ages).
In principle this should be possible, but nls is a little bit
fragile and so it gets in trouble.  I wasn't able to run all your
code because some of the packages you use seem to be unavailable
for the development version of R I'm using ...

  The following solution works for me.  You may be better off
fitting a nonlinear mixed model, but I don't have time to work
out that example at the moment ...

LMB <- structure(list(Age = c(1L, 2L, 3L, 5L, 1L, 2L, 3L, 4L, 1L, 2L,
3L, 4L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L,
1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L), MM = c(155.79, 296.37,
325.77, 374.65, 181.46, 258.31, 321.88, 355.6, 139.75, 230.72, 319.61,
344.84, 130.92, 236.34, 290.53, 360.33, 400.61, 155.33, 240.87,
315.46, 345.05, 378.2, 134.71, 256.66, 333.71, 362.99, 381.46, 153.91,
217.21, 287.8, 357.28, 385.62, 222.25, 288.93, 294.05, 332.79,
367.39), Year = c(2005L, 2005L, 2005L, 2005L, 2006L, 2006L, 2006L,
2006L, 2007L, 2007L, 2007L, 2007L, 2008L, 2008L, 2008L, 2008L, 2008L,
2009L, 2009L, 2009L, 2009L, 2009L, 2010L, 2010L, 2010L, 2010L, 2010L,
2011L, 2011L, 2011L, 2011L, 2011L, 2012L, 2012L, 2012L, 2012L,
2012L)), .Names = c("Age", "MM", "Year"), class = "data.frame",
row.names = c(NA, -37L))

library(ggplot2)
LMB$Yearf <- factor(LMB$Year)
(g0 <- ggplot(LMB,aes(Age,MM))+geom_point(aes(colour=factor(Year))))
(g2 <- g0 + geom_smooth(aes(colour=factor(Year)),se=FALSE,method="auto",span=2))
n1 <- nls(MM~SSasympOff(Age,Asym,lrc,c0),data=LMB)
pframe <- data.frame(Age=seq(1,5,length.out=50))
pframe$MM <- predict(n1,newdata=pframe)
(g1 <- g0+geom_line(data=pframe))
library(nlme)
nyear <- length(unique(LMB$Year))
svec <-  c(rbind(coef(n1),
           matrix(0,nrow=nyear-1,ncol=length(coef(n1)))))
fit2 <- gnls(MM~SSasympOff(Age,Asym,lrc,c0),data=LMB,
     params=Asym+lrc+c0~Yearf,
     start=svec)
printCoefmat(summary(fit2)$tTable)
pframe2 <- expand.grid(Age=seq(1,5,length.out=50),
                       Year=unique(LMB$Year))
pframe2$Yearf <- factor(pframe2$Year)
pframe2$MM <- predict(fit2,newdata=pframe2)
g0 + geom_line(data=pframe2,
               aes(colour=factor(Year)))




More information about the R-help mailing list