0

I'm trying to fit a Gompertz curve with the nls function, which always gives me the "singular gradient" error. I know a lot of questions are devoted to this error, but I still can't figure out my problem. I tried out multiple formula variations, starting values, the nlsLM function,... I feel like I'm missing something really simple but I've been searching for hours. Here's my data and the function:

a=structure(data.frame(sl = c(15.31, 14.21, 23.99, 13.34, 15.14, 14.83, 
                    23.53, 17.31, 14.69, 17.9, 11.9, 14.98, 22.43, 17.84, 13.84, 
                    13.5, 11.54, 12.76, 15.56, 16.11, 12.17, 17.74, 14.62, 11.36, 
                    10.57, 15.69, 20.91, 10.46, 10.78, 8.84, 9.89, 15.22, 9.34, 8.82, 
                    11.3, 9.11, 16.64, 12.94, 8.77, 9.44, 8.33, 10.14, 10.87, 9.92, 
                    10.01, 9.95, 10.38, 9.44, 11.09, 10.35, 13.04, 13.1, 12.78, 9.55, 
                    10.62, 10.7, 15, 8.48, 12.86, 16.18, 15.88, 23.51, 7.13, 8.75, 
                    18.09, 14.94, 17.64, 18.14, 15.71, 10.12, 23.74, 14, 7.36, 11.1, 
                    11.04, 23, 20.25, 17.57, 23.48, 16.98, 16.38, 17.77, 13.67, 10.55, 
                    15.66, 13.82, 15.37, 18.75, 14.74, 11.94, 19.52, 11.6, 8.91, 
                    11.84, 13.47, 11.55, 10.51, 12.09, 10.66, 10.92, 11.57, 13.19, 
                    10.01, 14.13, 14.83, 13.44, 12.5, 15.94, 12.83, 13.02, 22.19, 
                    20.62, 13.14, 14.24, 15.12, 15.79, 15.9, 9.76, 12.44, 10.75, 
                    10.62, 10.99, 10.12, 11.51, 11.22, 9.69, 11.58, 11.57, 13.16, 
                    12.97, 21.37, 13.97, 10.45, 10.91, 9.06, 10.86, 11.01, 12.05, 
                    11.33, 11.51, 17.62, 12.98, 6.51, 11.42, 12.6, 13.28, 10.68, 
                    13.25, 15.55, 10.24, 13.14, 14.44, 11.75, 11.75, 12.73, 20.19, 
                    13.11, 8.2, 15.17, 17.24, 17.51, 16.95, 12.79, 12.12, 12.97, 
                    14.46, 12.14, 8.8, 10.86, 14.75, 18.15, 15.95, 10.85, 14.92, 
                    12.9, 12.11, 12.77, 12.86, 16.09, 8.84, 14.88, 13.37, 10.76, 
                    14.56, 13.28, 13.46, 9.35, 11.16, 12.79, 15.25, 14.98, 10.21, 
                    9.9, 11.74, 14.78, 15.56, 11.16, 10.42, 9.12, 12.13, 11.82, 9.75, 
                    12.85, 10.57, 11.8, 11.09, 10.45, 8.71, 12.23, 14.31, 15.55, 
                    11.15, 10.17, 12.33, 12.02, 10.02, 12.75, 11.27, 13.45, 11.75, 
                    14.36, 12.76, 9.29, 12.92, 12.08, 9.86, 11.01, 12.23, 12.2, 11.43, 
                    13.97, 10.95, 13.16, 11.34, 10.66, 16.02, 22.03, 11.15, 9.29, 
                    10.01, 13.15, 9.24, 11.99, 9.16, 12.1, 15.12, 15.18, 15.09, 15.64, 
                    19.34, 17.82, 21.6, 10.98, 12.93, 9.93, 13.3, 16.12, 11.15, 13.58, 
                    19.41, 8.03, 14.04, 15.43, 14.65, 14.55, 16.64, 19.01, 17.38, 
                    15.08, 14.94, 13.04, 13.47, 13.78, 13.97, 10.98, 11.22, 10.93, 
                    18.87, 8.47, 13.57, 11.64, 13.23, 11.26, 12.53, 13.69, 14.32, 
                    10.35, 15.87, 11.71, 13.16, 14.96, 10.66, 7.05, 14.2, 15.35, 
                    14.31, 17.81, 11.28, 16.73, 17.44, 13.84, 15.83, 14.42, 12.51, 
                    8.77, 15.9, 19.89, 14.89, 10.9, 14.71, 13.31, 16.32, 12.64, 8.81, 
                    13.28, 12.2, 16.08, 10.3, 17.56, 18.79, 18.33, 17.77, 15.83, 
                    14.56, 13.91, 14.4, 14.22, 14.47, 13.98, 13.09, 11.45, 13.88, 
                    13.41, 8.96, 14.11, 9.99, 10.42, 11.4, 11.5), age = c(36L, 36L, 
                                                                          56L, 34L, 34L, 40L, 55L, 40L, 33L, 39L, 33L, 32L, 53L, 38L, 31L, 
                                                                          37L, 31L, 31L, 37L, 37L, 30L, 36L, 35L, 29L, 29L, 35L, 49L, 28L, 
                                                                          28L, 28L, 27L, 33L, 27L, 27L, 26L, 26L, 32L, 32L, 26L, 26L, 26L, 
                                                                          26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 26L, 31L, 31L, 31L, 25L, 
                                                                          25L, 25L, 31L, 25L, 30L, 38L, 38L, 38L, 24L, 24L, 38L, 37L, 37L, 
                                                                          37L, 37L, 23L, 43L, 36L, 22L, 28L, 27L, 42L, 42L, 42L, 41L, 41L, 
                                                                          34L, 34L, 34L, 26L, 33L, 33L, 33L, 33L, 31L, 31L, 37L, 28L, 27L, 
                                                                          26L, 32L, 31L, 30L, 30L, 30L, 29L, 28L, 28L, 27L, 40L, 39L, 32L, 
                                                                          32L, 32L, 32L, 31L, 52L, 44L, 37L, 37L, 37L, 37L, 37L, 30L, 30L, 
                                                                          29L, 29L, 29L, 28L, 28L, 28L, 28L, 28L, 28L, 34L, 34L, 41L, 34L, 
                                                                          27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 40L, 33L, 26L, 26L, 32L, 
                                                                          32L, 32L, 32L, 39L, 25L, 31L, 31L, 31L, 31L, 31L, 38L, 31L, 24L, 
                                                                          38L, 38L, 38L, 38L, 30L, 30L, 30L, 36L, 29L, 29L, 29L, 36L, 43L, 
                                                                          35L, 28L, 35L, 28L, 28L, 28L, 35L, 35L, 21L, 34L, 27L, 27L, 34L, 
                                                                          33L, 33L, 26L, 25L, 32L, 32L, 39L, 31L, 24L, 31L, 31L, 38L, 30L, 
                                                                          30L, 30L, 30L, 30L, 30L, 36L, 28L, 28L, 28L, 28L, 27L, 34L, 34L, 
                                                                          34L, 26L, 26L, 25L, 32L, 32L, 32L, 32L, 32L, 38L, 38L, 31L, 23L, 
                                                                          30L, 30L, 30L, 30L, 36L, 36L, 29L, 36L, 29L, 29L, 29L, 29L, 42L, 
                                                                          35L, 28L, 28L, 34L, 34L, 27L, 33L, 26L, 26L, 40L, 39L, 39L, 39L, 
                                                                          46L, 38L, 45L, 31L, 38L, 24L, 37L, 44L, 30L, 37L, 43L, 29L, 36L, 
                                                                          36L, 36L, 35L, 42L, 42L, 42L, 42L, 35L, 34L, 34L, 34L, 34L, 34L, 
                                                                          33L, 26L, 40L, 26L, 33L, 33L, 33L, 32L, 32L, 32L, 39L, 31L, 38L, 
                                                                          31L, 31L, 37L, 30L, 23L, 37L, 37L, 37L, 37L, 30L, 36L, 36L, 36L, 
                                                                          36L, 35L, 27L, 27L, 34L, 40L, 33L, 25L, 32L, 32L, 39L, 30L, 28L, 
                                                                          28L, 27L, 30L, 28L, 40L, 39L, 39L, 37L, 37L, 37L, 31L, 36L, 35L, 
                                                                          35L, 35L, 35L, 34L, 34L, 32L, 26L, 32L, 30L, 28L, 26L, 26L)))


