将模拟 merMods 的结果存储在数据框中
Storing results from simulated merMods in data frame
已更新:
我正在尝试通过模拟已知数据和 运行 模型 100 次来检查 merMod
对象的参数估计值的可变性。我希望结果是一个如下所示的数据框:
| simulation | intercept | est.x1 | est.x2 |
| ---------- | --------- | ------ | ------ |
| sim_study1 |.09 |.75 |.25 |
| sim_study2 |.10 |.72 |.21 |
| sim_study3 |NA |NA |NA |
我使用随机截距和 2 个预测变量生成多级数据的代码是:
# note. this code block runs as expected, and if I run a lmer() call
# on a simulated data set I get values that one would expect.
gen_fake <- function(i, j){
school <- rep(1:j)
person <- rep(1:i) # students nested in schools
# parameters
mu_a_true <- 0.10 # real intercept
sigma_a_true <- 0.10 # varince of intercept
sigma_y_true <- 0.40
b1_true <- .75
b2_true <- .25
# random intercept for schools
a_true <- rnorm(j, mu_a_true, sigma_a_true)
# random data for predictors
x1 <- rnorm(i, 0, 1)
x2 <- rnorm(i, 0, 1)
# outcome
y <- rnorm(i, a_true[school] + b1_true*x1 + b2_true*x2, sigma_y_true)
return (data.frame(y, person, school, x1, x2))
}
我正在尝试对模型进行 100 次模拟,同时每次都生成新数据。请注意,我正在尝试在循环内实现 tryCatch,因为对于更复杂的模型,模型可能无法正常终止,我希望 table 中返回的值对于参数为 NA。
我的代码如下:
# create an empty data frame with names of parameters (there's probably
# a slicker way to do this within the loop where I can match names from
# the model call)
sim_results <- data.frame(matrix(nrow=100, ncol=3,
dimnames=list(c(),
c("intercept",
"est.x1", "est.x2"))),
stringsAsFactors=F)
# load library for analysis
library(lme4)
# conduct 100 simulations of the model generating fake data for each run
sim_study <- function (i, j, n.sims){
for (sim in 1:n.sims){
fake_dat <- gen_fake(i, j)
tryCatch({
lmer_sim <- lmer(y ~ x1 + x2 + (1|school), data = fake_dat)
}, error = function(e){
return(NA)
}) #return previous value of fm if error
estimates <- rbind(fixef(lmer_sim))
}
sim_results[sim,] <- estimates
}
# run the simulation study
sim_study (1000,5,100)
我遇到的问题是该函数只有 returns 1 行并且它没有填充我创建的空数据框:
(Intercept) x1 x2
[1,] 0.09659339 0.7746392 0.2325391
我不确定这个问题。最后,如果您有任何关于如何使这项工作更快的反馈,我们也将不胜感激,因为我想了解有关该问题的更多信息。感谢您的帮助。
这可能有点夸张,但我认为您只是放错了循环括号?这对我有用:
sim_study <- function (i, j, n.sims){
for (sim in 1:n.sims) {
if (sim %% 10 == 0 ) cat(".\n") ## print progress
fake_dat <- gen_fake(i, j)
tryCatch({
lmer_sim <- lmer(y ~ x1 + x2 + (1|school),
data = fake_dat)
}, error = function(e){
return(rep(NA,3)) ## return vector of correct length
}) #return previous value of fm if error
estimates <- rbind(fixef(lmer_sim))
sim_results[sim,] <- estimates
}
return(sim_results)
}
再补充几点:
- 我不确定
tryCatch()
逻辑是否有效,因为我没有遇到任何错误(但我认为它应该被修改为 return 具有当前长度的对象,如上)
- 您可以替换您的一些
gen_fake
(不是预测变量的生成,而是使用内置 ?simulate.merMod()
生成的响应,但我认为它实际上不会工作得更好(或更差)
- 显着加快速度会有点 work/hacky。如果只有预测变量发生变化,有一个
refit()
函数可以快速运行,但在这种情况下不成立。您可以使用指定的技巧 here ...
已更新:
我正在尝试通过模拟已知数据和 运行 模型 100 次来检查 merMod
对象的参数估计值的可变性。我希望结果是一个如下所示的数据框:
| simulation | intercept | est.x1 | est.x2 |
| ---------- | --------- | ------ | ------ |
| sim_study1 |.09 |.75 |.25 |
| sim_study2 |.10 |.72 |.21 |
| sim_study3 |NA |NA |NA |
我使用随机截距和 2 个预测变量生成多级数据的代码是:
# note. this code block runs as expected, and if I run a lmer() call
# on a simulated data set I get values that one would expect.
gen_fake <- function(i, j){
school <- rep(1:j)
person <- rep(1:i) # students nested in schools
# parameters
mu_a_true <- 0.10 # real intercept
sigma_a_true <- 0.10 # varince of intercept
sigma_y_true <- 0.40
b1_true <- .75
b2_true <- .25
# random intercept for schools
a_true <- rnorm(j, mu_a_true, sigma_a_true)
# random data for predictors
x1 <- rnorm(i, 0, 1)
x2 <- rnorm(i, 0, 1)
# outcome
y <- rnorm(i, a_true[school] + b1_true*x1 + b2_true*x2, sigma_y_true)
return (data.frame(y, person, school, x1, x2))
}
我正在尝试对模型进行 100 次模拟,同时每次都生成新数据。请注意,我正在尝试在循环内实现 tryCatch,因为对于更复杂的模型,模型可能无法正常终止,我希望 table 中返回的值对于参数为 NA。
我的代码如下:
# create an empty data frame with names of parameters (there's probably
# a slicker way to do this within the loop where I can match names from
# the model call)
sim_results <- data.frame(matrix(nrow=100, ncol=3,
dimnames=list(c(),
c("intercept",
"est.x1", "est.x2"))),
stringsAsFactors=F)
# load library for analysis
library(lme4)
# conduct 100 simulations of the model generating fake data for each run
sim_study <- function (i, j, n.sims){
for (sim in 1:n.sims){
fake_dat <- gen_fake(i, j)
tryCatch({
lmer_sim <- lmer(y ~ x1 + x2 + (1|school), data = fake_dat)
}, error = function(e){
return(NA)
}) #return previous value of fm if error
estimates <- rbind(fixef(lmer_sim))
}
sim_results[sim,] <- estimates
}
# run the simulation study
sim_study (1000,5,100)
我遇到的问题是该函数只有 returns 1 行并且它没有填充我创建的空数据框:
(Intercept) x1 x2
[1,] 0.09659339 0.7746392 0.2325391
我不确定这个问题。最后,如果您有任何关于如何使这项工作更快的反馈,我们也将不胜感激,因为我想了解有关该问题的更多信息。感谢您的帮助。
这可能有点夸张,但我认为您只是放错了循环括号?这对我有用:
sim_study <- function (i, j, n.sims){
for (sim in 1:n.sims) {
if (sim %% 10 == 0 ) cat(".\n") ## print progress
fake_dat <- gen_fake(i, j)
tryCatch({
lmer_sim <- lmer(y ~ x1 + x2 + (1|school),
data = fake_dat)
}, error = function(e){
return(rep(NA,3)) ## return vector of correct length
}) #return previous value of fm if error
estimates <- rbind(fixef(lmer_sim))
sim_results[sim,] <- estimates
}
return(sim_results)
}
再补充几点:
- 我不确定
tryCatch()
逻辑是否有效,因为我没有遇到任何错误(但我认为它应该被修改为 return 具有当前长度的对象,如上) - 您可以替换您的一些
gen_fake
(不是预测变量的生成,而是使用内置?simulate.merMod()
生成的响应,但我认为它实际上不会工作得更好(或更差) - 显着加快速度会有点 work/hacky。如果只有预测变量发生变化,有一个
refit()
函数可以快速运行,但在这种情况下不成立。您可以使用指定的技巧 here ...