【问题标题】:using R.zoo to plot multiple series with error bars使用 R.zoo 绘制带有误差线的多个系列
【发布时间】:2011-03-02 19:21:18
【问题描述】:

我的数据如下所示:

   > head(data)
             groupname ob_time dist.mean  dist.sd dur.mean   dur.sd   ct.mean    ct.sd
      1      rowA     0.3  61.67500 39.76515 43.67500 26.35027  8.666667 11.29226
      2      rowA    60.0  45.49167 38.30301 37.58333 27.98207  8.750000 12.46176
      3      rowA   120.0  50.22500 35.89708 40.40000 24.93399  8.000000 10.23363
      4      rowA   180.0  54.05000 41.43919 37.98333 28.03562  8.750000 11.97061
      5      rowA   240.0  51.97500 41.75498 35.60000 25.68243 28.583333 46.14692
      6      rowA   300.0  45.50833 43.10160 32.20833 27.37990 12.833333 14.21800

每个组名都是一个数据系列。由于我想分别绘制每个系列,因此我将它们分开如下:

> A <- zoo(data[which(groupname=='rowA'),3:8],data[which(groupname=='rowA'),2])
> B <- zoo(data[which(groupname=='rowB'),3:8],data[which(groupname=='rowB'),2])
> C <- zoo(data[which(groupname=='rowC'),3:8],data[which(groupname=='rowC'),2])

预计到达时间:

Thanks to gd047: Now I'm using this:

    z <- dlply(data,.(groupname),function(x) zoo(x[,3:8],x[,2]))

生成的动物园对象如下所示:

> head(z$rowA)
          dist.mean  dist.sd dur.mean   dur.sd   ct.mean    ct.sd
     0.3  61.67500 39.76515 43.67500 26.35027  8.666667 11.29226
     60   45.49167 38.30301 37.58333 27.98207  8.750000 12.46176
     120  50.22500 35.89708 40.40000 24.93399  8.000000 10.23363
     180  54.05000 41.43919 37.98333 28.03562  8.750000 11.97061
     240  51.97500 41.75498 35.60000 25.68243 28.583333 46.14692
     300  45.50833 43.10160 32.20833 27.37990 12.833333 14.21800

因此,如果我想根据时间绘制 dist.mean 并为每个系列包含等于 +/- dist.sd 的误差线:

  • 如何组合 A、B、C dist.mean 和 dist.sd?
  • 如何制作条形图,或者更好,结果对象的折线图?

【问题讨论】:

  • 您是出于某种原因坚持使用zoo,还是只想使用任何可用的工具进行绘图?
  • @Aniko:我并不特别热衷于任何事情。我目前正在使用zoo,因为那是我的阅读引导我的地方。
  • 关于您的第一个问题,这有帮助吗?图书馆(plyr); zoo.obj
  • @gd047:效果很好!但是把它放在一个答案中,这样我就可以给分了。

标签: r plot time-series zoo


【解决方案1】:

我不认为将数据分成三部分只是为了将它们组合在一起以绘制图表有什么意义。这是使用ggplot2 库的图:

library(ggplot2)
qplot(ob_time, dist.mean, data=data, colour=groupname, geom=c("line","point")) + 
  geom_errorbar(aes(ymin=dist.mean-dist.sd, ymax=dist.mean+dist.sd))

这会将时间值沿自然比例隔开,您可以使用scale_x_continuous 在实际时间值处定义刻度线。让它们等距分布比较棘手:您可以将ob_time 转换为一个因子,但随后qplot 拒绝将这些点与一条线连接。

解决方案 1 - 条形图:

qplot(factor(ob_time), dist.mean, data=data, geom=c("bar"), fill=groupname, 
      colour=groupname, position="dodge") + 
geom_errorbar(aes(ymin=dist.mean-dist.sd, ymax=dist.mean+dist.sd), position="dodge")

解决方案 2 - 使用因子的 1,2,... 重新编码手动添加行:

qplot(factor(ob_time), dist.mean, data=data, geom=c("line","point"), colour=groupname) +
  geom_errorbar(aes(ymin=dist.mean-dist.sd, ymax=dist.mean+dist.sd)) + 
  geom_line(aes(x=as.numeric(factor(ob_time))))

