2015-12-06 5 views
2

Я подозреваю, что ответ на этот вопрос довольно прост, и я просто не знаю, что это такое.Как я могу сортировать случайные эффекты по значению случайного эффекта (а не перехвата) в dotplot или ggplot2

Короче говоря, я хочу показать точную точку случайных перехватов и склонов из модели, которую я оцениваю. Я использую функцию ggCaterpillar, которую с благодарностью представил here. Однако эта функция, а также стандарт dotplot из решетки, сортируют последующий график, уменьшая порядок случайного перехвата. Я хотел бы отсортировать график, увеличив значение случайного эффекта (либо в алфавитном, либо в численном).

Рассмотрите этот минимальный рабочий пример, который входит в комплект поставки lme4, а также функцию ggCaterpillar.

## https://stackoverflow.com/questions/13847936/in-r-plotting-random-effects-from-lmer-lme4-package-using-qqmath-or-dotplot 
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"]] 

График, который я получаю, выглядит следующим образом.

Sample graph

Как можно заказать график так, участки упорядочены по возрастанию значения случайного эффекта (например, 308, 309, 310 ... в случае sleepstudy)?

ответ

3

В той части функции, где созданы ord и pDf, строки переупорядочиваются по размеру перехвата. Мы можем сделать что часть необязательно, как в обновленной функции ниже:

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) 
} 

Если мы теперь называем эту функцию с reorder = FALSE мы получаем исходный порядок строк:

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

enter image description here

You может изменить порядок строк до построения графика, если хотите, например, для отмены порядка:

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

+1

Работал как очарование. Большое спасибо. – steve