Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error with nlme

Tags:

r

For IGF data from nlme library, I'm getting this error message:

lme(conc ~ 1, data=IGF, random=~age|Lot)
Error in lme.formula(conc ~ 1, data = IGF, random = ~age | Lot) : 
  nlminb problem, convergence error code = 1
  message = iteration limit reached without convergence (10)

But everything is fine with this code

lme(conc ~ age, data=IGF)
Linear mixed-effects model fit by REML
  Data: IGF 
  Log-restricted-likelihood: -297.1831
  Fixed: conc ~ age 
 (Intercept)          age 
 5.374974367 -0.002535021 

Random effects:
 Formula: ~age | Lot
 Structure: General positive-definite
            StdDev      Corr  
(Intercept) 0.082512196 (Intr)
age         0.008092173 -1    
Residual    0.820627711       

Number of Observations: 237
Number of Groups: 10 

As IGF is groupedData, so both codes are identical. I'm confused why the first code produces error. Thanks for your time and help.

like image 283
MYaseen208 Avatar asked Oct 27 '11 22:10

MYaseen208


2 Answers

I find the other, older answer here unsatisfactory. I distinguish between cases where, statistically, age has no impact and conversely we encounter a computational error. Personally, I have made career mistakes by conflating these two cases. R has signaled the latter and I would like to dive into why that is.

The model that OP has specified is a growth model, with random slopes and intercepts. A grand intercept is included but not a grand age slope. One unsavory constraint that is imposed by fitting a random slope without addition of its "grand" term is that you are forcing the random slope to have 0 mean, which is very difficult to optimize. Marginal models indicate age does not have a statistically significant different value from 0 in the model. Furthermore adding age as a fixed effect does not remedy the problem.

> lme(conc~ age, random=~age|Lot, data=IGF)
Error in lme.formula(conc ~ age, random = ~age | Lot, data = IGF) : 
  nlminb problem, convergence error code = 1
  message = iteration limit reached without convergence (10)

Here the error is obvious. It might be tempting to set the number of iterations up. lmeControl has many iterative estimands. But even that doesn't work:

> fit <- lme(conc~ 1, random=~age|Lot, data=IGF, 
control = lmeControl(maxIter = 1e8, msMaxIter = 1e8))

