Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fct_reorder() only working properly for one facet

Tags:

r

ggplot2

forcats

I am trying to create a faceted bar graph, with bars ordered according to their frequency (using fct_reorder). Here is my code:

word_count_label <- twitter_sm %>%
  group_by(complaint) %>%
  summarize_if(is.numeric, sum) %>%
  ungroup() %>%
  gather(word, n, -complaint) %>%
  mutate(word = as.factor(word)) %>%
  filter(n > 0) %>%
  group_by(complaint) %>%
  mutate(word = fct_reorder(word, n)) %>%
  top_n(20, n) %>%
  arrange(complaint, desc(n)) %>%
  ungroup()

The resulting data frame looks like this:

   complaint     word              n
   <fct>         <fct>         <dbl>
 1 non_complaint klm             820
 2 non_complaint flight          653
 3 non_complaint unit            537
 4 non_complaint americanair     532
 5 non_complaint delta           441
 6 non_complaint thank           420
 7 non_complaint southwestair    363
 8 non_complaint britishairway   326
 9 non_complaint just            294
10 non_complaint usairway        261
# … with 30 more rows

However, when I created a facetted bar graph plotting word counts for each facet (code shown below),

  ggplot(word_count_label, aes(x = word, y = n, fill = complaint)) +
  geom_col() + coord_flip() + 
  facet_wrap(~complaint, scales = 'free_y')

the plot only orders bars for one facet:

enter image description here

Does anyone have any insights as to why this is happening? Thanks!

like image 715
Eric Avatar asked Jan 30 '26 06:01

Eric


1 Answers

You could use reorder_within() from the tidytext package instead of fct_reorder(). Julia Silge has a great example here.

word_count_label <- twitter_sm %>%
  group_by(complaint) %>%
  summarize_if(is.numeric, sum) %>%
  ungroup() %>%
  gather(word, n, -complaint) %>%
  mutate(word = as.factor(word)) %>%
  filter(n > 0) %>%
  mutate(word = reorder_within(word, n, complaint)) %>%
  group_by(complaint) %>%
  top_n(20, n) %>%
  arrange(complaint, desc(n)) %>%
  ungroup()

Additionally, Julia uses scale_x_reordered() as a layer in ggplot. Here's an example how:

ggplot(word_count_label, aes(x = word, y = n, fill = complaint)) +
  geom_col() + 
  coord_flip() + 
  scale_x_reordered() + 
  facet_wrap(~complaint, scales = 'free_y')
like image 65
OTStats Avatar answered Feb 01 '26 18:02

OTStats



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!