0

I want to plot something like this in R.

enter image description here

I found some similar solution here so I tried something similar:

test  <- data.frame(person=c("group 1", "group 2", "group 3"), 
                value1=c(100,150,120),  # male   
                value2=c(25,30,45) ,    # female
                value3=c(25,30,45),     # male
                value4=c(100,120,150),  # female
                value5=c(10,12,15),     # male
                value6=c(50,40,70))     # female

library(reshape2) # for melt

melted <- melt(test, "person")

melted$cat <- ''
melted[melted$variable == 'value1' | melted$variable == 'value2',]$cat <- "sub group 1"
melted[melted$variable == 'value3' | melted$variable == 'value4',]$cat <- "sub group 2"
melted[melted$variable == 'value5' | melted$variable == 'value6',]$cat <- "sub graoup 3"

p = ggplot(melted, aes(x = cat, y = value, fill = variable)) 
    + geom_bar(stat = 'identity', position = 'stack') + facet_grid(~ person)

What I ended with is:

enter image description here

The problem is now I have 6 different values with 6 different colors. What I really want is 2 different values, let's call theme male and female represented by 2 different colors.

How can I do it in R? The data can be constructed in any different way (doesn't have to use data.frame as above). I don't need to use ggplot. In fact, I prefer the white clean background in example image than the grey background I got using ggplot.

Community
  • 1
  • 1
chepukha
  • 2,371
  • 3
  • 28
  • 40

1 Answers1

0

You could just add another variable to your melted data frame holding the gender information and then plot in ggplot. The background can also be easily changed to white. I edited your code example and posted it below.

I hope this helps!

test  <- data.frame(person=c("group 1", "group 2", "group 3"), 
                value1=c(100,150,120),  # male   
                value2=c(25,30,45) ,    # female
                value3=c(25,30,45),     # male
                value4=c(100,120,150),  # female
                value5=c(10,12,15),     # male
                value6=c(50,40,70))     # female

library(reshape2) # for melt

melted <- melt(test, "person")

melted$cat <- ''
melted[melted$variable == 'value1' | melted$variable == 'value2',]$cat <- "sub group 1"
melted[melted$variable == 'value3' | melted$variable == 'value4',]$cat <- "sub group 2"
melted[melted$variable == 'value5' | melted$variable == 'value6',]$cat <- "sub group 3"
melted$gender <- ''
melted[melted$variable %in% sprintf("value%i",c(1,3,5)),]$gender <- "female"
melted[melted$variable %in% sprintf("value%i",c(2,4,6)),]$gender <- "male"


p = ggplot(melted, aes(x = cat, y = value, fill = gender)) 

p + geom_bar(stat = 'identity', position = 'stack') +   facet_grid(~ person) + 
scale_fill_manual(values = c("orangered","dodgerblue2")) + 
theme(panel.background = element_rect(fill = 'white'))
sam
  • 158
  • 7
  • Thanks for your response, @sam. I got an error `Error: No layers in plot` running that snippet. It doesn't point to any line, a very general error. – chepukha Oct 30 '15 at 15:16
  • I tried adding `+ geom_line()` to the end but getting the same error. BTW, I use `print(p)` to display the graph. – chepukha Oct 30 '15 at 15:20
  • it's working well now. But ggplot sorts the label `c("group 1", "group 2", "group 3")` and order the groups on the plot according to alphabetical order. E.g. if I have `person=c('Eroupean', 'Asian', 'Ameria')`, then `America` group is always displayed first. Is there any way I can tell `ggplot` to just use the order as it is? Thanks – chepukha Oct 30 '15 at 18:32
  • Hi! Glad, that it worked. You can get the order you want by ordering the levels of the respective factors in a way like this before plotting: `melted$person <- factor(melted$person,levels = c("group 2","group 1","group 3"),ordered = T)` `melted$cat <- factor(melted$cat,levels = c("sub group 3","sub group 1","sub group 2"),ordered = T)` Hope this helps! – sam Nov 02 '15 at 06:32