0
votes

I want to plot a grouped bar chart. The dataset which I'm using for a plot is very large. Here is a small subset of it:

Label size
x     2 3 4 5 
y     2 6 8
z     1 6 8 
a     2 2 
b     4 7 9 10 11
c     8 12

I want to plot a bar-chart in which, on x axis there would be labels, and on y axis there would be multiple bars of sizes given.

For example here, x has sizes 2 3 4 5. So there would be four bars with heights 2, 3 , 4 and 5. Then y has sizes 2 6 8. So there would be 3 bars with sizes 2, 6 and 8 and so on.

Can any one help me out?

1
Please share your data in a reproducible format, like dput(droplevels(head(mydata))).Gregor Thomas
The output of dput is: structure(list(Label = structure(c(4L, 5L, 6L, 1L, 2L, 3L), .Label = c("a", "b", "c", "x", "y", "z"), class = "factor"), size = structure(c(3L, 4L, 1L, 2L, 5L, 6L), .Label = c("1 6 8 ", "2 2 ", "2 3 4 5 ", "2 6 8", "4 7 9 10 11", "8 12"), class = "factor")), .Names = c("Label", "size"), row.names = c(NA, 6L), class = "data.frame")jasp singh

1 Answers

4
votes

First let's save your data as a data.frame with two columns for the label and size.

mydata <- read.table(textConnection('
label\tsize
x\t2 3 4 5
y\t2 6 8
z\t1 6 8
a\t2 2
b\t4 7 9 10 11
c\t8 12
'),header=TRUE,sep="\t")

Show it in R,

> mydata
  label        size
1     x     2 3 4 5
2     y       2 6 8
3     z       1 6 8
4     a         2 2
5     b 4 7 9 10 11
6     c        8 12

Then is the tricky part. We save each individual value of the size in a matrix and fill with NA for shorter rows. This is inspired by this post.

mylist <- strsplit(as.character(mydata[,"size"])," ")
n <- max(sapply(mylist, length))
mymatrix <- apply(do.call(rbind, lapply(mylist, `[`, seq_len(n))),1,as.numeric)

The matrix looks like,

> mymatrix
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    2    2    1    2    4    8
[2,]    3    6    6    2    7   12
[3,]    4    8    8   NA    9   NA
[4,]    5   NA   NA   NA   10   NA
[5,]   NA   NA   NA   NA   11   NA

Finally we are ready to make the plot!

barplot(
  mymatrix, beside=TRUE, 
  col=1:n, 
  names.arg=mydata$label)

enter image description here