【问题标题】:R - Lattice xyplot - How do you add error bars to groups and summary lines?R - Lattice xyplot - 如何将误差线添加到组和摘要行?
【发布时间】:2014-10-13 03:24:01
【问题描述】:

我发布这个问题是因为直到现在还没有回答非常相似的问题here

我被要求在描述所有患者值的xyplot() 上绘制我的整个患者队列的平均值 +/- SEM。使用的数据代表接受手术的患者的术中心血管发现。

这是我的data.frame,叫df

dput(df)
structure(list(Name = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 
5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 4L, 4L, 4L, 4L, 4L, 4L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L), .Label = c("DE", "JS", "KG", "MK", "TG", "WT"), class = "factor"), 
    Time = structure(c(1L, 2L, 3L, 4L, 5L, 7L, 8L, 1L, 2L, 3L, 
    4L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 
    6L, 7L, 8L, 2L, 3L, 4L, 5L, 7L, 8L, 1L, 2L, 3L, 4L, 5L, 6L, 
    7L, 8L), .Label = c("T1", "T2", "T3", "T4", "T5", "T6", "T7", 
    "T8"), class = "factor"), Dobut = structure(c(1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 1L), .Label = c("No", "Yes"
    ), class = "factor"), DobutDose = c(NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    4L, 6L, 8L, 8L, 8L, 8L, 8L, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, 5L, 5L, NA), CI = c(1.4, 2.3, 1.3, 1.8, 2.1, 
    2, 2.1, 2.1, 2.3, 1.9, 1.6, 2, 2.4, 2.7, 2.6, 2.7, 2.6, 2.3, 
    2.4, 2.6, 0.9, 2.5, 2.1, 1.6, 1.5, 1.8, 2, 2, 1.9, 2.1, 2.3, 
    2, 2.4, 2.3, 2.6, 2.4, 2, 2.2, 1.6, 2.1, 2.5, 2.8), SvO2 = c(57L, 
    65L, 47L, 45L, 51L, 60L, 56L, 70L, 85L, 75L, 79L, 82L, 73L, 
    77L, 78L, 73L, 71L, 73L, 80L, 74L, 41L, 66L, 51L, 51L, 49L, 
    54L, 68L, 48L, 80L, 70L, 71L, 69L, 74L, 79L, 77L, 77L, 75L, 
    74L, 70L, 79L, 80L, 79L), SVRI = c(4000L, 1983L, 4000L, 2444L, 
    1981L, 2120L, 2514L, 2971L, 2157L, 3747L, 4300L, 3200L, 2867L, 
    1778L, 1169L, 1215L, 1262L, 1461L, 1600L, 1692L, 4978L, 1760L, 
    2019L, 2650L, 2827L, 2356L, 1800L, 2840L, 2063L, 2248L, 1948L, 
    2160L, 1733L, 2296L, 2677L, 2100L, 2640L, 2655L, 3950L, 2210L, 
    2848L, 2543L), MAP = c(80L, 65L, 86L, 74L, 67L, 65L, 74L, 
    90L, 70L, 90L, 96L, 94L, 100L, 82L, 60L, 61L, 62L, 62L, 69L, 
    71L, 70L, 71L, 77L, 73L, 75L, 77L, 61L, 85L, 65L, 74L, 70L, 
    67L, 69L, 74L, 92L, 71L, 88L, 93L, 89L, 79L, 97L, 97L), CVP = c(10L, 
    8L, 21L, 19L, 15L, 12L, 8L, 12L, 8L, 11L, 10L, 14L, 14L, 
    22L, 22L, 20L, 21L, 20L, 21L, 16L, 14L, 16L, 24L, 20L, 22L, 
    24L, 16L, 14L, 16L, 15L, 14L, 13L, 17L, 8L, 5L, 8L, 22L, 
    20L, 20L, 21L, 8L, 8L), PAP = c(23L, 22L, 36L, 36L, 34L, 
    32L, 22L, 33L, 28L, 36L, 36L, 40L, 37L, 37L, 40L, 35L, 35L, 
    34L, 38L, 36L, 45L, 43L, 55L, 49L, 52L, 54L, 43L, 47L, 27L, 
    25L, 23L, 22L, 28L, 21L, 20L, 25L, 33L, 33L, 38L, 35L, 33L, 
    29L), PCWP = c(15L, 11L, 28L, 26L, 23L, 21L, 11L, 26L, NA, 
    NA, 25L, 25L, NA, 27L, NA, NA, NA, NA, NA, NA, 30L, NA, NA, 
    NA, NA, NA, NA, NA, 19L, NA, NA, NA, NA, NA, 16L, NA, NA, 
    NA, NA, NA, NA, NA)), .Names = c("Name", "Time", "Dobut", 
"DobutDose", "CI", "SvO2", "SVRI", "MAP", "CVP", "PAP", "PCWP"
), class = "data.frame", row.names = c(NA, -42L))

现在我为变量CI 制作的第一个xyplot 看起来像这样

require(lattice)
xyplot(CI~Time, groups=Name, data=df, ty=c("l", "p"),
+        ,xlab="Measurement Time Point", 
ylab=expression("CI"~(l/min/m^"2")), main="Cardiac Index")

现在我可以通过执行以下操作来添加整个队列的平均值(黑线)

