Eric Green
Eric Green

Reputation: 7725

reorder is not sorting bars correctly

I am trying to sort facet bars by a numeric value via reorder(), but I can't seem to get it to work. I pasted my approach below.

enter image description here

    dat <- structure(list(item1 = c("word 2", "word 2", "word 2", "word 2", 
                                    "word 1", "word 1", "word 1", "word 2", "word 1", "word 1", "word 1", 
                                    "word 2", "word 2", "word 2", "word 1", "word 2", "word 1", "word 2", 
                                    "word 1", "word 1"), item2 = c("ir", "pr", "no", "mi", "wi", 
                                                                   "pr", "fe", "pa", "ti", "la", "pa", "ex",
                                                                   "cy", "se", "pe", "ti", 
                                                                   "qu", "qu", "se", "pr"), 
                          correlation = c(0.25456134079712, 0.2519936013674, 0.235943369717533, 
                                          0.227471817443391, 0.226966823585789, 0.211693332876911,
                                          0.209447353365894, 0.207110281022818, 0.19877845972944, 
                                          0.191606462402359, 0.186883665554187, 0.179251580064878, 
                                          0.17330384364747, 0.163131910906122, 0.163131910906122, 
                                          0.154238168542876, 0.153535076033027, 0.146798885015777, 
                                          0.144380422722292, 0.142845908676349)), 
                     class = c("tbl_df", "tbl", 
                               "data.frame"), row.names = c(NA, -20L))

    library(tidyverse)
    ggplot(dat, aes(x = reorder(item2, -correlation), y = correlation)) +
      geom_bar(stat = "identity") +
      facet_wrap(~ item1, scales = "free") +
      theme_classic() +
      coord_flip() +
      theme(axis.title.y=element_blank())

Update 1:

I simplified the example item2 variable but kept two repeat values "a" and "b" that have correlations with "word 1" and "word 2". I also incorporated the suggestion to add max to reorder().

Each facet is sorted by its correlation with item2, but "b" in the "word 1" facet appears out of order. "b" appears in the "word 2" facet which seems to be driving the order.

enter image description here

dat <- structure(list(item1 = c("word 2", "word 2", "word 2", "word 2", 
                                "word 1", "word 1", "word 1", "word 2", "word 1", "word 1", "word 1", 
                                "word 2", "word 2", "word 2", "word 1", "word 2", "word 1", "word 2", 
                                "word 1", "word 1"), item2 = c("a", "b", "c", "d", "a", 
                                                               "f", "g", "h", "i", "j", "k", "l",
                                                               "m", "n", "o", "p", 
                                                               "q", "r", "s", "b"), 
                      correlation = c(0.25456134079712, 0.2519936013674, 0.235943369717533, 
                                      0.227471817443391, 0.226966823585789, 0.211693332876911,
                                      0.209447353365894, 0.207110281022818, 0.19877845972944, 
                                      0.191606462402359, 0.186883665554187, 0.179251580064878, 
                                      0.17330384364747, 0.163131910906122, 0.163131910906122, 
                                      0.154238168542876, 0.153535076033027, 0.146798885015777, 
                                      0.144380422722292, 0.142845908676349)), 
                 class = c("tbl_df", "tbl", 
                           "data.frame"), row.names = c(NA, -20L))

library(tidyverse)
ggplot(dat, aes(x = reorder(item2, correlation, max), y = correlation)) +
  geom_bar(stat = "identity") +
  facet_wrap(~ item1, scales = "free") +
  theme_classic() +
  coord_flip() +
  theme(axis.title.y=element_blank())

Upvotes: 2

Views: 576

Answers (1)

OTStats
OTStats

Reputation: 1868

I'm able to get you slightly there, hopefully this will help us figure it out...

I think the issue is that you need to create a few extra fields to help you sort. I found this post, Ordering Categories Within ggplot2 Facets, which seems to also be using tidytext. Looks like the author, Simon Jackson, arranges the data frame based on the relevant value (in this case it would be correlation).

In your case, I first duplicated item1 to a new field called word, pivoted the data, then arranged the rows.
The only outstanding issue now it that your y-axis labels are order.

library(tidyverse)
dat %>% 
  mutate(word = item1) %>% 
  spread(item1, item2) %>%
  arrange(desc(`word 2`),  correlation) %>% 
  mutate(order = row_number()) %>% 
  ggplot(aes(x = order, correlation)) + 
  geom_col() + 
  theme_classic() +
  coord_flip() +
  theme(axis.title.y=element_blank()) + 
  facet_wrap(~ word, scales = "free")

ordered facet plot

EDIT:

Figured it out...
Ultimately, duplicating both item1 and item2 (to word and letter respectively), then saving the data frame was most conducive to getting the desired result.

dat2 <- dat %>% 
  mutate(word = item1, 
         letter = item2) %>% 
  spread(item1, item2) %>%
  arrange(desc(`word 2`),  correlation) %>% 
  mutate(order = row_number())

dat2 %>% 
  ggplot(aes(x = order, correlation)) + 
  geom_col() + 
  theme_classic() +
  coord_flip() +
  theme(axis.title.y=element_blank()) + 
  facet_wrap(~ word, scales = "free") + 
  scale_x_continuous(
    breaks = dat2$order,
    labels = dat2$letter
  )

enter image description here

Upvotes: 2

Related Questions