# Testing whether random effects are normally distributed in R

I've been working on a GLMM in R and I see that an assumption of the test is that the random factor must be normally distributed (that is, unless you're using a package like hglm where you can specify a different distribution). However, I can't find any sort of code for how to test the distribution of the random effect, does anyone here have any ideas?

I'm only aware of how to test the residuals of the GLMM for normality, via:

resid <- residuals(model)
qqnorm(resid)
qqline(resid, col = 2)


and

shapiro.test(residuals(model, type = "normalized"))


In lme4 you can use the ranef() function which extracts the conditional modes of the random effects as a list of data frames, one entry in the list corresponding to one grouping factor. Further details are here. For example, with one grouping factor (for Subject), the following model has a random intercept and a random slope (for Days)

require(lme4)
model <- lmer(Reaction ~ Days + (Days | Subject), data=sleepstudy)

r_int<- ranef(model)$Subject$(Intercept)
qqnorm(r_int)
qqline(r_int)
shapiro.test(r_int)

r_slope<- ranef(model)$Subject$Days
qqnorm(r_slope)
qqline(r_slope)
shapiro.test(r_slope)

• What exactly does ranef do? Readers who use non-R software surely would want to know so that they could apply your answer, too.
– whuber
Sep 29, 2014 at 20:48
• Good point. I have added some info about ranef and a link Sep 29, 2014 at 21:21
• Thanks @RobertLong! To make sure I'm doing this right...My data has one random effect, "FocalID", that contains 40 different clusters. I used the following code: model<-lmer(VPL~Age+Sex+DET+DOC+GS+NND+Month+(1|FocalID),data=VPtest) ranef.model<-ranef(model)$FocalID$(Intercept) qqnorm(ranef.model) qqline(ranef.model) shapiro.test(ranef.model) Which gives me tests run on 40 different points. I'm confused about the use of Intercept and slope in your example though, could you explain how that might apply to my model? Do I need to use the actual output intercept value? Sep 30, 2014 at 0:24
• Sorry, I'm new at formatting on these forums...so my code isn't quite posted correctly... and it wouldn't let me edit after my 5 minute timeframe was up! Sep 30, 2014 at 0:31
• In your model you only have a random intercept, not a random slope, so you just need ranef(model)$Subject$(Intercept) Sep 30, 2014 at 9:47