Stacked bar chart with side-by-side in R ggplot

2019-09-14 15:42发布

问题:

 library(plyr)
 library(ggplot2)

 period <- c("period 0","period 1","period 1","period 1","period 1","period   1","period 2","period 2","period 2","period 2","period 2","period 2","period 2", "period 2","period 2","period 3","period 3","period 3","period 3","period 3","period 3","period 3.5","period 3.5","period 3.5","period 4","period 4",   "period 4","period 4","period 4","period 4","period 4","period 5","period 5","period 5","period 5","period 5","period 5","period 5","period 6","period 7")

 teacher <- c("17","14","17","20","22","23","13","15","17","19","20","22", "23","24","25","14","17","20","22","23","24","20","22","24","13","15","16","17", "20","21","22","14","15","18","19","20","22","23","18","20")

 qty <- c(2,1,2,2,1,1,4,1,1,1,1,5,4,1,1,2,13,2,2,1,1,2,1,3,4,1,1,7,2,1,1,1,  6,5,2,2,3,2,1,2)

 ref_by_period_df <- data.frame(Period=period,Teacher=teacher,Qty=qty)
 ref_by_period_df <- ddply(ref_by_period_df, .(Period), transform, pos = cumsum(Qty) - (0.5 * Qty))

 ref_by_period <- ggplot(ref_by_period_df, aes(x=Period,y=Qty))+
                  geom_bar(aes(fill=Teacher),stat="identity")+
                  geom_text(aes(label=Qty,x=Period,y=pos),size=3)+
                  labs(y="Referral Count",x=NULL,title="Frequency of referrals by period by teacher")+
                  theme(axis.text.x = element_text(angle = 90, hjust = 1))  

Hello wonderful people of stack exchange, this data and code get me the graphic I want. However, I now want to compare this data with side-by-side bars in 6 week intervals. I want to keep the stacks, but now I'll have additional side-by-side stacks (There will be a total of 6: H1,H2,H3,H4,H5,H6). Thus for Period 1, I'd like to see 6 side by side stacks. But I can't figure out how to tell ggplot to do a side-by-side based upon the new variable field "Hex". When I put the position="dodge" into the geom_bar, get H1,H2 side by side, but then period 0-7 to the right of it....The result was undesirable. Any help would be appreciated.

So my new data would look like this:

 hex1 <- c("H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1", "H1" ,"H1", "H1", "H1", "H1", "H1", "H1","H1", "H1", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2", "H2")

 Period1 <- c("period 0",   "period 1",   "period 1",   "period 1",   "period 1",   "period 2",   "period 2",   "period 2",   "period 2",   "period 2", "period 3",   "period 3",   "period 3",   "period 3",   "period 3",   "period 3.5", "period 3.5", "period 4",   "period 4",   "period 4",  "period 4",   "period 4",   "period 5",   "period 5",   "period 5",   "period 5",   "period 5",   "period 5",   "period 7",   "period 0", "period 1",   "period 2",   "period 2",   "period 2",   "period 2" ,  "period 2",   "period 3",   "period 3",   "period 3",   "period 3.5", "period 4",   "period 4" ,  "period 4",   "period 5",   "period 5",   "period 5",   "period 5",   "period 6")

 Teacher1 <- c("17", "14", "17", "20", "23", "13", "19", "20", "22", "23", "14" ,"17", "20", "23", "24", "22", "24", "13", "16", "17", "20", "21", "14", "15", "18", "20", "22","23", "20", "17", "22", "13", "15", "17", "24", "25", "14", "17", "22", "20", "15", "17", "22", "15" ,"18", "19", "22", "18")

 Qty1 <- c(1, 1, 2, 2, 1, 3, 1, 1, 5, 4, 1, 9, 2, 1, 1, 1, 3, 4, 1, 5, 2, 1, 1, 5, 3, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 4, 2, 2, 1, 2, 1, 1, 2, 2, 2, 1)


 ref_by_period_df <- data.frame(Hex=hex1,Period=Period1,Teacher=Teacher1,Qty=Qty1)
 ref_by_period_df <- ddply(ref_by_period_df, .(Period), transform, pos = cumsum(Qty) - (0.5 * Qty)) #Now let's calculate midpoint
 ref_by_period <- ggplot(ref_by_period_df, aes(x=Period,y=Qty))+
    geom_bar(aes(Hex,fill=Teacher),stat="identity",position="dodge")+
    geom_text(aes(label=Qty,x=Period,y=pos),size=3)+
    labs(y="Referral Count",x=NULL,title="Frequency of referrals by period by teacher")+
    theme(axis.text.x = element_text(angle = 90, hjust = 1))
    #This puts H1,H2 on the left, Period 0-7 on the right. Bars appear for H1,H2, but not for the Periods.  The numerical values appear for the periods, but they are not correct.

回答1:

Faceting would work well here. It doesn't look exactly as you wanted it, but it should get the message across.

# Data  
Hex <- sample(c("H1","H2","H3","H4","H5","H6"),size = 100,replace = TRUE)
Period <- sample(c("period 0",   "period 1","period 2", "period 3","period 3.5", "period 4","period 5",   "period 7"),size = 100, replace = TRUE)
Teacher <- sample(c("13","14","15","16","17","18","19","20","21","22","23","24","25"), size = 100, replace = TRUE)
Qty <- sample(c(1:9), size = 100, replace = TRUE)

ref_by_period_df <- data.frame(Hex=Hex,Period=Period,Teacher=Teacher,Qty=Qty)
ref_by_period_df <- ddply(ref_by_period_df, .(Period), transform, pos = cumsum(Qty) - (0.5 * Qty)) #Now let's calculate midpoint


# Plotting
ggplot(ref_by_period_df, aes(x = Hex, y = Qty, fill = Teacher)) + 
  geom_bar(stat="identity") + 
  facet_grid(.~Period) +
  theme(axis.text.x = element_text(angle = 90, size = 8))



标签: r ggplot2