0
library(tidyverse)
library(ggplot2)

I am attempting to create the bar chart below but I'm having trouble restructuring the data. I provided some sample data below which I created kind of fast, so the results may be strange, but I'm more interested in how to use tidyverse tools to set up the data.

Q1_Sat<-c("Sat","Sat","Sat","Other","Other","Other","Other","Other")
Q1_VSat<-c("VSat","Other","Other","VSat","VSat","VSat","VSat","VSat")
Q1_M<-c("SatVSat","SatVSat","SatVSat","SatVSat","Other","Other","SatVSat","SatVSat")
Q2_Sat<-c("Sat","Other","Sat","Other","Sat","Sat","Other","Other")
Q2_VSat<-c("VSat","Other","VSat","Other","VSat","VSat","VSat","VSat")
Q2_M<-c("SatVSat","SatVSat","SatVSat","SatVSat","SatVSat","SatVSat","SatVSat","Other")
Q3_Sat<-c("Sat","Other","Sat","Other","Sat","Sat","Sat","Sat")
Q3_VSat<-c("VSat","Other","VSat","Other","Other","Other","Other","VSat")
Q3_M<-c ("SatVSat","SatVSat","SatVSat","Other","Other","Other","Other","Other")

Q4_Sat<-c("Sat","Other","Other","Other","Other","Other","Other","Other")
Q4_VSat<-c("VSat","VSat","VSat","VSat","VSat","VSat","VSat","VSat")
Q4_M<-c("SatVSat","Other","Other","Other","Other","Other","SatVSat","SatVSat")

Q20<-c("Nat","Internat","Nat","Nat","Internat","Internat","Nat","Nat")
Calc_Sat<-c("Sat","Sat","Sat","Other","Other","Other","Sat","Sat")
Calc_VSat<-c("Other","Other","VSat","VSat","VSat","VSat","Other","VSat")
PCode<-c("C11","C11","H12","F33","F33","C11","S33","F33")
CCode<-c("Dept","Camit","Camit","CCT","Dept","CCT","TTT","CCT")
Data<-data_frame(Q1_Sat,Q1_VSat,Q1_M,Q2_Sat,Q2_VSat,Q2_M,Q3_Sat,Q3_VSat,Q3_M,Q4_Sat,Q4_VSat,Q4_M,Q20,PCode,CCode,Calc_Sat,Calc_VSat)

Below is the code I've developed so far but I'm stuck at this point and not sure how to incorporate the Q20 variable for the coloured grouped bars. I would like to use Tidyverse and ggplot2 to achieve this. Any other feedback about how to make my code more elegant and compact would also be greatly appreciated.

Data%>%
select(-CCode,-Q1_M,-Q2_M,-Q3_M,-Q4_M)%>%
gather(key,value,-PCode,-Q20)%>%
filter(PCode=="C11")%>%
count(Q20,key,value)%>%
mutate(perc=round(n/sum(n),2))%>%
separate(key,c("Question","SatLevel"),sep="_")%>%
filter(value != "Other")%>%
ggplot(aes(x=Question,y=perc,fill=SatLevel))+geom_col()

enter image description here

Mike
  • 2,017
  • 6
  • 26
  • 53

1 Answers1

0

Generally, ggplot requires long-format tables, and your data seems to be wide. I.e., in the end your data should look something like:

Q barColor barShade Y
1 grey light 55
1 grey dark 20
1 blue light 57
1 blue dark 21
2 grey light 23
...

so that you could call ggplot with aes(color=barColor, y=Y) etc.
I'd say tidyr::gather should take care of most of the restructuring, but see also this great cheatsheet for other helpful tools.


Edit: possible solution for stacked+grouped barplots, without using facet_wrap:

df = Data%>%
    select(-CCode,-Q1_M,-Q2_M,-Q3_M,-Q4_M)%>%
    gather(key,value,-PCode,-Q20)%>%
    filter(PCode=="C11")%>%
    count(Q20,key,value)%>%
    mutate(perc=round(n/sum(n),2))%>%
    separate(key,c("Question","SatLevel"),sep="_")%>%
    filter(value != "Other") df$Question = c(14, 14, 1, 1, 4, 4, 7, 10,
                15, 2, 2, 5, 5, 8, 8, 11, 11)

ggplot(df, aes(x=Question,y=perc,fill=SatLevel)) + geom_col() +
    theme_bw() +
    scale_x_continuous(breaks=c(1.5, 4.5, 7.5, 10.5, 14.5),
                       labels=c("Q1", "Q2", "Q3", "Q4", "Calc"))

enter image description here

juod
  • 440
  • 3
  • 8
  • Thanks for the pointers. I added code to show what I've tried so far and where I'm stuck. I've restructured the data to look like your example, but I'm not sure how to proceed further... – Mike May 22 '17 at 18:55
  • @Mike So now the issue is making a bar chart with both stacks and groups? A quick search here on SO gives [this](https://stackoverflow.com/questions/13486501/stacked-bars-within-grouped-bar-chart) solution, with `facet_wrap`. If you don't like the separate facets, you can make a fake x variable to map the bars precisely where you want (e.g. 1, 4, 7... for grey bars, 2, 5... for the blue ones, 3, 6... for spaces). Fixing the tick mark text should be easy then. Can't say more without having the actual data though. – juod May 23 '17 at 13:47
  • Can you provide the code for the sample data I provided in the post? I provided some code to show what I've tried so far...it's pretty close. If you can reproduce it and show how to make the attached chart, I can then give you the credit. I appreciate the help so far..... – Mike May 24 '17 at 03:30
  • @Mike edited to detail what I mean by fake x variable mapping. Code for the `facet_wrap` solution is provided in the answer linked before. – juod May 24 '17 at 05:54