How to show bars in ggplot2 in descending order of a numeric vector?

Michael Bellhouse picture Michael Bellhouse · Sep 15, 2013 · Viewed 10.1k times · Source
df <- data.frame (Categories=c("Alpha Category", "Alpha Category", 
                               "Alpha Category", "Bravo Category", 
                               "Bravo Category", "Bravo Category", 
                               "Charlie Category", "Charlie Category", 
                               "Charlie Category"),  
                  choices=c("alpha1", "alpha2", "alpha3", "bravo1", 
                            "bravo2", "bravo3", "charlie1", "charlie2",
                            "charlie3")  , 
                  ratings=c(20,60,40, 55,75,25,65,35,45))    
df.plot <- ggplot(df, aes(Categories, ratings, fill = choices))
           + geom_bar(position="dodge", stat="identity") 
           + coord_flip()    
df.plot <- df.plot 
           + theme_classic(base_size = 16, base_family = "")  
           + scale_fill_brewer(palette="Paired")    
df.plot <- df.plot 
           + scale_y_continuous(breaks=seq(0,100,by=10),limits=c(0,80) )  
           + ylab("Ratings")  
           + theme(axis.text.y = element_text(size=16)) #change font size of y axis label   
df.plot

Most importantly, I would like to show the "choices" within each "category" in descending order of their "ratings", for example here "Charlie Category" would show charlie1, then charlie3, then charlie2.

I have honestly looked online for solutions for about a week but can't find it. My current thoughts is that I should convert the choices into factors but I haven't figured out how to do this properly.

Of secondary importance, it would be great if the "categories" could be listed, from the top down, "Alpha Category", "Bravo category", "Charlie Category" rather than in the inverse order as seems to occur when coordinates are flipped

Answer

Metrics picture Metrics · Sep 15, 2013
library(ggplot2)
df.plot <- ggplot(df, aes(x=Categories,y=reorder(choices,ratings), fill = choices)) +
  geom_bar(position = "dodge", stat = "identity") + coord_flip() +
  scale_x_discrete(limits = rev(levels(df$Categories)))

enter image description here