[R-sig-ME] Formula and Start-values for simplest "non-linear" mixed model - nlmer (nlme??, lmer ?)

Ben Bolker bbolker at gmail.com
Tue Jan 21 05:22:40 CET 2014


   Here's a start (I hope) -- new examples for nlmer ...  for the naming
issue, I would consider brute force:  R has a feature that often annoys
me that the names of vectors get carried along ...


> x <- c(a=1,b=2)
> y <- c(a=x[1])
> y
a.a
  1

instead try y<-c(a=unname(x[1]))


> y
a
1

## nonlinear mixed models --- 3-part formulas ---
## 1. basic nonlinear fit. Use stats::SSlogis for its
## implementation of the 3-parameter logistic curve.
## "SS" stands for "self-starting logistic", but the
## "self-starting" part is not currently used by nlmer ... 'start' is
## necessary
startvec <- c(Asym = 200, xmid = 725, scal = 350)
(nm1 <- nlmer(circumference ~ SSlogis(age, Asym, xmid, scal) ~ Asym|Tree,
             Orange, start = startvec))
## 2. re-run with "quick and dirty" PIRLS step
(nm1a <- update(nm1, nAGQ = 0L))
## 3. Fit the same model with a user-built function:
## a. Define formula
nform <- ~Asym/(1+exp((xmid-input)/scal))
## b. Use deriv() to construct function:
nfun <- deriv(nform,namevec=c("Asym","xmid","scal"),
              function.arg=c("input","Asym","xmid","scal"))
nm1b <- update(nm1,circumference ~ nfun(age, Asym, xmid, scal)  ~ Asym |
Tree)
## 4. User-built function without using derivs():
##    derivatives could be computed more efficiently
##    by pre-computing components, but these are essentially
##    the gradients as one would derive them by hand
nfun2 <- function(input, Asym, xmid, scal) {
    value <- Asym/(1+exp((xmid-input)/scal))
    grad <- cbind(Asym=1/(1+exp((xmid-input)/scal)),
              xmid=-Asym/(1+exp((xmid-input)/scal))^2*1/scal*
                    exp((xmid-input)/scal),
              scal=-Asym/(1+exp((xmid-input)/scal))^2*
                     -(xmid-input)/scal^2*exp((xmid-input)/scal))
    attr(value,"gradient") <- grad
    value
}
stopifnot(all.equal(attr(nfun(2,1,3,4),"gradient"),
                    attr(nfun(2,1,3,4),"gradient")))
nm1c <- update(nm1,circumference ~ nfun2(age, Asym, xmid, scal)  ~ Asym
| Tree)

On 14-01-16 01:01 PM, Robert Chatfield wrote:
> Hi, Ben.  There's been no response yet to the question about nlmer.   
> Could you start me off with  an answer to the question of how to send
> start values   start.vals=    as a named vector?  
> 
> It's fine to take the answer on the list.
> 
> 
> (NOTE: It does not seem to work to look for the usual  y intercepts by running the problem "backwards"
> as a multiple regression of a single tracer-variable versus many species.type concentrations
> (y[ ij ] == a[ i ] *( + {x^o}[ j ]  
> x[j]  = alpha(i) * y[ij] + x^o[j]  
> since there is an "exact" but trivial solution x^0[j] = x[j]  ... 
> 
> Two questions ... 
> ======================================================================================
> Mostly: (1)
> I could not convince nlmer that the the starting values were vectors ... perhaps this is
> elementary R
> start.vals.1 = c(a=aij, x.nought=x.nought.lin)    (SEE VALUES BELOW)
> #   start.vals.1 = cbind(a=aij, x.nought=x.nought.lin)  # tried this -- does not work
> 
> where this calculation for aij
> len.lon.dat = dim(good.est.merge.long.dat)[1]   #  repeats once for each species.type
> len.lon.dat = dim(good.est.merge.long.dat)[1]   #  repeats once for each species.type 
> 
> aij = vector(mode="numeric",length= len.lon.dat)
> #  The name aij is given since
> for ( i in 1:len.lon.dat ) {
> spec.type.nm = as.character(species.type[i])
> aij[i] = (ranef(try.spec.2.lmer,drop=T)[["species.type"]])[[spec.type.nm]]
> }
> 
> 
>  I've been using c( , ) but I'm wondering
> if nlmer expects the results that occur for a vector of start.vals
> 
> I am wondering if the names are not being passed along correctly ...
>> names(start.vals.1)[1]
> [1] "a1"
>> start.vals.1[1]
>       a1 
> 0.002266363 
>> start.vals.1[1802]
>    a1802 
> -0.02694557 
>> start.vals.1[1803]
> x.nought1 
> -0.3141149 
>> start.vals.1[3604]
> x.nought1802 
> -0.1204595 
> Could this naming be confusing to nlmer?  The start values must be named.
> 
> == from a follow-up post ====  "not all parameter names"  meaning?
> 
>  first.nlmer = nlmer( y ~ a*(x+ x.nought) ~ (a|species.type) + (x.nought|id),
> 
> +      start=start.vals.1,  data=good.est.merge.long.dat  )
> Error in nlmer(y ~ a * (x + x.nought) ~ (a | species.type) + (x.nought |  : 
>   not all parameter names are used in the nonlinear model expression
> 
> where named list is given by ...
>>
>  start.vals.1 = c(a=aij, x.nought=C.nought.lin)
> 
>>
>  start.vals.1[1]
> 
>          a1 
> 0.002266363 
>>
>  start.vals.1[3604]
> 
> x.nought1802 
>   -0.1204595 
> 
> Using single values with a single name also does not work, nor does a construct
> with cbind:
> 
>>
>  first.nlmer = nlmer( y ~ a*(x+ x.nought) ~ (a|species.type) + (x.nought|id),
> 
> +      start=c(a=0.00364901,x.nought=0),  data=good.est.merge.long.dat  )
> Error in nlmer(y ~ a * (x + x.nought) ~ (a | species.type) + (x.nought |  : 
>   gradient attribute of evaluated model must be a numeric matrix
> 
> Bob Chatfield
> 
>



More information about the R-sig-mixed-models mailing list