【问题标题】:using sapply in R for ploting side by side graph在 R 中使用 lapply 绘制并排图
【发布时间】:2016-04-25 16:06:46
【问题描述】:

我有以下代码:

dat <- read.table(text="Topic  Project  C10     C14     C03     C11     C16     C08
                        T1     P1       0.24    0.00    0.00    0.04    0.04    0.00
                        T2     P1       0.00    0.30    0.00    0.00    0.00    0.00
                        T3     P1       0.04    0.04    0.00    0.24    0.00    0.00
                        T4     P1       0.00    0.00    0.00    0.04    0.33    0.04
                        T5     P1       0.00    0.09    0.21    0.00    0.00    0.00
                        T6     P1       0.00    0.09    0.00    0.00    0.00    0.34
                        T1     P2       0.20    0.00    0.00    0.04    0.00    0.04
                        T2     P2       0.00    0.22    0.04    0.00    0.00    0.00
                        T3     P2       0.04    0.00    0.00    0.24    0.00    0.00
                        T4     P2       0.00    0.00    0.04    0.00    0.33    0.00
                        T5     P2       0.04    0.00    0.21    0.00    0.00    0.00
                        T6     P2       0.00    0.04    0.00    0.00    0.00    0.34",
                        header=TRUE)
layout(matrix(c(1,2,5,3,4,5),nrow=2,byrow = TRUE))
#     [,1] [,2] [,3]
#[1,]    1    2    5
#[2,]    3    4    5
barcols <- c("red","blue","green","orange","black","yellow")
sapply(3:8, 
  function(x) {
    bp <- barplot(matrix(dat[,x],nrow=2,byrow=TRUE),ylim=c(0, 0.5),beside=TRUE,col=barcols)
    title(main=names(dat[x]))
    axis(1,at=colMeans(bp),c("T1","T2","T3","T4","T5","T6"),lwd=0,lwd.tick=1)
    abline(h=0)
  }
)
plot(NA,xlim=c(0,1),ylim=c(0,1),ann=FALSE,axes=FALSE)
legend(0,0.6,c("C10","C10","C03","C11","C16","C08"),fill=barcols,cex=1.5)

上面的代码应该使用并排功能绘制两个条形图,如下所示:

不幸的是我只得到了一个情节,这是不正确的,代码的灵感来自这个post

【问题讨论】:

  • 在链接的情况下,使用ggplot2.. 会容易得多。

标签: r plot bar-chart sapply


【解决方案1】:

对我来说,获得类似 ggplot 的分面的最简单方法是编写一个函数,该函数采用数据子集并在 split 上使用它,例如,

dat <- read.table(text="Topic  Project  C10     C14     C03     C11     C16     C08
                        T1     P1       0.24    0.00    0.00    0.04    0.04    0.00
                        T2     P1       0.00    0.30    0.00    0.00    0.00    0.00
                        T3     P1       0.04    0.04    0.00    0.24    0.00    0.00
                        T4     P1       0.00    0.00    0.00    0.04    0.33    0.04
                        T5     P1       0.00    0.09    0.21    0.00    0.00    0.00
                        T6     P1       0.00    0.09    0.00    0.00    0.00    0.34
                        T1     P2       0.20    0.00    0.00    0.04    0.00    0.04
                        T2     P2       0.00    0.22    0.04    0.00    0.00    0.00
                        T3     P2       0.04    0.00    0.00    0.24    0.00    0.00
                        T4     P2       0.00    0.00    0.04    0.00    0.33    0.00
                        T5     P2       0.04    0.00    0.21    0.00    0.00    0.00
                        T6     P2       0.00    0.04    0.00    0.00    0.00    0.34",
                  header=TRUE)


layout(matrix(c(1,1,2,2,3,3),nrow=2))
barcols <- c("red","blue","green","orange","black","yellow")

sp <- split(dat, dat$Project)