nls(sl~a*exp(-b*exp(-k*age)),data=a,start=list(a=60,b=0.2,k=50)) 

Thank you for any help

Robert
  • 5,038
  • 1
  • 25
  • 43
Wave
  • 1,216
  • 1
  • 9
  • 22
  • a is the asymptote, here I would guess ~40, b is the displacement 0.2 seems to be to low, try 5 or 20, k is the steepness, your data does not look very steep, try something small ~0.1. – EDi Aug 05 '14 at 17:10
  • Than the error changes to "Missing value or an infinity produced when evaluating the model". So would it be possible there's simply no way to properly fit this model to this data? Maybe because the data is too linear? – Wave Aug 06 '14 at 06:51
  • 1
    Just play around a bit more. The model converges for me if I use some of @Edi's suggestions (`start=list(a=40, b=20, k=0.1)`). – aosmith Aug 06 '14 at 18:16
  • Sorry, I have to revise my comment. Yes, this give me some coefficients, but when I plot the curve, it's awefull. How can I get good estimations? plot(a$age, all.small$sl, pch=16, cex=0.3,ylim=c(0,30), ylab="SL (mm)", xlab="Age (days)", xlim=c(20,50)) ;gomp.new=curve(coef(gom)[1]*exp(-coef(gom)[2]*exp(x-coef(gom)[3])), from=2, to=55, add=T, lwd=2.5,col="blue") – Wave Aug 07 '14 at 14:55

1 Answers1

1

Try DE, even starting far away from your initials it converges to similar solution:

library(NMOF)
 yf= function(params,x){
   a=params[1];b=params[2];k=params[3]
   a*exp(-b*exp(-k*x))
   }

 algo5 <- list(printBar = FALSE,
               nP  = 200L,
               nG  = 1000L,
               F   = 0.50,
               CR  = 0.99,
               min = rep(-5,3),
               max = rep(5,3))

 OF2 <- function(Param, data) { 
   x <- data$x
   y <- data$y
   ye <- data$model(Param,x)
   aux <- y - ye; aux <- sum(aux^2)
   if (is.na(aux)) aux <- 1e10
   aux
 }

 data5 <- list(x = a$age, y = a$sl,  model = yf, ww = 1)
 system.time(sol5 <- DEopt(OF = OF2, algo = algo5, data = data5))
 sol5$xbest
 OF2(sol5$xbest,data5)

plot(a$age, a$sl, pch=16, cex=0.3,ylim=c(0,30), ylab="SL (mm)", xlab="Age (days)", xlim=c(1,80)) 
gomp.new=curve(yf(sol5$xbest,x), 1, 85, add=T, lwd=2.5,col="blue",n=1000)

#>  sol5$xbest
#[1] 37.49220109  3.50998966  0.03758578

enter image description here

Robert
  • 5,038
  • 1
  • 25
  • 43