为什么 SAS PROC GLIMMIX 给我的随机斜率与二项式 glmm 的 glmer (lme4) 非常不同

机器算法验证 r 二项分布 sas 随机效应模型 lme4-nlme
2022-03-25 19:45:51

我是一个更熟悉 R 的用户,并且一直试图在 5 年内为四个栖息地变量估计大约 35 个人的随机斜率(选择系数)。响应变量是位置是“使用”(1) 还是“可用”(0) 栖息地(以下“使用”)。

我使用的是 Windows 64 位计算机。

在 R 版本 3.1.0 中,我使用下面的数据和表达式。PS、TH、RS 和 HW 是固定效应(标准化、测量到栖息地类型的距离)。lme4 V 1.1-7。

str(dat)
'data.frame':   359756 obs. of  7 variables:
 $ use     : num  1 1 1 1 1 1 1 1 1 1 ...
 $ Year    : Factor w/ 5 levels "1","2","3","4",..: 4 4 4 4 4 4 4 4 3 4 ...
 $ ID      : num  306 306 306 306 306 306 306 306 162 306 ...
 $ PS: num  -0.32 -0.317 -0.317 -0.318 -0.317 ...
 $ TH: num  -0.211 -0.211 -0.211 -0.213 -0.22 ...
 $ RS: num  -0.337 -0.337 -0.337 -0.337 -0.337 ...
 $ HW: num  -0.0258 -0.19 -0.19 -0.19 -0.4561 ...

glmer(use ~  PS + TH + RS + HW +
     (1 + PS + TH + RS + HW |ID/Year),
     family = binomial, data = dat, control=glmerControl(optimizer="bobyqa"))

glmer 为我提供了对我有意义的固定效应的参数估计,当我对数据进行定性调查时,随机斜率(我将其解释为每种栖息地类型的选择系数)也有意义。该模型的对数似然为 -3050.8。

然而,大多数动物生态学研究不使用 R,因为对于动物位置数据,空间自相关会使标准错误容易出现 I 类错误。虽然 R 使用基于模型的标准误差,但首选经验(也是 Huber-white 或三明治)标准误差。

虽然 R 目前不提供此选项(据我所知 - 请纠正我,如果我错了),SAS 提供 - 虽然我无法访问 SAS,但一位同事同意让我借用他的计算机以确定标准错误使用经验方法时发生显着变化。

首先,我们希望确保在使用基于模型的标准误差时,SAS 会产生与 R 相似的估计值——以确保在两个程序中以相同的方式指定模型。我不在乎它们是否完全相同 - 只是相似。我试过(SAS V 9.2):

proc glimmix data=dat method=laplace;
   class year id;
   model use =  PS TH RS HW / dist=bin solution ddfm=betwithin;
   random intercept PS TH RS HW / subject = year(id) solution type=UN;
run;title;

我还尝试了其他各种形式,例如添加线条

random intercept / subject = year(id) solution type=UN;
random intercept PS TH RS HW / subject = id solution type=UN;

我试过没有指定

solution type = UN,

或注释掉

ddfm=betwithin;

无论我们如何指定模型(并且我们尝试了很多方法),我都无法让 SAS 中的随机斜率与 R 的输出很相似——即使固定效果足够相似。当我的意思是不同时,我的意思是甚至符号都不相同。SAS 中的 -2 对数似然是 71344.94。

我无法上传完整的数据集;所以我做了一个玩具数据集,只有三个人的记录。SAS 在几分钟内给我输出;在 R 中需要一个多小时。奇怪的。有了这个玩具数据集,我现在得到了对固定效应的不同估计。

我的问题:谁能解释为什么 R 和 SAS 之间的随机斜率估计可能如此不同?我可以在 R 或 SAS 中做些什么来修改我的代码,以便调用产生类似的结果?我宁愿更改 SAS 中的代码,因为我“相信”我的 R 估计更多。

我真的很关心这些差异,并想深入了解这个问题!

我的玩具数据集的输出仅使用了 R 和 SAS 的完整数据集中 35 个人中的三个,被包含为 jpeg。

R输出 SAS 输出 1 SAS 输出 2 SAS 输出 3


编辑和更新:

正如@JakeWestfall 帮助发现的那样,SAS 中的斜率不包括固定效应。当我添加固定效果时,结果如下 - 将 R 斜率与 SAS 斜率进行比较,以获得程序之间的一个固定效果“PS”:(选择系数 = 随机斜率)。请注意 SAS 中增加的变化。

