问题
In my below code, I was wondering how I can obtain the equivalent of out
and Ts
from an lme()
object in the library(nlme)
?
dat <- read.csv("https://raw.githubusercontent.com/rnorouzian/v/main/mv.l.csv")
library(lme4)
x <- lmer(value ~0 + name+ (1| School/Student), data = dat,
control = lmerControl(check.nobs.vs.nRE= "ignore"))
lwr <- getME(x, "lower")
theta <- getME(x, "theta")
out = any(theta[lwr == 0] < 1e-4) # find this from `x1` object below
Ts = getME(x, "Tlist") # find this from `x1` object below
# Fitting the above model using `library(nlme)`:
library(nlme)
x1 <- lme(value ~0 + name, random = ~1| School/Student, data = dat)
回答1:
I would strongly suggest reading the docs! lme4 and nlme use inherently different methods for fitting mixed models -- lme4 uses a penalized least-squares formulation based on the lower Cholesky factor (theta) and nlme4 uses a generalized least-squares formulation that can optionally be stored as a Cholesky factor -- but their docs give you the information to get what you need from the internal representation. After that, it's up to you to do the math to convert between the representations.
If you do ?lme
then there is the line
See
lmeObject
for the components of the fit
Then you do ?lmeObject
, where you find two promising entries:
apVar
an approximate covariance matrix for the variance-covariance coefficients. IfapVar = FALSE
in the control values used in the call tolme
, this component isNULL
.
and
modelStruct
an object inheriting from classlmeStruct
, representing a list of mixed-effects model components, such asreStruct
,corStruct
, andvarFunc
objects.
Well, we don't actually want the var-cov coefficients, but rather the random effects matrices. So we can look at reStruct
. That is a lot more flexible in nlme than lme4, but it's generally just the random effects matrices. To do anything comparable to lme4, you need to transform those to their lower Cholesky factor. Here's an example using the sleepstudy
data:
> library("nlme")
> library("lme4")
>
> data("sleepstudy")
> m_nlme <- lme(fixed=Reaction ~ 1 + Days,
+ random=~ 1 + Days | Subject,
+ data=sleepstudy,
+ method = "ML")
> m_lme4 <- lmer(Reaction ~ 1 + Days + (1 + Days|Subject),
+ data=sleepstudy,
+ REML=FALSE)
>
> re_lme4 <- getME(m_lme4, "Tlist")$Subject
> print(re_lme4)
[,1] [,2]
[1,] 0.92919061 0.0000000
[2,] 0.01816575 0.2226432
>
> re_nlme <- m_nlme$modelStruct$reStruct$Subject
> # entire covariance matrix
> print(re_nlme)
Positive definite matrix structure of class pdLogChol representing
(Intercept) Days
(Intercept) 0.86344433 0.01688228
Days 0.01688228 0.04990040
> # get the lower cholesky factor
> re_nlme <- t(chol(re_nlme)) # could also use pdMatrix(re_nlme, TRUE)
> print(re_nlme)
(Intercept) Days
(Intercept) 0.92921705 0.0000000
Days 0.01816829 0.2226439
The theta vector for lme4 is just a row-major representation of the lower triangle of the lower Cholesky factor for a given grouping variable. (For models with multiple grouping variables, you just concatenate these together.) The lower Cholesky factor is constrained to not have entries smaller than zero on the diagonal (because that would correspond to a negative variance), and otherwise not constrained. In other words, diagonal entries get a a lower bound at 0, all other entries get a lower bound at -Inf.
So, in lme4:
> re_lme4[lower.tri(re_lme4,diag = TRUE)]
[1] 0.92919061 0.01816575 0.22264321
> getME(m_lme4, "theta")
Subject.(Intercept) Subject.Days.(Intercept) Subject.Days
0.92919061 0.01816575 0.22264321
> getME(m_lme4, "lower")
[1] 0 -Inf 0
We can implement this for nlme (not the most efficient way, but it shows how things are built up):
> lowerbd <- function(x){
+ dd <- diag(0, nrow=nrow(x))
+ dd[lower.tri(dd)] <- -Inf
+ dd[lower.tri(dd, diag=TRUE)]
+ }
> lowerbd(re_nlme)
[1] 0 -Inf 0
> lowerbd(re_lme4)
[1] 0 -Inf 0
Note that this is one spot where nlme is actually more powerful than lme4: the whole pdMatrix
set of restrictions can create different lower bounds for different entries (as well as e.g. constrain the relationship between entries).
来源:https://stackoverflow.com/questions/66017374/obtaining-random-effects-matrices-from-a-mixed-model