Plot random effects from lmer (lme4 package) using qqmath or dotplot: How to make it look fancy?

ggplot2, lme4, r, random-effects

Solution

One possibility is to use library `ggplot2` to draw similar graph and then you can adjust appearance of your plot.

First, `ranef` object is saved as `randoms`. Then variances of intercepts are saved in object `qq`.

randoms<-ranef(fit1, postVar = TRUE)
qq <- attr(ranef(fit1, postVar = TRUE)[[1]], "postVar")

Object `rand.interc` contains just random intercepts with level names.

rand.interc<-randoms$Batch

All objects put in one data frame. For error intervals `sd.interc` is calculated as 2 times square root of variance.

df<-data.frame(Intercepts=randoms$Batch[,1],
              sd.interc=2*sqrt(qq[,,1:length(qq)]),
              lev.names=rownames(rand.interc))

If you need that intercepts are ordered in plot according to value then `lev.names` should be reordered. This line can be skipped if intercepts should be ordered by level names.

df$lev.names<-factor(df$lev.names,levels=df$lev.names[order(df$Intercepts)])

This code produces plot. Now points will differ by `shape` according to factor levels.

library(ggplot2)
p <- ggplot(df,aes(lev.names,Intercepts,shape=lev.names))

#Added horizontal line at y=0, error bars to points and points with size two
p <- p + geom_hline(yintercept=0) +geom_errorbar(aes(ymin=Intercepts-sd.interc, ymax=Intercepts+sd.interc), width=0,color="black") + geom_point(aes(size=2)) 

#Removed legends and with scale_shape_manual point shapes set to 1 and 16
p <- p + guides(size=FALSE,shape=FALSE) + scale_shape_manual(values=c(1,1,1,16,16,16))

#Changed appearance of plot (black and white theme) and x and y axis labels
p <- p + theme_bw() + xlab("Levels") + ylab("")

#Final adjustments of plot
p <- p + theme(axis.text.x=element_text(size=rel(1.2)),
               axis.title.x=element_text(size=rel(1.3)),
               axis.text.y=element_text(size=rel(1.2)),
               panel.grid.minor=element_blank(),
               panel.grid.major.x=element_blank())

#To put levels on y axis you just need to use coord_flip()
p <- p+ coord_flip()
print(p)

Problem

The qqmath function makes great caterpillar plots of random effects using the output from the lmer package. That is, qqmath is great at plotting the intercepts from a hierarchical model with their errors around the point estimate. An example of the lmer and qqmath functions are below using the built-in data in the lme4 package called Dyestuff. The code will produce the hierarchical model and a nice plot using the ggmath function. ``` library("lme4") data(package = "lme4") # Dyestuff # a balanced one-way classiï¬cation of Yield # from samples produced from six Batches summary(Dyestuff) # Batch is an example of a random effect # Fit 1-way random effects linear model fit1 <- lmer(Yield ~ 1 + (1|Batch), Dyestuff) summary(fit1) coef(fit1) #intercept for each level in Batch # qqplot of the random effects with their variances qqmath(ranef(fit1, postVar = TRUE), strip = FALSE)$Batch ``` The last line of code produces a really nice plot of each intercept with the error around each estimate. But formatting the qqmath function seems to be very difficult, and I've been struggling to format the plot. I've come up with a few questions that I cannot answer, and that I think others could also benefit from if they are using the lmer/qqmath combination: - Is there a way to take the qqmath function above and add a few options, such as, making certain points empty vs. filled-in, or different colors for different points? For example, can you make the points for A,B, and C of the Batch variable filled, but then the rest of the points empty? - Is it possible to add axis labels for each point (maybe along the top or right y axis, for example)? - My data has closer to 45 intercepts, so it is possible to add spacing between the labels so they do not run into each other? MAINLY, I am interested in distinguishing/labeling between points on the graph, which seems to be cumbersome/impossible in the ggmath function. So far, adding any additional option in the qqmath function produce errors where I would not get errors if it was a standard plot, so I'm at a loss. Also, if you feel there is a better package/function for plotting intercepts from lmer output, I'd love to hear it! (for example, can you do points 1-3 using dotplot?) EDIT: I'm also open to an alternative dotplot if it can be reasonably formatted. I just like the look of a ggmath plot, so I'm starting with a question about that.

Original source

Related problems