lme4 + simulate
Esta entrada es casi una referencia para mí. Cada vez tiro más de lme4
en mis modelos y en uno en concreto que tengo entre manos toca simular escenarios. Para lo cual, simulate.merMod
.
Véamoslo en funcionamiento. Primero, datos (ANOVA-style) y el modelo que piden a gritos:
library(plyr)
library(lme4)
a <- c(0,0,0, -1, -1, 1, 1, -2, 2)
factors <- letters[1:length(a)]
datos <- ldply(1:100, function(i){
data.frame(x = factors, y = a + rnorm(length(a)))
})
modelo <- lmer(y ~ (1 | x), data = datos)
El resumen del modelo está niquelado:
summary(modelo)
# Linear mixed model fit by REML ['lmerMod']
# Formula: y ~ (1 | x)
# Data: datos
#
# REML criterion at convergence: 2560.3
#
# Scaled residuals:
# Min 1Q Median 3Q Max
# -3.6798 -0.6442 -0.0288 0.6446 3.3582
#
# Random effects:
# Groups Name Variance Std.Dev.
# x (Intercept) 1.5197 1.2328
# Residual 0.9582 0.9789
# Number of obs: 900, groups: x, 9
#
# Fixed effects:
# Estimate Std. Error t value
# (Intercept) -0.009334 0.412212 -0.023
En particular,
- el término independiente es prácticamente cero;
- la desviación estándar de los residuos es casi uno (de acuerdo con el modelo de generación de datos);
- y la desviación estándar del efecto aleatorio de
x
es, prácticamente,sd(a)
, como cabía esperar.
Ahora, la simulación. Así,
sims.u.false <- simulate(modelo, nsim = 1000, use.u = FALSE)
hist(apply(sims.u.false, 1, mean))
obtengo
donde se ha ignorado el valor preespecificado de los efectos aleatorios (el valor de x
) en los datos. En jerga estadística, es la predicción incondicional. Pero podemos exigir que se condicione en los valores de x
(es decir, tener en cuenta de que hay observaciones con valores x predefinidos) así:
sims.u.true <- simulate(modelo, nsim = 1000, use.u = TRUE)
hist(apply(sims.u.true, 1, mean))
para obtener
que tiene mucha mejor pinta. Nótese que en los datos originales hay sujetos cuyas predicciones tienen una media alrededor de 2 y que no se manifiestan en la simulación incondicional.
Finalmente, se pueden añadir observaciones con un nivel de x
desconocido. La simulación condicional lo es para aquellas observaciones con niveles conocidos del factor aleatorio y, por decirlo de alguna manera, incondicional para las que no (y hay que usar la opción allow.new.levels = TRUE
):
new_data <- data.frame(x = c(factors, "z"))
sims.u.true.alt <- simulate(modelo, nsim = 1000, use.u = TRUE, allow.new.levels = TRUE, newdata = new_data)
t(apply(sims.u.true.alt, 1, function(x) c(mean(x), sd(x))))
# [,1] [,2]
# 1 0.070687053 0.9992549
# 2 -0.004564873 0.9950122
# 3 -0.123329896 0.9882788
# 4 -0.808170380 1.0128760
# 5 -0.952436678 0.9484248
# 6 0.871509730 0.9727093
# 7 1.130616303 0.9958116
# 8 -2.098316767 0.9620356
# 9 1.926374151 0.9744446
# 10 0.012539384 1.0108651
En particular, se aprecia cómo las simulaciones asociadas a la última observación, la que tiene el nivel desconocido de x
z
, están mucho más próximas a cero.
Autonota: Tengo que revisar por qué la varianza de esta última observación es similar a las que tienen el nivel conocido a
. Deberían tener una varianza más grande, ¿no?