【问题标题】:Changing x axis limits and ticks for mada::forest()更改 mada::forest() 的 x 轴限制和刻度
【发布时间】:2016-05-14 00:11:57
【问题描述】:

如果我正在为诊断测试准确性荟萃分析制作森林图:

dat<-data.frame(TP=sample(c(25:100),20,replace=TRUE),
            FN=sample(c(25:100),20,replace=TRUE),
            FP=sample(c(25:100),20,replace=TRUE),
            TN=sample(c(25:100),20,replace=TRUE))

我想绘制 DOR:

library(mada)
fit.DOR.DSL <- madauni(dat)
forest(fit.DOR.DSL)

但是我想自定义x轴上下限和刻度线。 forest() 情节没有任何明显的论据。它允许传递额外的图形参数,我尝试投掷一些随机飞镖,如xlim=c()at=c() 等。我觉得我好像在黑暗中投掷飞镖。

有人知道我需要在这里提出的神奇论点吗?我没有传递“附加图形参数”的经验。

一如既往,谢谢!

这是我更新的函数,维护者 Philipp Doebler 非常有帮助,并且包含了我希望函数执行的一些其他内容。

#instead of using forest() for mada package, use forest.madad()
#and forest.madauni(), from this file, they allow for control over
#the x-axis and the additional of (1) summary sens and spec in forest.madad()
#and a verticle line at the summar statistic in either forest.madad() or 
#forest.madauni()

myforest <- 
  function (x, ci, plotci = TRUE, main = "Forest plot", xlab = NULL,
            SumLine=SumLine, digits = 2L, snames = NULL, subset = NULL, pch     = 15, cex = 1, 
            cipoly = NULL, polycol = NA, plotxaxis = TRUE, ...) 
  {
    stopifnot(length(x) == dim(ci)[1], all(!is.na(c(ci, x))), 
              is.logical(plotci))
    if (!is.null(snames)) {
      stopifnot(length(snames) == length(x))
    }
    if (is.null(snames)) {
      snames <- paste("Study", 1:length(x))
    }
    if (!is.null(subset)) {
      stopifnot(length(subset) > 0, is.integer(subset))
    }
    if (is.null(subset)) {
      subset <- 1:length(x)
    }
    if (!is.null(cipoly)) {
      stopifnot(length(cipoly) == length(x))
      cireg <- which(!cipoly)
      cipoly <- which(cipoly)
    }
    if (is.null(cipoly)) {
      cireg <- 1:length(x)
    }
    x <- x[subset]
    lb <- ci[subset, 1]
    ub <- ci[subset, 2]
    snames <- snames[subset]
    if (is.null(xlab)) {
      xlab <- ""
    }
    N <- length(x)
    plotrange <- max(ub) - min(lb)
    if (plotci) {
      xlim <- c(min(lb) - plotrange * 1.2, max(ub) + plotrange * 
                  1.2)
    }
    else {
      xlim <- c(min(lb) - plotrange * 1.2, max(ub) + plotrange * 
                  0.4)
    }
    ylim <- c(0.5, N + 1)
    plot(NA, NA, xlim = xlim, ylim = ylim, xlab = xlab, ylab = "", 
         yaxt = "n", xaxt = "n", xaxs = "i", bty = "n", main = main, 
         ...)
    abline(h = ylim[2], ...)
    if(!is.null(SumLine)) abline(v = x[length(x)],lty=2, ...)

    for (i in cireg) {
      points(x[i], (N:1)[i], pch = pch)
      arrows(lb[i], (N:1)[i], ub[i], angle = 90, code = 3, 
             length = 0.05, ...)
    }
    for (i in cipoly) {
      polygon(x = c(lb[i], x[i], ub[i], x[i]), y = c((N:1)[i], 
                                                     (N:1)[i] + 0.25, (N:1)    [i], (N:1)[i] - 0.25), col = polycol)
    }
    text(x = xlim[1], N:1, labels = snames[1:N], pos = 4, cex = cex)
    if (plotci) {
      citext <- format(round(cbind(x, ci), digits = digits), 
                       nsmall = digits)
      citext <- paste(citext[, 1], " [", citext[, 2], ", ", 
                      citext[, 3], "]", sep = "")
      text(x = xlim[2], N:1, labels = citext, pos = 2, cex = cex)
    }
    if(plotxaxis){
      axis(1, at = round(seq(from = min(lb), to = max(ub), length.out = 5), 
                         digits), cex = cex)
    }
    return(invisible(NULL))
  }

forest.madauni <- 
  function (x, log = TRUE, plotxaxis = TRUE,SumLine=NULL, snames=NULL, ...) 
  {
    fit <- x
    stopifnot(class(fit) == "madauni")
    descr <- fit$descr
    level <- fit$descr$level
    summ <- summary(fit, level = level)
    forest.x <- fit$theta
forest.ci <- switch(fit$type, DOR = descr$DOR$DOR.ci, negLR =     descr$negLR$negLR.ci, 
                        posLR = descr$posLR$posLR.ci)
    forest.x <- c(forest.x, summ$CIcoef[1, 1])
    forest.ci <- rbind(forest.ci, summ$CIcoef[1, 2:3])
    if (!exists("snames")) {
      snames <- descr$names
      if (is.null(snames)) {
        snames <- paste("Study", 1:descr$nobs)
      }
      snames <- c(snames, paste("Summary (", fit$method, ")", 
                                sep = ""))
    }
    xlab = switch(fit$type, DOR = "diagnostic odds ratio", negLR = "negative     likelihood ratio", 
                  posLR = "positive likelihood ratio")
    if (log) {
      forest.x <- log(forest.x)
      forest.ci <- log(forest.ci)
      xlab <- paste("log", xlab)
    }
    myforest(x = forest.x, ci = forest.ci, snames = snames, SumLine=SumLine,
             xlab = xlab, cipoly = c(rep(FALSE, descr$nobs), TRUE),
             plotxaxis = plotxaxis, 
             ...)
  }


