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

前端 未结 4 1955
耶瑟儿~
耶瑟儿~ 2020-12-07 08:46

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 hiera

4条回答
  •  臣服心动
    2020-12-07 09:00

    Didzis' answer is great! Just to wrap it up a little bit, I put it into its own function that behaves a lot like qqmath.ranef.mer() and dotplot.ranef.mer(). In addition to Didzis' answer, it also handles models with multiple correlated random effects (like qqmath() and dotplot() do). Comparison to qqmath():

    require(lme4)                            ## for lmer(), sleepstudy
    require(lattice)                         ## for dotplot()
    fit <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy)
    ggCaterpillar(ranef(fit, condVar=TRUE))  ## using ggplot2
    qqmath(ranef(fit, condVar=TRUE))         ## for comparison
    

    enter image description here

    Comparison to dotplot():

    ggCaterpillar(ranef(fit, condVar=TRUE), QQ=FALSE)
    dotplot(ranef(fit, condVar=TRUE))
    

    enter image description here

    Sometimes, it might be useful to have different scales for the random effects - something which dotplot() enforces. When I tried to relax this, I had to change the facetting (see this answer).

    ggCaterpillar(ranef(fit, condVar=TRUE), QQ=FALSE, likeDotplot=FALSE)
    

    enter image description here

    ## re = object of class ranef.mer
    ggCaterpillar <- function(re, QQ=TRUE, likeDotplot=TRUE) {
        require(ggplot2)
        f <- function(x) {
            pv   <- attr(x, "postVar")
            cols <- 1:(dim(pv)[1])
            se   <- unlist(lapply(cols, function(i) sqrt(pv[i, i, ])))
            ord  <- unlist(lapply(x, order)) + rep((0:(ncol(x) - 1)) * nrow(x), each=nrow(x))
            pDf  <- data.frame(y=unlist(x)[ord],
                               ci=1.96*se[ord],
                               nQQ=rep(qnorm(ppoints(nrow(x))), ncol(x)),
                               ID=factor(rep(rownames(x), ncol(x))[ord], levels=rownames(x)[ord]),
                               ind=gl(ncol(x), nrow(x), labels=names(x)))
    
            if(QQ) {  ## normal QQ-plot
                p <- ggplot(pDf, aes(nQQ, y))
                p <- p + facet_wrap(~ ind, scales="free")
                p <- p + xlab("Standard normal quantiles") + ylab("Random effect quantiles")
            } else {  ## caterpillar dotplot
                p <- ggplot(pDf, aes(ID, y)) + coord_flip()
                if(likeDotplot) {  ## imitate dotplot() -> same scales for random effects
                    p <- p + facet_wrap(~ ind)
                } else {           ## different scales for random effects
                    p <- p + facet_grid(ind ~ ., scales="free_y")
                }
                p <- p + xlab("Levels") + ylab("Random effects")
            }
    
            p <- p + theme(legend.position="none")
            p <- p + geom_hline(yintercept=0)
            p <- p + geom_errorbar(aes(ymin=y-ci, ymax=y+ci), width=0, colour="black")
            p <- p + geom_point(aes(size=1.2), colour="blue") 
            return(p)
        }
    
        lapply(re, f)
    }
    

提交回复
热议问题