【讨论】:

    【解决方案2】:

    这暗示了我会尝试这样做的方式。我忽略了分组,因此您必须对其进行修改以包含多个系列。我也没有用过zoo,因为我知道的不多。

    g <- (nrow(data)-1)/(3*nrow(data))
    
    plot(data[,"dist.mean"],col=2, type='o',lwd=2,cex=1.5, main="This is the title of the graph",
     xlab="x-Label", ylab="y-Label", xaxt="n",
     ylim=c(0,max(data[,"dist.mean"])+max(data[,"dist.sd"])),
     xlim=c(1-g,nrow(data)+g))
    axis(side=1,at=c(1:nrow(data)),labels=data[,"ob_time"])
    
    for (i in 1:nrow(data)) {
    lines(c(i,i),c(data[i,"dist.mean"]+data[i,"dist.sd"],data[i,"dist.mean"]-data[i,"dist.sd"]))
    lines(c(i-g,i+g),c(data[i,"dist.mean"]+data[i,"dist.sd"], data[i,"dist.mean"]+data[i,"dist.sd"]))
    lines(c(i-g,i+g),c(data[i,"dist.mean"]-data[i,"dist.sd"], data[i,"dist.mean"]-data[i,"dist.sd"]))
    }
    

    【讨论】:

      【解决方案3】:

      使用带有 split= 参数的 read.zoo 读取数据,以按组名进行拆分。然后将 dist、lower 和 upper 线绑定在一起。最后绘制它们。

      Lines <- "groupname ob_time dist.mean  dist.sd dur.mean   dur.sd   ct.mean    ct.sd
      rowA     0.3  61.67500 39.76515 43.67500 26.35027  8.666667 11.29226
      rowA    60.0  45.49167 38.30301 37.58333 27.98207  8.750000 12.46176
      rowA   120.0  50.22500 35.89708 40.40000 24.93399  8.000000 10.23363
      rowA   180.0  54.05000 41.43919 37.98333 28.03562  8.750000 11.97061
      rowB   240.0  51.97500 41.75498 35.60000 25.68243 28.583333 46.14692
      rowB   300.0  45.50833 43.10160 32.20833 27.37990 12.833333 14.21800"
      
      library(zoo)
      # next line is only needed until next version of zoo is released
      source("http://r-forge.r-project.org/scm/viewvc.php/*checkout*/pkg/zoo/R/read.zoo.R?revision=719&root=zoo")
      z <- read.zoo(textConnection(Lines), header = TRUE, split = 1, index = 2)
      
      # pick out the dist and sd columns binding dist with lower & upper 
      z.dist <- z[, grep("dist.mean", colnames(z))]
      z.sd <- z[, grep("dist.sd", colnames(z))]
      zz <- cbind(z = z.dist, lower = z.dist - z.sd, upper = z.dist + z.sd)
      
      # plot using N panels
      N <- ncol(z.dist)
      ylab <- sub("dist.mean.", "", colnames(z.dist))
      plot(zz, screen = 1:N, type = "l", lty = rep(1:2, N*1:2), ylab = ylab)
      

      【讨论】:

        【解决方案4】:

        我认为您不需要为这种类型的绘图创建动物园对象,我会直接从数据框中创建。当然,使用 zoo 对象可能还有其他原因,比如智能合并、聚合等。

        一个选项是latticeExtra 中的segplot 函数

        library(latticeExtra)
        segplot(ob_time ~ (dist.mean + dist.sd) + (dist.mean - dist.sd) | groupname, 
            data = data, centers = dist.mean, horizontal = FALSE)
        ## and with the latest version of latticeExtra (from R-forge):
        trellis.last.object(segments.fun = panel.arrows, ends = "both", angle = 90, length = .1) +
            xyplot(dist.mean ~ ob_time | groupname, data, col = "black", type = "l")
        

        使用 Gabor 的重现性良好的数据集生成:

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-30
          • 2021-09-14
          • 2018-02-22
          • 2013-03-15
          • 1970-01-01
          相关资源
          最近更新 更多