-1

I have a file with data as shown below:

  test  <- data.frame(Group=c("A", "B", "C", "D", "E"), 
                value1=c(100,150,120,80,150),     
                value2=c(25,30,45,30,30) , 
                value3=c(100,120,150,150,200),
                value4=c(30,45,65,45,30)) 

I would like to create a grouped barplot for each 'Group' where value1 and value2 are stacked into 1 bar and value3 and value 4 are stacked into another bar.

P:S: Value2 should be a subset of value1 and Value4 as a subset of value3 in the bar.

Could it be possible in R.

chas
  • 1,565
  • 5
  • 26
  • 54
  • Judging from most of the questions on grouped and stacked charts, [here](http://stackoverflow.com/questions/18774632/how-to-produce-stacked-bars-within-grouped-barchart-in-r) and [here too](http://stackoverflow.com/questions/13486501/stacked-bars-within-grouped-bar-chart) It looks like `facet_grid` is the way to go. Someone did use manipulation of the data, but I'm not sure how it would apply here [this question](http://stackoverflow.com/questions/18081102/r-bar-plot-with-two-groups-of-which-one-is-stacked). Hope that helps. – Pierre L Sep 24 '15 at 09:33
  • I looked into those, but looks slightly different from what i need. Here i have pair of columns where each pair has to be stacked into one bar. – chas Sep 24 '15 at 09:42
  • Yes I understand what you are looking for. The only way is to either use facet_grid or abandon the five groups and turn them into 10 groups as Heroka kindly demonstrated. – Pierre L Sep 24 '15 at 09:43
  • i still did not get what you mean. I have used facet_grid which gives the second plot given by Heroka. However, the values in the stack are present on top of the other but not within the limits of the max value. – chas Sep 24 '15 at 10:22
  • subtract value 2 from value 1. In the first example that is 100 - 25. Which gives 75.If you stack 75 and 25 you will get your desired output – Pierre L Sep 24 '15 at 10:27

2 Answers2

2

We need to do some data-reshaping first, as each points needs al the info associated with it on it's own row.

library(reshape2)
library(ggplot2)
m_test <- melt(test,id.var="Group")

#generate a grouping variable to separate the two bars.
#currently done by comparing variable names.
m_test$subvar <- as.numeric(m_test$variable %in% c("value3","value4"))

test2 <- dcast(Group+subvar+variable~"value",value.var="value",data=m_test)
#reverse for proper plotting
test2 <- test2[rev(order(test2$variable)),]
> head(test2)
   Group subvar variable value
20     E      1   value4    30
16     D      1   value4    45
12     C      1   value4    65
8      B      1   value4    45
4      A      1   value4    30
19     E      1   value3   200

Then we can either plot like this:

p1 <- ggplot(test2, aes(x=interaction(subvar,Group),y=value,fill=variable))+
  geom_bar(stat="identity")
p1

enter image description here

Or use facets:

p2 <- ggplot(test2, aes(x=factor(subvar),y=value, fill=variable))+
  geom_bar(stat="identity")+facet_grid(.~Group)
p2

enter image description here

Heroka
  • 12,889
  • 1
  • 28
  • 38
  • It looks nearly working. But, for instance in the first stacked bar the value1 is 100 and value 2 is 25. The total value in the stack should be 100 and 25 should be represented within the 100. Currently, it shows 25 and 100 which totals 125. – chas Sep 24 '15 at 09:52
  • @chas In your question, when you say "should be a subset of", it isn't clear what the expected outcome is. "value 1" needs to be "value1 - value2" in the data. – Pierre L Sep 24 '15 at 09:58
  • To make it simple, value 2 should be represented as value within value1. i.e. in this case value2 is 25 and value1 is 100, so the bottom value 25 should represent value2 and the top value until 100 should represent value1 – chas Sep 24 '15 at 10:03
  • That means value 2 is 25 and value 1 is 75. So what you should do is subtract value 2 from value 1 and plot it as above. – Pierre L Sep 24 '15 at 10:25
  • I got it how to make it work. If i have more variables, i.e. value 5 and value6, value 7 and value 8, could it be possible to extend the code? it looks like it has to do with 'm_test$subvar <-as.numeric(m_test$variable %in% c("value3","value4"))' in the code. Could someone let me know what it means and how it can be extended to more variables? – chas Sep 24 '15 at 10:42
  • You can just add the variable names to the comparison. Experiment with what happens if you do `c("value2","value3","value4")` in that position. And I'm with @PierreLafortune; your description was a bit unclear. – Heroka Sep 24 '15 at 11:15
0

I found that I needed to re-write your input data as follows,

test  <- data.frame(Group=c("A", "B", "C", "D", "E"), 
                    value1=c(100,150,120,80,150),     
                    value2=c(25,30,45,30,30) , 
                    value3=c(100,120,150,150,200),
                    value4=c(30,45,65,45,30), stringsAsFactors=F)

note the stringsAsFactors=F argument.

I got what (I think) you want from the following,

barplot(as.matrix(t(test[,-1])), names.arg=test[,1])

You need to play around with the colours and labels.

DarrenRhodes
  • 1,431
  • 2
  • 15
  • 29
  • Nope. I would need, for each Group, one stacked bar for value1 and value2 and another stacked bar for value3 and value4. – chas Sep 24 '15 at 09:14
  • @chas I'm not sure what you mean but I see your point: you can only tell us by having the code to show us. – DarrenRhodes Sep 24 '15 at 09:19
  • i am playing around the code at 'http://stackoverflow.com/questions/18774632/how-to-produce-stacked-bars-within-grouped-barchart-in-r' this has three values where value 2 and value 3 are stacked. In my case i have 4 values where value 1 and value 2 should be stacked into 1 bar and value 3 and value 4 should be stacked into 1 bar. – chas Sep 24 '15 at 09:33