当包装在函数中时,lme4 allFit()给出令人困惑的结果

时间:2019-07-04 19:58:59

标签: r lme4

我正在lme4中使用allFit()自动扫描可能的优化器,因为在这种情况下默认优化器通常不会收敛。当我运行it line-by-line时,我的代码工作正常,但是当我将其包装在一个简单的函数中运行时,它会给出不同的结果。

我已经查看了allFit调用的输出,似乎当它不在函数内部时,它会根据需要返回lmerModLmerTest对象的列表。

但是,在函数内部,它返回一个列表,其中包含值simpleErrorerrorcondition。为什么要这样做?

我正在使用RStudio,R 3.6,lme4 1.1-21,lmerTest 3.1-0。

更新:问题在于,重新拟合模型时,allFit使用的update()方法无法找到“ tt”数据框。我在代码中添加了断点,但是似乎“测试”数据存在于函数环境中,所以我不明白为什么找不到它...

更新2:看来,如果我将测试数据的分配更改为<<-,它就可以工作。但是,这很危险,因为它破坏了函数式编程,并且我认为在尝试并行化时可能会失败。我正在进一步测试...仍然可以接受建议!

这是起作用的代码,而不是函数内部:

library(lme4)

multi_arm_var_sim <- function(nsub = 20, nclust = 100, narm = 2, iccs = c(.01, .04), betas = c(0,.3)){
  sig_b2 <- -1*iccs / (iccs - 1)
  n <- nsub * nclust * narm
  y <- rep_len(NA, n)
  arm <- as.factor(rep(0:(narm-1), each = nsub*nclust))
  clustid <- rep(1:(nclust*narm), each = nsub)
  clustRElist <- rnorm(narm*nclust, mean = 0, sd = rep(sqrt(sig_b2), each = nclust))
  clustRE <- rep(clustRElist, each = nsub)
  sig_b2 <- rep(sig_b2, each = nclust*nsub)
  error <- rnorm(n, mean = 0, sd = 1)
  beta <- rep(betas, each = nclust*nsub)
  linpred <- beta + clustRE + error
  output <- cbind.data.frame(arm, clustid, sig_b2, clustRE, linpred)
  return(output)
}

set.seed(2)
test_1 <- multi_arm_var_sim()
model_flex_1 <- lmer(linpred ~ arm + (1 + arm | clustid),
                             data = test_1)

diff_optims_1 <- allFit(model_flex_1, verbose = TRUE)
print(class(diff_optims_1[[1]]))
is.OK_1 <- sapply(diff_optims_1, is, "lmerMod")
print(is.OK_1)

这是不起作用的代码,相同的设置,包装在一个函数中。

library(lme4)

multi_arm_var_sim <- function(nsub = 20, nclust = 100, narm = 2, iccs = c(.01, .04), betas = c(0,.3)){
  sig_b2 <- -1*iccs / (iccs - 1)
  n <- nsub * nclust * narm
  y <- rep_len(NA, n)
  arm <- as.factor(rep(0:(narm-1), each = nsub*nclust))
  clustid <- rep(1:(nclust*narm), each = nsub)
  clustRElist <- rnorm(narm*nclust, mean = 0, sd = rep(sqrt(sig_b2), each = nclust))
  clustRE <- rep(clustRElist, each = nsub)
  sig_b2 <- rep(sig_b2, each = nclust*nsub)
  error <- rnorm(n, mean = 0, sd = 1)
  beta <- rep(betas, each = nclust*nsub)
  linpred <- beta + clustRE + error
  output <- cbind.data.frame(arm, clustid, sig_b2, clustRE, linpred)
  return(output)
}

get_pval <- function(){
  tt <- multi_arm_var_sim()
  model_flex <- lme4::lmer(linpred ~ arm + (1 + arm | clustid),
                               data = tt)
  diff_optims <- lme4::allFit(model_flex, data = tt, verbose = TRUE)
  print(class(diff_optims[[1]]))
  is.OK <- sapply(diff_optims, is, "merMod")
  print(is.OK)
}
set.seed(2)
get_pval()

谢谢!

0 个答案:

没有答案