3

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: enter image description here

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

Community
  • 1
  • 1
Sultan
  • 189
  • 2
  • 9

3 Answers3

4

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)

enter image description here

rawr
  • 20,481
  • 4
  • 44
  • 78
  • this is actually what I want. Question: what if I want to plot 15 projects (Ps) dataset same as P1 and P2, what should I do to keep all 15 figures on the same layout? – Sultan Apr 25 '16 at 17:50
  • @Sultan depends on how large the overall figure is and how small the text will be. If it takes too much work to extract useful info from a figure, your best bet is to try something else – rawr Apr 25 '16 at 18:01
  • the size for the data-set will the same style of P1 and P2 but will include P3 to P15. The figures size is the issue for me, I would like to keep the quality and readability for all (P1 to P15) and they have to be in the same frame !!. Do you have suggestion for that, and how to do it using the same code? I would like to print out the results into PDF file. – Sultan Apr 25 '16 at 18:45
  • @Sultan I would use `par(mfrow = c(5,3))` or something like tim suggested. for a pdf, you can just make it as big as you need: `pdf('plot.pdf', width = 9, height = 15); plot code; dev.off()` adjust the `par(mar)` settings or make the device even bigger – rawr Apr 25 '16 at 19:09
  • I did that, but the issue, it plot the figures into a separated pages of the pdf !! – Sultan Apr 25 '16 at 21:26
  • @Sultan did you use mfrow after pdf? – rawr Apr 25 '16 at 21:29
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: ggplot version

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")
denise
  • 149
  • 14
  • I tried with the first code and it did not show the results !! the second code gives error `Error in eval(expr, envir, enclos) : could not find function "cast"` FYI: my R version 3.2.4, does that make difference? – Sultan Apr 25 '16 at 16:58
  • oops my bad. the function is called `dcast`. I'll edit the answer. I'll also add a picture of what I get when running the ggplot version. – denise Apr 25 '16 at 17:02
  • I tried to run ggplot2, it runs without errors but it did not show the figures. FYI: my R version 3.2.4, does that make difference? 'library(reshape2) library(ggplot2) dat <- read.table(text="....", header=TRUE) 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)' – Sultan Apr 25 '16 at 17:24
  • That's strange. Not sure if the version makes a difference, I still have 3.2.3. – denise Apr 25 '16 at 17:40
1

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)
       }
)
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • it shows 6 plots !! while my data is about only two projects (P1 and P2) as I showed in the figure of the question. – Sultan Apr 25 '16 at 16:16
  • 2
    No, you are looping 6 times and calling `barplot()` each time. Therefore, there _should_ be 6 plots. – Tim Biegeleisen Apr 25 '16 at 16:17
  • How could I make it two for P1 and P2.. i just realized that the barplot traverse on columns, while I want it for P1 and P2 only. – Sultan Apr 25 '16 at 16:19
  • so you want a group of 6 bars (one bar for each C10 .. C08) for each T1...T6? – denise Apr 25 '16 at 16:26
  • is there a reason why you don't want to use `ggplot2`? – denise Apr 25 '16 at 16:38
  • I'm not an expert in R plotting, I was only trying to fix the code in the OP. If you feel `ggplot2` would be a better choice then feel free to post an answer. – Tim Biegeleisen Apr 25 '16 at 16:40
  • I didn't use before, and the data in this example is for two projects (P1, and P2) while the original data will include 15 projects. – Sultan Apr 25 '16 at 16:42