【问题标题】:How can I sort random effects by value of the random effect (not the intercept) in dotplot or ggplot2如何按 dotplot 或 ggplot2 中的随机效应值(不是截距)对随机效应进行排序
【发布时间】:2016-03-11 06:55:56
【问题描述】:

我怀疑这个问题的答案相当简单,我只是不知道它是什么。

长话短说,我想显示一个我正在估计的模型的随机截距和斜率的点图。我正在使用ggCaterpillar 功能,这很有帮助地介绍了here。然而,这个函数,以及来自 lattice 的标准 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"]] 

我得到的图表是这样的。

如何对图表进行排序,以便通过增加随机效应的值(例如 sleepstudy 案例中的 308、309、310...)对图表进行排序?

【问题讨论】:

    标签: r ggplot2 lattice lme4


    【解决方案1】:

    在创建ordpDf 的函数部分中,行按截距大小重新排序。我们可以使该部分成为可选的,就像下面更新的函数一样:

    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"]]
    

    如果您愿意,可以在绘图前重新排序行,例如颠倒顺序:

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

    【讨论】:

    • 工作就像一个魅力。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 2021-12-16
    • 1970-01-01
    • 2012-06-22
    • 2014-07-24
    • 1970-01-01
    • 2019-02-09
    相关资源
    最近更新 更多