从lme4 mer模型对象中提取随机效应方差

54

我有一个mer对象,其中包含固定效应和随机效应。如何提取随机效应的方差估计值?以下是我问题的简化版本。

study <- lmer(Reaction ~ Days + (1|Subject), data = sleepstudy)
study

这会产生很长的输出 - 在这种情况下不算太长。无论如何,我该如何明确选择

Random effects:
Groups   Name        Variance Std.Dev.
Subject  (Intercept) 1378.18  37.124  
Residual              960.46  30.991  

输出的一部分?我想要这些值本身。

我已经仔细查看了

str(study)

然而什么都没有!我也检查了lme4包中的任何提取函数,但无济于事。请帮忙!

7个回答

89

其他回答中的一些方法是可行的,但我认为最好的方法是使用专门设计用于此目的的访问器方法--VarCorr(这与lme4的前身nlme包中的方法相同)。

更新 在最近版本的lme4(版本1.1-7,但以下所有内容可能适用于版本> = 1.0),VarCorr比以前更灵活,并且应该能够满足您的所有需求,而无需查找拟合模型对象的内部细节。

library(lme4)
study <- lmer(Reaction ~ Days + (1|Subject), data = sleepstudy)
VarCorr(study)
##  Groups   Name        Std.Dev.
##  Subject  (Intercept) 37.124  
##  Residual             30.991

默认情况下,VarCorr()打印标准差,但是如果您愿意,可以获取方差:

print(VarCorr(study),comp="Variance")
##  Groups   Name        Variance
##  Subject  (Intercept) 1378.18 
##  Residual              960.46 

(comp=c("Variance","Std.Dev.")将打印两者)。

为了更灵活地使用,您可以使用as.data.frame方法转换VarCorr对象,该对象给出了分组变量、效应变量和方差/协方差或标准偏差/相关性:

as.data.frame(VarCorr(study))
##        grp        var1 var2      vcov    sdcor
## 1  Subject (Intercept) <NA> 1378.1785 37.12383
## 2 Residual        <NA> <NA>  960.4566 30.99123

最后,VarCorr对象的原始形式(如果没有必要,您应该不要更改它)是一个方差-协方差矩阵列表,其中还有额外的(冗余的)信息编码标准偏差和相关性,以及属性("sc")提供残差标准偏差,并指定模型是否具有估计的比例参数("useSc")。

unclass(VarCorr(fm1))
## $Subject
##             (Intercept)      Days
## (Intercept)  612.089748  9.604335
## Days           9.604335 35.071662
## attr(,"stddev")
## (Intercept)        Days 
##   24.740448    5.922133 
## attr(,"correlation")
##             (Intercept)       Days
## (Intercept)  1.00000000 0.06555134
## Days         0.06555134 1.00000000
## 
## attr(,"sc")
## [1] 25.59182
## attr(,"useSc")
## [1] TRUE
## 

VarCorr似乎只提供标准偏差而不是方差估计,这通常是人们想要报告的内容,对吗? - user1320502
4
(1) 将标准差平方相当容易; (2) print(VarCorr(fitted_model),comp="Variance") 或者 as.data.frame(VarCorr(fitted_model)) 可以轻松获取方差; (3) 报告方差或标准差取决于上下文 -- 如果尝试思考方差分解/比例解释,我通常更喜欢报告方差,如果试图与固定效应的量级进行比较,则选择标准差。 - Ben Bolker
1
谢谢你的评论,Ben。非常有帮助! - user1320502

15

lmer返回一个S4对象,因此这应该可以工作:

remat <- summary(study)@REmat
print(remat, quote=FALSE)

输出结果为:

 Groups   Name        Variance Std.Dev.
 Subject  (Intercept) 1378.18  37.124  
 Residual              960.46  30.991  

一般来说,您可以查看“mer”对象的printsummary方法的源代码:

class(study) # mer
selectMethod("print", "mer")
selectMethod("summary", "mer")

6
如果你想要获取值,那么VarCorr()函数会更加有效率。建议查看Ben Bolker的帖子。 - Thierry
2
这个内容现在有点过时了(尽管原问题确实涉及“mer objects”,这些对象定义与1.0之前的lme4相关--该类现在称为merMod)。 - Ben Bolker

5
> attributes(summary(study))$REmat
 Groups     Name          Variance  Std.Dev.
 "Subject"  "(Intercept)" "1378.18" "37.124"
 "Residual" ""            " 960.46" "30.991"

3
可能我说的不对,但是在attributes(summary(study))中似乎不再有REmat了。 - blazej

1

1
另一个可能性是:
sum <- summary (study)
var <- data.frame (sum$varcor)

1
这个答案很大程度上基于@Ben Bolker的答案,但如果人们是新手并想要值本身,而不仅仅是值的打印输出(似乎OP想要的是这样),那么可以按以下方式提取值:
VarCorr对象转换为数据框。
re_dat = as.data.frame(VarCorr(study))

然后访问每个单独的值:
int_vcov = re_dat[1,'vcov']
resid_vcov = re_dat[2,'vcov']

通过这种方法(在您创建的数据框中指定行和列),您可以访问任何想要的值。

-9

尝试一下

attributes(study)

举个例子:

> women
   height weight
1      58    115
2      59    117
3      60    120
4      61    123
5      62    126
6      63    129
7      64    132
8      65    135
9      66    139
10     67    142
11     68    146
12     69    150
13     70    154
14     71    159
15     72    164

> lm1 <- lm(height ~ weight, data=women)
> attributes(lm1)
$names
 [1] "coefficients"  "residuals"     "effects"       "rank"         
 [5] "fitted.values" "assign"        "qr"            "df.residual"  
 [9] "xlevels"       "call"          "terms"         "model"        

$class
[1] "lm"

> lm1$coefficients
(Intercept)      weight 
 25.7234557   0.2872492 

> lm1$coefficients[[1]]

[1] 25.72346


> lm1$coefficients[[2]]

[1] 0.2872492

结束。


3
抱歉,您的代码使用了 lm(),但问题是关于 lmer() 的,它们并不是同一件事。 - Dirk Eddelbuettel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接