using sapply in R for ploting side by side graph

帅比萌擦擦* 提交于 2019-12-10 19:17:26

问题


I have the following code:

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)

The above code should plot two barplots using the side-by-side feature as follow:

unfortunatly I only get one plot, which is incorrect, and the code is inspired from this post


回答1:


The easiest way for me to get the ggplot-like faceting is to write a function that takes a subset of data and use that on a split, eg,

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)




回答2:


Here's a ggplot solution:

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)

This is how the result looks like:

In case you want to plot the two graphs side by side, specify ncol = 2 instead.

If you want to use your existing code, try reshaping your dataset beforehand such that the T1..T6 are your columns:

library(reshape2)

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



回答3:


Use 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)
       }
)


来源:https://stackoverflow.com/questions/36845682/using-sapply-in-r-for-ploting-side-by-side-graph

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!