xyplot(CI~Time, groups=Name, data=df, ty=c("l", "p"), 
       panel = function(x, y, ...) {
           panel.xyplot(x, y, ...)
           panel.linejoin(x, y, horizontal = FALSE,..., col="black", lty=1, lwd=4)
       }
       ,xlab="Measurement Time Point", 
ylab=expression("CI"~(l/min/m^"2")), main="Cardiac Index")

现在我想将 +/- SE 添加到平均值之上/之下的一条线,但我无法找到如何做到这一点。

我能做的是使用latticeExtra 包添加黄土线+/- SE,如下所示,但这不是我正在寻找的正确数学函数。我在那里留下了平均线来说明两者之间的区别。

require(latticeExtra)
xyplot(CI~Time, groups=Name, data=df, ty=c("l", "p"), 
+        panel = function(x, y, ...) {
+            panel.xyplot(x, y, ...)
+            panel.linejoin(x, y, horizontal = FALSE,..., col="black", lty=1, lwd=4)
+            panel.smoother(x,y,se=TRUE, col.se="grey")
+        }
+        ,xlab="Measurement Time Point", 
ylab=expression("CI"~(l/min/m^"2")), main="Cardiac Index")

我已经通过 SO 和互联网进行了广泛的搜索,但我无法找到合适的功能来执行此操作。

非常感谢您的帮助!谢谢。

【问题讨论】:

  • 你想精确地绘制什么标准误差?您是否只想在给定的测量时间点绘制所有点的 SE? lattice 中没有可以为您计算该值的函数。您需要自己计算,然后在自定义面板函数中绘制它。你想把它画成丝带吗?
  • 谢谢。正如你所说,我想要的 SE:对于给定时间点(T1-T8)的所有测量。有点像黄土函数,但基本上每个时间点的平均值 +/- SEM 和点的连接是平均值。我用所有感兴趣的值计算了一个单独的data.frame,但无法将它“覆盖”在xyplot 上。如果您想要 SE 的快速功能,这里有一个:stderr<-function(x) sqrt(var(x,na.rm=TRUE)/length(na.omit(x)))。感谢您的时间和帮助。

标签: r lattice standard-error


【解决方案1】:

您可以创建自己的面板函数来绘制 +/- SD 区域。例如

#new panel function
panel.se <- function(x, y, col.se=plot.line$col, alpha.se=.25, ...) {
    plot.line <- trellis.par.get("plot.line")
    xs <- if(is.factor(x)) {
       factor(c(levels(x) , rev(levels(x))), levels=levels(x))
    } else {
       xx <- sort(unique(x))
       c(xx, rev(xx))
    }
    means <- tapply(y,x, mean, na.rm=T)
    vars <- tapply(y,x, var, na.rm=T)
    Ns <- tapply(!is.na(y),x, sum)
    ses <- sqrt(vars/Ns)
    panel.polygon(xs, c(means+ses, rev(means-ses)), col=col.se, alpha=alpha.se)
}

然后你可以像这样使用它

#include new panel function
xyplot(CI~Time, groups=Name, data=df, ty=c("l", "p"), 
       panel = function(x, y, ...) {
           panel.se(x,y, col.se="grey")
           panel.xyplot(x, y, ...)
           panel.linejoin(x, y, horizontal = FALSE,..., col="black", lty=1, lwd=4)

       }
       ,xlab="Measurement Time Point", 
ylab=expression("CI"~(l/min/m^"2")), main="Cardiac Index")

导致

【讨论】:

  • 哈!弗里克先生真是个男人!这真是太棒了!谢谢!我在想我必须创建一个新面板,其中还包括tapply 函数。现在仔细阅读您的代码,我是否正确地假设我们正在绘制标准偏差而不是平均值的标准误差?我尝试重新编写您的代码以包含我在上面发布的stderr 函数,但我收到一条错误消息。很抱歉一直打扰你,但是看到你刚刚解决了我一整天的问题,我很兴奋!!!
  • 我已根据您对“标准错误”的定义进行了更新。我假设这将修复错误消息,但由于您没有显示您的代码,甚至没有给出确切的错误消息,所以无法判断。
  • 实际上是一个旁注:我设法让代码工作,通过添加stderr 函数,但在panel.sd 函数中删除na.rm=T...实际上这很奇怪!但是看到stderr 函数中有一个na.rm=T 并且NAs 只影响SE 和SD 的计算(但不影响平均值),我认为没关系,不是吗?
  • 产生错误信息的代码:Error using paket 1 unused argument na.rm=TRUEpanel.sem &lt;- function(x, y, col.se=plot.line$col, alpha.se=.10, ...) { + plot.line &lt;- trellis.par.get("plot.line") + xs &lt;- if(is.factor(x)) { + factor(c(levels(x) , rev(levels(x))), levels=levels(x)) + } else { + xx &lt;- sort(unique(x)) + c(xx, rev(xx)) + } + means &lt;- tapply(y,x, mean, na.rm=T) + stderr &lt;- tapply(y,x, stderr, na.rm=T) + panel.polygon(xs, c(means+stderr, rev(means-stderr)), col=col.se, alpha=alpha.se) 请参阅上面的修复方法。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-05
  • 2021-01-31
  • 2020-09-25
  • 2023-03-27
相关资源
最近更新 更多