使用R中的confint计算固定效应的CI

时间:2014-10-28 16:27:01

标签: r lme4

我想在二项式GLMM中执行自举以获得95%Cis的固定效果:

m <- glmer(cbind(df$Valid.detections, df$Missed.detections) ~ distance + 
              Habitat + Replicate + transmitter.depth + receiver.depth + 
              wind.speed + wtc + Transmitter + (1 | Unit) + 
              (1 | SUR.ID) + distance:Transmitter + 
              distance:Habitat + distance:transmitter.depth + distance:receiver.depth + 
              distance:wind.speed, data = df, family = binomial(link=logit),control=glmerControl(calc.derivs=F))

我发现confint()函数能够实现这一点,所以我指定了函数:

confint(m, method = "boot", boot.type = "basic", seed = 123, nsim = 1000)

在我决定终止之前,该功能已运行超过8小时。终止后,我收到了以下警告信息(x10):

Warning messages:
1: In (function (fn, par, lower = rep.int(-Inf, n), upper = rep.int(Inf,  :
  failure to converge in 10000 evaluations

我的问题是:1)我是否需要担心这些警告信息?如果是这样,我怎么能处理它们?,2)因为8小时后它还在运行我不知道执行这个功能需要多长时间。因此,在执行此功能时有一些进度条会很好。我读到confint()可以从bootMer获取参数,所以我包含了参数.progress =“txt”,结果是:

confint(m, method = "boot", boot.type = "basic", seed = 123, nsim = 1000, .progress = "txt")

但它似乎不起作用。或者,如果有更好的方法来实现相同的目标,我愿意接受建议。

感谢您的帮助

1 个答案:

答案 0 :(得分:3)

以下是一个例子:

library("lme4")
(t1 <- system.time(
    gm1 <- glmer(cbind(incidence, size - incidence) ~ period + (1 | herd),
                 data = cbpp, family = binomial)))
##    user  system elapsed 
##   0.188   0.000   0.186

nranpars <- length(getME(gm1,"theta"))
nfixpars <- length(fixef(gm1))

(t2 <- system.time(c1 <- confint(gm1,method="boot", nsim=1000,
                  parm=(nranpars+1):(nranpars+nfixpars),
                  .progress="txt")))

##    user  system elapsed 
## 221.958   0.164 222.187

请注意,此进度条的长度仅为80个字符,因此仅在每次1000/80 = 12次自举迭代后才会递增。如果您的原始模型需要一个小时才能适应,那么您不应期望在12小时之后看到任何进度条活动...

(t3 <- system.time(c2 <- confint(gm1,
                  parm=(nranpars+1):(nranpars+nfixpars))))

##    user  system elapsed 
##   5.212   0.012   5.236 

1000个bootstrap reps可能有点过分 - 如果你的模型很慢,你可以从200个bootstrap reps中获得合理的 CI。

我也尝试使用optimizer="nloptwrap",希望能加快速度。虽然有一个缺点(见下文),但确实如此。

(t4 <- system.time(
    gm1B <- glmer(cbind(incidence, size - incidence) ~ period + (1 | herd),
                 data = cbpp, family = binomial, 
                 control=glmerControl(optimizer="nloptwrap"))))
##   user  system elapsed 
##  0.064   0.008   0.075 

(t5 <- system.time(c3 <- confint(gm1B,method="boot", nsim=1000,
                  parm=(nranpars+1):(nranpars+nfixpars),
                  .progress="txt",PBargs=list(style=3))))
##
##   user  system elapsed 
## 65.264   2.160  67.504

这个更快,会发出警告(本例中为37) 收敛。根据{{​​1}},以这种方式计算的置信区间只有大约2%的差异。 (在包装本身中仍然有一些皱纹......)

加快这项工作的最佳选择是并行化 - 不幸的是,这样你就失去了使用进度条的能力......

all.equal()

这需要更多用户时间(它计算所有核心上使用的时间),但经过的时间减半。 (用4个内核做得更好,但速度快两倍仍然不错。这些是虚拟Linux机器上的虚拟内核,真实(非虚拟)内核可能有更好的性能。)

(t6 <- system.time(c4 <- confint(gm1,method="boot", nsim=1000, parm=(nranpars+1):(nranpars+nfixpars), parallel="multicore", ncpus=4))) ## ## user system elapsed ## 310.355 0.916 116.917 和多核组合后,我可以将时间缩短到91秒(用户)/ 36秒(已过去)。