我正在尝试扩展this question的答案:具体来说, how to build simulations for linear mixed effects models with a random intercept 'from scratch' (没有 simulate.merModarm ) . 我问,因为我有兴趣重新采样从拟合模型中获得的参数估计值来模拟 - 而不是预测 - 新值的响应,同时重新采样固定效应参数估计,随机效应估计和残差方差 . 我错了或如何改进流程 .

我从Ben Bolker的建议开始,并使用 mvrnorm() 从固定效应参数的采样分布中绘制新系数 .

library(lme4)
mod1 <- lmer(Sepal.Length ~ Sepal.Width + (1 | Species), data = iris)

v <- vcov(mod1)
b <- mod1@beta

fixed <- MASS::mvrnorm(1000, mu=b, Sigma=v)

使用 melt 重新整形重新采样的系数,并重命名列 .

library(reshape)
library(dplyr)
fixed.resampled = reshape::melt(fixed, id.vars= "refs") %>%
  dplyr::rename(species=X2)

从答案到question about plotting random effects,提取并保存 ranef 对象,在 qq 中保存截距的方差,并将截距估计,标准差和随机效果级别放在数据框中 .

randoms <- ranef(mod1, condVar = TRUE)
qq <- attr(ranef(mod1, condVar = TRUE)[[1]], "postVar")
rand.interc <- randoms$Species
df <- data.frame(Intercepts=randoms$Species[,1],
               sd.interc=2*sqrt(qq[,,1:length(qq)]),
               lev.names=rownames(rand.interc))

与固定效应系数一样,从采样分布中抽取随机效应估计值 . 每个随机效应估计从具有均值 df$Intercepts 和标准偏差 df$sd.interc 的正态分布中采样 . 创建一个空数组来保存样本 .

ranef.resampled <- array(dim=c(1000,3))

使用物种特定方法和标准偏差,从每个物种的正态分布中取样 .

for(i in 1:length(randoms$Species[,1])){
  ranef.resampled[,i] <- rnorm(1000,mean=df$Intercepts[i],sd=df$sd.interc[i])
}

重塑和重命名数据框 .

ranef.resampled <- data.frame(ranef.resampled) %>%
   dplyr::rename(setosa=X1,versicolor=X2,virginica=X3) %>%
   gather() %>%
   dplyr::rename(species=key)

出于绘图目的,创建包含系数和随机效应估计的数据帧 .

fixed.e <- data.frame(species=names(fixef(mod1)),estimate=fixef(mod1)[1:2])
ranef.e <- data.frame(species=row.names(rand.interc),estimate=rand.interc[,1])

把所有东西放在一起 .

dfLong <- fixed.resampled %>% 
          dplyr::bind_rows(ranef.resampled) %>%
          dplyr::bind_rows(fixed.e) %>%
          dplyr::bind_rows(ranef.e) %>%
          dplyr::rename(X2=species)

绘制系数和随机效应估计值 .

ggplot(dfLong, aes (value,group=X2)) +
  geom_density() + 
  geom_vline(data=dfLong,
    aes(xintercept=estimate),
    color="red",linetype="dashed") +
  facet_grid(X2~.) + 
  theme_classic()

enter image description here

要模拟值,首先要创建一个新数据框来保存要执行模拟的值 . 在这里,我生成了1000个样本,这些样本与 Species="setosa" 的原始数据的分布相匹配 .

set.seed(101)
newDf <- data.frame(Sepal.Width = rnorm(1000,mean(iris$Sepal.Width[1:50]), sd(iris$Sepal.Width[1:50])), Species="setosa")

然后我使用这个新数据来使用_1349850来模拟结果(这是在 mer 模型对象上调用 simulate() 时调用的 .

simulated.setosa <- data.frame(setosa=simulate(mod1, nsim=1, newdata=newDf)[1:1000,])

我想要做的是在不使用 simulate() 的情况下生成类似的预测 . 到目前为止,我采取了以下步骤 . 总和:截距,'width'的参数估计值乘以'width'的模拟值,以及'setosa.'的重采样随机效应估计值

sim.setosa <- data.frame(setosa=fixed[1:1000,1] + fixed[1:1000,2] * newDf$Sepal.Width[1:1000] + ranef.resampled[1:1000,2])

然后我使用以下内容来比较这两个模拟的输出 . 虽然我不希望它们完全匹配(重新采样系数是 simulate() 的内部,但我认为它与我尝试将模拟拼凑在一起的输出相同 .

ggplot() +
  geom_density(data=simulated.setosa,aes(setosa)) +
  geom_density(data=sim.setosa,aes(setosa),col="red") +
  theme_classic() +
  xlim(c(0,10))