Error in lme.formula(conc ~ 1, random = ~age | Lot, 
data = IGF, control = lmeControl(maxIter = 1e+08,  : 
  nlminb problem, convergence error code = 1
  message = singular convergence (7)

So it's not a precision thing, the optimizer is running out-of-bounds.

There must be key differences between the two models you have proposed fitting, and a way to diagnose the error that you have found. One simple approach is specifying a "verbose" fit for the problematic model:

> lme(conc~ 1, random=~age|Lot, data=IGF, control = lmeControl(msVerbose = TRUE))
  0:     602.96050:  2.63471  4.78706  141.598
  1:     602.85855:  3.09182  4.81754  141.597
  2:     602.85312:  3.12199  4.97587  141.598
  3:     602.83803:  3.23502  4.93514  141.598
   (truncated)
 48:     602.76219:  6.22172  4.81029  4211.89
 49:     602.76217:  6.26814  4.81000  4425.23
 50:     602.76216:  6.31630  4.80997  4638.57
 50:     602.76216:  6.31630  4.80997  4638.57

The first term is the REML (I think). The second through fourth terms are the parameters to an object called lmeSt of class lmeStructInt, lmeStruct, and modelStruct. If you use Rstudio's debugger to inspect attributes of this object (the lynchpin of the problem), you'll see it is the random effects component that explodes here. coef(lmeSt) after 50 iterations produces reStruct.Lot1 reStruct.Lot2 reStruct.Lot3 6.316295 4.809975 4638.570586

as seen above and produces

> coef(lmeSt, unconstrained = FALSE)

    reStruct.Lot.var((Intercept)) reStruct.Lot.cov(age,(Intercept)) 
                         306382.7                         2567534.6 
            reStruct.Lot.var(age) 
                       21531399.4 

which is the same as the

Browse[1]> lmeSt$reStruct$Lot
Positive definite matrix structure of class pdLogChol representing
            (Intercept)      age
(Intercept)    306382.7  2567535
age           2567534.6 21531399

So it's clear the covariance of the random effects is something that's exploding here for this particular optimizer. PORT routines in nlminb have been criticized for their uninformative errors. The text from David Gay (Bell Labs) is here http://ms.mcmaster.ca/~bolker/misc/port.pdf The PORT documentation suggests our error 7 from using a 1 billion iter max "x may have too many free components. See §5.". Rather than fix the algorithm, it behooves us to ask if there are approximate results which should generate similar outcomes. It is, for instance, easy to fit an lmList object to come up with the random intercept and random slope variance:

> fit <- lmList(conc ~ age | Lot, data=IGF)
> cov(coef(fit))
            (Intercept)          age
(Intercept)  0.13763699 -0.018609973
age         -0.01860997  0.003435819

although ideally these would be weighted by their respective precision weights:

To use the nlme package I note that unconstrained optimization using BFGS does not produce such an error and gives similar results:

> lme(conc ~ 1, data=IGF, random=~age|Lot, control = lmeControl(opt = 'optim'))
Linear mixed-effects model fit by REML
  Data: IGF 
  Log-restricted-likelihood: -292.9675
  Fixed: conc ~ 1 
(Intercept) 
   5.333577 

Random effects:
 Formula: ~age | Lot
 Structure: General positive-definite, Log-Cholesky parametrization
            StdDev      Corr  
(Intercept) 0.032109976 (Intr)
age         0.005647296 -0.698
Residual    0.820819785       

Number of Observations: 237
Number of Groups: 10 

An alternative syntactical declaration of such a model can be done with the MUCH easier lme4 package:

library(lme4)
lmer(conc ~ 1 + (age | Lot), data=IGF)

which yields:

> lmer(conc ~ 1 + (age | Lot), data=IGF)
Linear mixed model fit by REML ['lmerMod']
Formula: conc ~ 1 + (age | Lot)
   Data: IGF
REML criterion at convergence: 585.7987
Random effects:
 Groups   Name        Std.Dev. Corr 
 Lot      (Intercept) 0.056254      
          age         0.006687 -1.00
 Residual             0.820609      
Number of obs: 237, groups:  Lot, 10
Fixed Effects:
(Intercept)  
      5.331 

An attribute of lmer and its optimizer is that random effects correlations which are very close to 1, 0, or -1 are simply set to those values since it simplifies the optimization (and statistical efficiency of the estimation) substantially.

Taken together, this does not suggest that age does not have an effect, as was said earlier, and this argument can be supported by the numeric results.

like image 149
AdamO Avatar answered Nov 10 '22 08:11

AdamO


If you plot the data, you can see that there is no effect of age, so it seems strange to be trying to fit a random effect of age in spite of this. No wonder it is not converging.

library(nlme)
library(ggplot2)

dev.new(width=6, height=3)
qplot(age, conc, data=IGF) + facet_wrap(~Lot, nrow=2) + geom_smooth(method='lm')

enter image description here

I think what you want to do is model a random effect of Lot on the intercept. We can try including age as a fixed effect, but we'll see that it is not significant and can be thrown out:

> summary(lme(conc ~ 1 + age, data=IGF, random=~1|Lot))
Linear mixed-effects model fit by REML
 Data: IGF 
       AIC      BIC    logLik
  604.8711 618.7094 -298.4355

Random effects:
 Formula: ~1 | Lot
        (Intercept) Residual
StdDev:  0.07153912 0.829998

Fixed effects: conc ~ 1 + age 
                Value  Std.Error  DF  t-value p-value
(Intercept)  5.354435 0.10619982 226 50.41849  0.0000
age         -0.000817 0.00396984 226 -0.20587  0.8371
 Correlation: 
    (Intr)
age -0.828

Standardized Within-Group Residuals:
        Min          Q1         Med          Q3         Max 
-5.46774548 -0.43073893 -0.01519143  0.30336310  5.28952876 

Number of Observations: 237
Number of Groups: 10 
like image 20
John Colby Avatar answered Nov 10 '22 08:11

John Colby