sapply(seq_along(sp),
       function(x) {
         dd <- sp[[x]]
         m <- t(`rownames<-`(as.matrix(dd[, -(1:2)]), dd[, 1]))
         bp <- barplot(m,ylim=c(0, 0.5),beside=TRUE,col=barcols)
         title(main=names(sp[x]))
         abline(h=0)
       }
)
plot(NA,xlim=c(0,1),ylim=c(0,1),ann=FALSE,axes=FALSE)
legend(0,0.6,c("C10","C10","C03","C11","C16","C08"),fill=barcols,cex=1.5)

【讨论】:

  • 这实际上是我想要的。问题:如果我想绘制与 P1 和 P2 相同的 15 个项目 (Ps) 数据集怎么办,我应该怎么做才能使所有 15 个图形保持在相同的布局上?
  • @Sultan 取决于整体数字的大小和文本的大小。如果从图形中提取有用信息需要花费太多工作,那么最好的办法是尝试其他方法
  • 数据集的大小将与 P1 和 P2 的样式相同,但将包括 P3 到 P15。数字大小对我来说是个问题,我想保持所有人(P1 到 P15)的质量和可读性,并且它们必须在同一个框架中!!。您对此有什么建议,以及如何使用相同的代码进行操作?我想将结果打印成 PDF 文件。
  • @Sultan 我会使用par(mfrow = c(5,3)) 或类似 tim 建议的东西。对于 pdf,您可以根据需要将其放大:pdf('plot.pdf', width = 9, height = 15); plot code; dev.off() 调整 par(mar) 设置或使设备更大
  • 我这样做了,但问题是,它将数字绘制成 pdf 的单独页面!
【解决方案2】:

这是ggplot 解决方案:

library(ggplot2)
library(reshape2)

meltData <- melt(dat, id = c("Topic", "Project"))
ggplot(meltData) +
   geom_bar(aes(x = Topic, y = value, fill = variable), stat = "identity", 
            position = "dodge") +
   facet_wrap(~Project, nrow = 2)

结果如下所示:

如果您想并排绘制两个图表,请指定ncol = 2

如果您想使用现有代码,请尝试预先调整您的数据集,使 T1..T6 成为您的列:

library(reshape2)

longFormat <- melt(dat, id = c("Topic", "Project"))
wideFormat <- dcast(longFormat, Project + variable ~ Topic, value.var = "value")

【讨论】:

  • 我尝试了第一个代码,但没有显示结果!第二个代码给出错误Error in eval(expr, envir, enclos) : could not find function "cast" 仅供参考:我的 R 版本 3.2.4,这有什么不同吗?
  • 哎呀我的错。该函数称为dcast。我会编辑答案。我还将添加一张运行 ggplot 版本时得到的图片。
  • 我尝试运行 ggplot2,它运行没有错误,但没有显示数字。仅供参考:我的 R 版本 3.2.4,这有什么不同吗? 'library(reshape2) library(ggplot2) dat
  • 这很奇怪。不知道版本有没有区别,我还有3.2.3。
【解决方案3】:

使用par(mfrow=c(3, 3)):

par(mfrow=c(3, 3))
sapply(3:8, 
       function(x) {
          bp <- barplot(matrix(dat[,x],nrow=2,byrow=TRUE), ylim=c(0, 0.5), beside=TRUE, col=barcols)
          title(main=names(dat[x]))
          axis(1,at=colMeans(bp), c("T1","T2","T3","T4","T5","T6"), lwd=0, lwd.tick=1)
          abline(h=0)
       }
)

【讨论】:

  • 它显示了 6 个地块!!而我的数据仅涉及两个项目(P1 和 P2),如问题图中所示。
  • 不,你循环了 6 次,每次都调用 barplot()。因此,应该有 6 个地块。
  • 我怎样才能将 P1 和 P2 设为两个 .. 我刚刚意识到 barplot 在列上遍历,而我只希望 P1 和 P2 使用它。
  • 所以您想要一组 6 个柱(每个 C10 .. C08 一个柱)用于每个 T1...T6?
  • 有你不想使用ggplot2的原因吗?
猜你喜欢
  • 2020-04-29
  • 1970-01-01
  • 1970-01-01
  • 2021-12-07
  • 2016-09-10
  • 1970-01-01
  • 2018-02-19
  • 1970-01-01
  • 2017-06-07
相关资源
最近更新 更多