I am trying to reorder categories in a ggplot bar chart by the size of the variables, with the biggest categories first, followed by increasingly minor ones. I've tried playing with the order in a few ways but only seem to be able to set the order manually which isn't very helpful for big data sets.
For example: Let's say I have the following data:
mydata <- read.table(header=TRUE, text="
shop    fruit   varieties   km_away
shop1   apple   0   12
                     shop1  banana  0   12
                     shop1  pear    2   12
                     shop1  melon   1   12
                     shop1  orange  1   12
                     shop1  peach   3   12
                     shop1  apricot 6   12
                     shop1  lime    1   12
                     shop2  apple   1   1
                     shop2  banana  0   1
                     shop2  pear    2   1
                     shop2  melon   2   1
                     shop2  orange  5   1
                     shop2  peach   4   1
                     shop2  apricot 11  1
                     shop2  lime    0   1
                     shop3  apple   0   2
                     shop3  banana  1   2
                     shop3  pear    2   2
                     shop3  melon   1   2
                     shop3  orange  4   2
                     shop3  peach   1   2
                     shop3  apricot 11  2
                     shop3  lime    1   2
                     shop4  apple   0   5
                     shop4  banana  0   5
                     shop4  pear    3   5
                     shop4  melon   2   5
                     shop4  orange  6   5
                     shop4  peach   1   5
                     shop4  apricot 9   5
                     shop4  lime    0   5
                     ")
I can usefully visualise it like this:
library(ggplot2)
library(RColorBrewer)
p <- ggplot(data = mydata, aes(x=reorder(shop, km_away), y=varieties, fill=fruit))+
  geom_bar(stat="identity") + coord_flip()+scale_fill_brewer(palette="Accent")
p
But how do I tell ggplot to plot the apricots first, then the oranges, etc? This will make it much easier to visually compare different categories across shops.
You can first obtain a vector of the categories, ordered by your quantity of interest:
fruit_levels <- names(sort(tapply(mydata$varieties, mydata$fruit, sum)))
Then, in your call to ggplot, map fill to a factor variable with the corresponding levels:
p <- ggplot(data = mydata, 
    aes(x=reorder(shop, km_away), y=varieties, 
        fill=factor(fruit, levels = fruit_levels)))+
  geom_bar(stat="identity") + coord_flip()+
  scale_fill_brewer(name = "fruit", palette="Accent") 
p
Output:

Update. A more direct route is to re-order the factor levels in your original dataframe, and call ggplot as in your original code:
mydata$fruit <- reorder(mydata$fruit, mydata$varieties, sum)
p <- ggplot(data = mydata, aes(x=reorder(shop, km_away), y=varieties, fill=fruit))+
  geom_bar(stat="identity") + coord_flip()+scale_fill_brewer(palette="Accent")
p
Update 2. On older versions of ggplot2 (pre version 2), try specifying the order aesthetic:
p <- ggplot(data = mydata, aes(x=reorder(shop, km_away), 
                               y=varieties, 
                               fill=fruit, order=fruit)) +
  geom_bar(stat="identity") + coord_flip()+scale_fill_brewer(palette="Accent")
p
And if you want to reverse the ordering, add a negative sign in front of the ordering variable:
reorder(mydata$fruit, -mydata$varieties, sum)
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With