I have a data frame with subject
, wd
, and group
variables, and a value
response variable. Each subject is assigned to one group and has 7 measurements taken over each weekday. Because each subject is completely nested within a group, I want to use a nested random effects model with subject
and group
, as well as adding a third random effect for wd
. Currently, I am using this to do so:
model = lmer(value ~ 1+ (1|wd) + (1|group) + (1|subject),
data = dframe, REML = 0)
I found the code I based this off of on page 40 of this guide. I have used both REML = TRUE
and REML = 0
. However, when I use VarCorr(model)$variances
, I get
Groups Name Std.Dev.
subject (Intercept) 94.9534363
wd (Intercept) 42.5931401
group (Intercept) 0.0015608
Residual 0.9589836
This group variance conflicts with the code that I used to generate the data, which has group means of 36.9, 28.78, and -15.269. When I look at "residuals" for the predicted random effects (using ranef
) vs. true random effects, I get residuals with very high correlation to the group they are in (if I modeled residuals ~ group
, the R-squared value would be over 0.9).
How do I properly fit a nested random effects model in R? I prefer to use lme4, but any package will suffice.
Here is the code I used to generate the data:
library(dplyr)
generate_data <- function(n = 10, g = 3, seed = 1, mean.overall = 300,
sigma.g = 50, sigma.wd = 50,
sigma.subject = 100, sigma. = 30) {
set.seed(seed)
means.wd = rnorm(7) * sigma.wd
means.g = rnorm(g) * sigma.g
means.subject = rnorm(n*g) * sigma.subject
dframe = data.frame(subject = rep(1:(g*n), each = 7),
wd = rep(1:7, g*n),
group = rep(1:g, each = (7*n)))
dframe = mutate(dframe,
value = mean.overall + means.wd[wd] +
means.subject[subject] + means.g[group] + rnorm(7*g*n),
subject = factor(subject, levels = 1:(n*g)),
wd = factor(wd),
group = factor(group, levels = 1:g))
dframe$value = round(pmax(5,dframe$value))
truefx = list(wd = means.wd, group = means.g,
subject = means.subject)
list(data = dframe, effects = truefx)
}
dframe = generate_data()$data