R 与 SAS 的 PS

2个回答

根据 Zhang et al 2011 的说法,我似乎不应该期望包之间的随机斜率相似。在他们的论文On Fitting Generalized Linear Mixed-effects Models for Binary Responses using different Statistical Packages中,他们描述了:

抽象的:

广义线性混合效应模型 (GLMM) 是将横截面数据模型扩展到纵向设置的流行范式。当应用于建模二进制响应时,不同的软件包,甚至一个包中的不同程序可能会给出完全不同的结果。在本报告中,我们描述了这些不同程序背后的统计方法,并讨论了它们在应用于拟合相关二元响应时的优势和劣势。然后,我们通过将在一些流行的软件包中实现的这些程序应用于模拟和真实研究数据来说明这些考虑因素。我们的模拟结果表明,所考虑的大多数程序都缺乏可靠性,这对在实践中应用此类流行的软件包具有重要意义。

我希望@BenBolker 和团队将我的问题视为对 R 的投票,以将经验标准误差和 Gauss-Hermite 正交能力用于具有多个随机斜率项的模型与 glmer 相结合,因为我更喜欢 R 接口并且希望能够应用该程序中的一些进一步分析。令人高兴的是,即使 R 和 SAS 没有可比的随机斜率值,但总体趋势是相同的。感谢大家的投入,我非常感谢您为此付出的时间和考虑!

答案和评论/更多问题的混合:

我为“玩具”数据集安装了三种不同的优化器选择。(*注 1:对于比较目的,通过从每年和 id 内进行二次抽样而不是通过对分组变量进行二次抽样来制作一个小数据集可能更有用。事实上,我们知道 GLMM 不会执行特别适合这么少的分组变量级别。您可以通过以下方式执行此操作:

library(plyr)
subdata <- ddply(fulldata,c("year","id"),
    function(x) x[sample(nrow(x),size=round(nrow(x)*0.1)),])

批量拟合代码:

Ntoy <- readRDS("Newton_toy.RDS")
library(lme4)
fitfun <- function(opt) {
    tt <- system.time(fit1 <- glmer(use ~  ps + th + rs + hw +
                                    (1 + ps + th + rs + hw |id/year),
                                    family = binomial, data = Ntoy,
                                    control=glmerControl(optimizer=opt),
                                    verbose=100))
    return(list(time=tt,fit=fit1))
}

opts <- c("nloptwrap","nlminbwrap","bobyqa")
## use for() instead of lapply so we can checkpoint more easily
res <- setNames(vector("list",length(opts)),opts)
for (i in opts) {
    res[[i]] <- fitfun(i)
    save("res",file="Newton_batch.RData")
}

然后我在一个新会话中读取结果:

load("Newton_batch.RData")
library(lme4)

经过的时间和偏差:

cbind(time=unname(sapply(res,function(x) x$time["elapsed"])),
          dev=sapply(res,function(x) deviance(x$fit)))
##                time      dev
## nloptwrap  1001.824 6067.706
## nlminbwrap 3495.671 6068.730
## bobyqa     4945.332 6068.731

这些偏差远低于 OP 从 R (6101.7) 报告的偏差,略低于 OP 从 SAS (6078.9) 报告的偏差,尽管比较不同包之间的偏差并不总是明智的。

SAS 只在大约 100 个函数评估中收敛,我确实感到惊讶!

Macbook Pro 上的时间范围从 17 分钟 ( nloptwrap) 到 80 分钟 ( bobyqa),与 OP 的经验一致。偏差对nloptwrap.

round(cbind(sapply(res,function(x) fixef(x$fit))),3)
##             nloptwrap nlminbwrap bobyqa
## (Intercept)    -5.815     -5.322 -5.322
## ps             -0.989      0.171  0.171
## th             -0.033     -1.342 -1.341
## rs              1.361     -0.140 -0.139
## hw             -2.100     -2.082 -2.082

答案似乎与nloptwrap-- 尽管标准误差很大......

round(coef(summary(res[[1]]$fit)),3)
##             Estimate Std. Error z value Pr(>|z|)
## (Intercept)   -5.815      0.750  -7.750    0.000
## ps            -0.989      1.275  -0.776    0.438
## th            -0.033      2.482  -0.013    0.989
## rs             1.361      2.799   0.486    0.627
## hw            -2.100      0.490  -4.283    0.000

year:id(这里的代码给出了一些关于我应该追踪的警告)

待续 ... ?