1

I'm facing an issue with sorting bars when using facet_wrap (which is commonly reported here, here and others) after group variables and get top values. When I run the code without factor conversion, bars are ordered:

iris %>% 
  gather(key = measurements, value = values, - Species) %>% 
  mutate(kk = factor(measurements, levels = unique(.$measurements)),
         species_l = with(., paste(Species, .$measurements, sep = "_"))) %>% 
  ggplot(aes(x = reorder(species_l, values),
             y = values, 
             fill = kk)) +
  geom_bar(stat = "identity") +
  facet_wrap(.~kk,
             scales = "free")

But now I want to order decreasingly bars within facet_wrap and after top_n. Heres is what I've tried so far:

library(tidyverse)
iris %>% 
  gather(key = measurements, value = values, - Species) %>% 
  within(., 
         Species <- factor(Species, 
                          levels=names(sort(table(Species), 
                                            decreasing=FALSE)))) %>% 
  ggplot(aes(x = Species,
             y = values, 
             fill = measurements)) +
  geom_bar(stat = "identity") +
  facet_wrap(.~ measurements,
             scales = "free") 

and this:

iris %>% 
  gather(key = measurements, value = values, - Species) %>% 
  group_by(measurements, Species) %>% 
  top_n(5, wt = values) %>% 
  ggplot(aes(x = reorder(Species, Species,
                         function(x)-length(x)),
             y = values, 
             fill = measurements)) +
  geom_bar(stat = "identity") +
  facet_wrap(.~measurements,
             scales = "free")

and this:

iris %>% 
  gather(key = measurements, value = values, - Species) %>% 
  mutate(kk = factor(measurements, levels = unique(.$measurements)),
         species_l = with(., paste(Species, .$measurements, sep = "_"))) %>% 
  group_by(measurements, Species) %>%
  top_n(5, wt = values) %>%
  ungroup() %>%
  ggplot(aes(x = reorder(species_l, values),
             y = values, 
             fill = kk)) +
  geom_bar(stat = "identity") +
  facet_wrap(.~kk,
             scales = "free")

This is what I get: enter image description here

As you can see Sepal.Width bars are not sorted.

patL
  • 2,259
  • 1
  • 17
  • 38
  • Try these too https://stackoverflow.com/questions/52214071/how-to-order-data-by-value-within-ggplot-facets/52214383#52214383 – Tung Oct 25 '19 at 17:29
  • @Tung can you read edits. I'm trying to reopen since with `top_n` and `group_modify` it seems that answers marked as duplicated from don't fit my question. – patL Oct 30 '19 at 10:26

1 Answers1

2

Your first attempt was close -- you need to make sure you're reordering per facet, and not just reordering the factor based on the top 5 values of all measurements. Julia Silge explains thoroughly here

library(tidytext) 
library(tidyverse)
library(magtrittr)

iris %>%
   gather(key = measurements, value = values, - Species) %>% 
    mutate(kk = factor(measurements, levels = unique(.$measurements)),
#The '-values' below specifies to order in descending
      Species = reorder_within(Species, -values, measurements)) %>% 
   ggplot(aes(x = Species, y = values, fill = kk)) +
      geom_bar(stat = "identity") +
        facet_wrap(.~kk, scales = "free") +
      scale_x_reordered()`
Jonni
  • 804
  • 5
  • 16