我很难理解在R中如何使用具有单组随机截距的多级线性回归模型生成新数据的预测模拟。按照this text第146-147页的例子,我可以为没有随机效应的简单线性模型执行此任务。我无法解决的问题是如何扩展设置以适应添加到该模型中的因子的随机截距。
我会使用iris
和一些虚假数据来显示我遇到的问题。我将从一个简单的线性模型开始:
mod0 <- lm(Sepal.Length ~ Sepal.Width, data = iris)
现在让我们使用该模型为250个新案例生成1,000个预测模拟。我将从弥补这些案件开始:
set.seed(20912)
fakeiris <- data.frame(Sepal.Length = rnorm(250, mean(iris$Sepal.Length), sd(iris$Sepal.Length)),
Sepal.Width = rnorm(250, mean(iris$Sepal.Length), sd(iris$Sepal.Length)),
Species = sample(as.character(unique(iris$Species)), 250, replace = TRUE),
stringsAsFactors=FALSE)
按照前面提到的文字中的示例,这里是我为这250个新案例中的每个案例进行1,000次预测模拟所做的工作:
library(arm)
n.sims = 1000 # set number of simulations
n.tilde = nrow(fakeiris) # set number of cases to simulate
X.tilde <- cbind(rep(1, n.tilde), fakeiris[,"Sepal.Width"]) # create matrix of predictors describing those cases; need column of 1s to multiply by intercept
sim.fakeiris <- sim(mod0, n.sims) # draw the simulated coefficients
y.tilde <- array(NA, c(n.sims, n.tilde)) # build an array to hold results
for (s in 1:n.sims) { y.tilde[s,] <- rnorm(n.tilde, X.tilde %*% sim.fakeiris@coef[s,], sim.fakeiris@sigma[s]) } # use matrix multiplication to fill that array
工作正常,现在我们可以执行colMeans(y.tilde)
之类的操作来检查这些模拟的中心趋势,并cor(colMeans(y.tilde), fakeiris$Sepal.Length)
将它们与Sepal.Length的(假)观察值进行比较。< / p>
现在让我们试试这个简单模型的扩展,其中我们假设截距在不同的观察组之间变化 - 这里是物种。我将使用lmer()
包中的lme4
来估算与该描述匹配的简单多级/层次模型:
library(lme4)
mod1 <- lmer(Sepal.Length ~ Sepal.Width + (1 | Species), data = iris)
好的,这有效,但现在怎样?我跑:
sim.fakeiris.lmer <- sim(mod1, n.sims)
当我使用str()
检查结果时,我发现它是类sim.merMod的一个对象,有三个组件:
@fixedef
,一个1,000 x 2矩阵,具有固定效果的模拟系数(截距和Sepal.Width)
@ranef
,一个1,000 x 3矩阵,模拟随机效应系数(三种)
@sigma
,长度为1,000的向量,包含与每个模拟相关联的西格玛
我不能围绕如何将矩阵结构和用于简单线性模型的乘法扩展到这种情况,这增加了另一个维度。我查看了文本,但我只能找到一个例子(第272-275页),用于单个组中的单个案例(此处为物种)。我想要执行的真实任务涉及在32个小组(主队)中均匀分布的256个新案例(职业足球比赛)中运行这样的模拟。我非常感谢您提供的任何帮助。
附录即可。愚蠢的是,在发布此帖子之前,我没有查看simulate.merMod()
中lme4
的详细信息。我现在有了。似乎应该这样做,但是当我运行simulate(mod0, nsim = 1000, newdata = fakeiris)
时,结果只有150行。值看起来很合理,但fakeiris
中有250行(个案)。 150来自哪里?
答案 0 :(得分:4)
一种可能性是使用predictInterval
包中的merTools
函数。该软件包即将提交给CRAN,但目前的开发版本可从GitHub下载,
install.packages("devtools")
devtools::install_github("jknowles/merTools")
获得100次模拟的中位数和95%可信区间:
mod1 <- lmer(Sepal.Length ~ Sepal.Width + (1 | Species), data = iris)
out <- predictInterval(mod1, newdata=fakeiris, level=0.95,
n.sims=100, stat="median")
默认情况下,predictInterval
包含剩余变体,但您可以
关闭该功能:
out2 <- predictInterval(mod1, newdata=fakeiris, level=0.95,
n.sims=100, stat="median",
include.resid.var=FALSE)
希望这有帮助!
答案 1 :(得分:3)
这可能有所帮助:它不使用sim()
,而是使用mvrnorm()
从固定效应参数的采样分布中绘制新系数,使用一些内部机制({ {1}})重新分配固定效应系数的内部值。随机效果系数的内部值由setBeta0
使用默认参数simulate.merMod
自动重新采样。但是,残差方差不重新采样 - 它在模拟中保持固定,这不是100%真实。
在您的使用案例中,您需要指定re.form=NA
。
newdata=fakeiris