How can I sort random effects by random effect value (not interception) in dotplot or ggplot2

I suspect the answer to this question is quite simple, and I just don't know what it is.

In short, I want to show the exact point of random intercepts and slopes from the model that I am evaluating. I am using the ggCaterpillar function, which was successfully introduced here . However, this function, as well as the dotplot standard from the grid, sort the subsequent graph, reducing the order of random interception. I would like to sort the graph by increasing the value of the random effect (either alphabetically or digitally).

Consider this minimal working example, which comes standard in the lme4 package along with the ggCaterpillar function.

 ## /questions/200997/in-r-plotting-random-effects-from-lmer-lme4-package-using-qqmath-or-dotplot-how-to-make-it-look-fancy 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) } library(lme4) fit <- lmer(Reaction ~ Days + (Days|Subject), sleepstudy) ggCaterpillar(ranef(fit,condVar=TRUE), QQ=FALSE, likeDotplot=TRUE)[["Subject"]] 

The graph that I get is as follows.

Sample graph

How can I arrange the graph so that the graphs are arranged by increasing the value of the random effect (e.g. 308, 309, 310 ... in case of a dream)?

+2
source share
1 answer

In the part of the function where ord and pDf , the lines are reordered according to the size of the interception. We can make this part optional, as in the updated function below:

 require(ggplot2) ggCaterpillar <- function(re, QQ=TRUE, likeDotplot=TRUE, reorder=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, ]))) if (reorder) { 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))) } else { pDf <- data.frame(y=unlist(x), ci=1.96*se, nQQ=rep(qnorm(ppoints(nrow(x))), ncol(x)), ID=factor(rep(rownames(x), ncol(x)), levels=rownames(x)), 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) } 

If we now call the function with reorder = FALSE , we get the original row order:

 ggCaterpillar(ranef(fit,condVar=TRUE), QQ=FALSE, likeDotplot=TRUE, reorder=FALSE)[["Subject"]] 

enter image description here

You can change the order of the lines before plotting, if you want, for example, to change the order:

 ref <- ranef(fit,condVar=TRUE) ref$Subject <- ref$Subject[nrow(ref$Subject):1, ] ggCaterpillar(ref, QQ=FALSE, likeDotplot=TRUE, reorder=FALSE)[["Subject"]] 

enter image description here

+3
source

Source: https://habr.com/ru/post/1238577/


All Articles