forest.madad <- 
  function (x, IncludeSummary=NULL,SumLine=NULL,type = "sens", log = FALSE,         plotxaxis = TRUE, ...) 
  {
    dat<-x$data
    fitmod<-summary(reitsma(dat))$coefficients[3:4,c(1,5,6)]
    sensEstimate<-fitmod[1,]
    specEstimate<-1-fitmod[2,]
    d <- x
    stopifnot(class(d) == "madad")
    stopifnot(type %in% c("DOR", "sens", "spec", "posLR", "negLR"))
    if (type == "DOR") {
      ci <- d$DOR$DOR.ci
      x <- d$DOR$DOR
    }
    if (type == "sens") {
      if(!is.null(IncludeSummary)) ci <- rbind(d$sens$sens.ci,sensEstimate[2:3])
      if(!is.null(IncludeSummary)) x <- c(d$sens$sens,sensEstimate[1])
      if(is.null(IncludeSummary)) ci <- d$sens$sens.ci
      if(is.null(IncludeSummary)) x <- d$sens$sens
    }
    if (type == "spec") {
      if(!is.null(IncludeSummary)) ci <-  rbind(d$spec$spec.ci,specEstimate[c(3,2)])
      if(!is.null(IncludeSummary)) x <- c(d$spec$spec,specEstimate[1])
      if(is.null(IncludeSummary)) ci <- d$spec$spec.ci
      if(is.null(IncludeSummary)) x <- d$spec$spec
    }
    if (type == "posLR") {
      ci <- d$posLR$posLR.ci
      x <- d$posLR$posLR
    }
    if (type == "negLR") {
      ci <- d$negLR$negLR.ci
      x <- d$negLR$negLR
    }
    if (log) {
      x <- log(x)
      ci <- log(ci)
    }
    if(is.null(IncludeSummary)) polySum<-rep(FALSE, length(x))
    if(!is.null(IncludeSummary)) polySum<-c(rep(FALSE, length(x)-1),TRUE)
    myforest(x, ci, plotxaxis = plotxaxis, cipoly=polySum,SumLine=SumLine,         ...)
  }

然后我通过如下调用创建了森林图:

forest.madad(madad(SingleSmall),
             SumLine=TRUE,
             type="sens",
             plotxaxis = FALSE,
             IncludeSummary=TRUE,
             snames=c(paste(c(rep("A",3),rep("E",16)),SingleCutpoint$Author),"Summary Estimate"),
             main="Sensitivity")
axis(1, at = seq(0 ,1, by = .25))

我表示我不希望函数绘制 x 轴,然后我调用轴。请注意,我还要求汇总统计数据和汇总估计值。如果您愿意,可以忽略这些论点。

【问题讨论】:

    标签: r plot


    【解决方案1】:

    显然你不能改变这些(或者至少不能立即改变)。

    如果您查看forestmada 函数的源代码(这是在您使用forest 函数时调用的函数),您会发现不能。运行getAnywhere(forest.madad)查看forest函数,运行mada::forestmada查看forestmada函数。或者直接查看?forest

    所以,这就是在 forestmada 函数中调用的内容:

       if (plotci) {
            xlim <- c(min(lb) - plotrange * 1.2, max(ub) + plotrange * 
                1.2)
        }
        else {
            xlim <- c(min(lb) - plotrange * 1.2, max(ub) + plotrange * 
                0.4)
        }
    

    因此,即使您包含任何 xlimylim 参数,这些参数最终也会被上述内容覆盖。

    at 参数完全相同:

    axis(1, at = round(seq(from = min(lb), to = max(ub), length.out = 5), 
        digits), cex = cex)
    

    唯一的方法是复制源代码并尝试自己修改它,但这需要大量工作。

    我自己尝试了一下,但显然所有这些参数都在以后以特定方式使用,所以每当我更改任何内容时,我都会收到很多警告和错误,显然这就是为什么作者决定将它们计算在具体方式。

    希望这会有所帮助。

    【讨论】:

    • 谢谢。昨天我确实最终破解了代码以制定解决方案,但仍然希望其他人会向我展示一个更优雅的想要通过它。我刚刚在您复制的代码之前做了一个ifelsestatement,其中lbub 可以通过提供的xlim 参数重写。我还创建了两个axis 命令,一个用于指定by,另一个用于指定length.out。它有效,但确实需要相当多的工作。感谢您查看并确认原始函数中有如此简单的修复。
    • 非常感谢:)。我真的很高兴能帮上忙!不幸的是,我知道这需要一些工作,但我很高兴你成功了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多