3
votes

The data in the following example are from here

library(tidyverse)
library(lme4)
dat <- read.table("aids.dat2",head=T) %>%
  filter(day <= 90) %>%
  mutate(log10copy = log10(lgcopy)) %>%
  na.omit()

> head(dat)
  patid day    cd4   lgcopy    cd8 log10copy
2 11542   2 159.84 4.361728 619.38 0.6396586
3 11542   7 210.60 3.531479 666.90 0.5479566
4 11542  16 204.12 2.977724 635.04 0.4738844
5 11542  29 172.48 2.643453 407.68 0.4221716
6 11542  57 270.94 2.113943 755.78 0.3250933
8 11960   2 324.72 3.380211 856.08 0.5289438

Running the following code gives me the error: Error in eval(expr, envir, enclos) : object 'log10copy' not found, but log10copy is clearly one of the columns in my data set?

lme4.fit <- lme4::nlmer(log10copy ~ exp(p1-b1*day) + exp(p2-b2*day + 1) + 
                          (1|p1) + (1|b1) + (1|p2) + (1|b2), data = dat)

I want to fit a model with 4 fixed effects on p1, b1, p2, b2 and 4 random effects on the same set of parameters.

1
The formula for nlmer should be a 3-part formula of the form resp ~ Nonlin ~ fixed + random. Also what are p1, p2, b1, b2? They are not in your example data. - neilfws
@neilfws p1, p2, b1 and b2 are my parameters - Adrian
@neilfws I updated my post with some new code (according to the syntax you suggested), but now I'm running into a different error.. - Adrian

1 Answers

3
votes

You have several problems here...

1) The starting values must be a named vector
2) the data argument in nlmer should receive dat as value and not aids.dat as in your example

start <- c(p1 = 10, b1 = 0.5, p2 = 6, b2 = 0.005)
lme4.fit <- lme4::nlmer(log10copy ~ exp(p1-b1*day) + exp(p2-b2*day + 1) ~ 
                            (p1|patid) + (b1|patid) + (p2|patid) + (b2|patid), data = dat,
                        start = start)

This will now trigger the following error :

Erreur : is.matrix(gr <- attr(val, "gradient")) is not TRUE

As explained in the documentation :

Currently, the Nonlin(..) formula part must not only return a numeric vector, but also must have a "gradient" attribute, a matrix. The functions SSbiexp, SSlogis, etc, see selfStart, provide this (and more). Alternatively, you can use deriv() to automatically produce such functions or expressions.

You can then adapt the example provided by the documentation :

## a. Define formula
nform <- ~ exp(p1-b1*input) + exp(p2-b2*input + 1)
## b. Use deriv() to construct function:
nfun <- deriv(nform, namevec=c("p1", "b1", "p2", "b2"),
              function.arg=c("input","p1", "b1", "p2", "b2"))
lme4.fit <- lme4::nlmer(log10copy ~ nfun(day, p1, b1, p2, b2) ~ 
                            (p1|patid) + (b1|patid) + (p2|patid) + (b2|patid), data = dat,
                        start = start)

You will then have the following error

Error in fn(nM$xeval()) : prss failed to converge in 300 iterations

This might mean that your model is too complex for your data... Or maybe I did a mistake in the specification as I' don't know nlmer very well (I just tried to apply the documentation...) nor do I know your model/question.

When you change the optimizer, the convergence problems seem to be gone...
See here for recommendations about "troubleshooting" (including convergence problems) with lme4

lme4.fit <- lme4::nlmer(log10copy ~ nfun(day, p1, b1, p2, b2) ~ 
                            (p1|patid) + (b1|patid) + 
                            (p2|patid) + (b2|patid), 
                        data = dat,
                        start = start, 
                        nlmerControl(optimizer = "bobyqa"))