6

My data:

structure(list(LoB = c("C", "C", "C", "A", 
"A", "B", "C", "A", "A", "C", 
"A", "B", "C", "B", "A", "C", "B", 
"A", "B", "C", "A", "B", "B", "A", 
"B", "C", "A", "B", "C", "B"), word = c("speed", 
"connection", "call", "bt", "reliable", "reliable", "reliable", 
"expensive", "cheaper", "uk", "customer", "customer", "customer", 
"network", "broadband", "broadband", "signal", "price", "price", 
"price", "poor", "poor", "ee", "service", "service", "service", 
"excellent", "excellent", "excellent", "coverage"), word_total = c(68L, 
46L, 44L, 3138L, 3479L, 906L, 71L, 6096L, 2967L, 39L, 10405L, 
1429L, 113L, 676L, 5193L, 73L, 868L, 8763L, 814L, 139L, 4708L, 
659L, 530L, 19185L, 2253L, 136L, 7180L, 1227L, 69L, 1453L), word_prop_by_total_feedbacks = c(0.0656370656370656, 
0.0444015444015444, 0.0424710424710425, 0.0343378635677237, 0.0380692885124636, 
0.101603678367164, 0.0685328185328185, 0.0667060600091918, 0.0324666797977808, 
0.0376447876447876, 0.113857702492723, 0.160255691376023, 0.109073359073359, 
0.075810250084109, 0.0568248965924759, 0.0704633204633205, 0.0973421554334417, 
0.0958899612632132, 0.0912863070539419, 0.134169884169884, 0.0515177379467314, 
0.0739037792979702, 0.0594370303913872, 0.209933687873416, 0.252663451833576, 
0.131274131274131, 0.0785678331473092, 0.137602332623079, 0.0666023166023166, 
0.16294717954469)), class = c("grouped_df", "tbl_df", "tbl", 
"data.frame"), row.names = c(NA, -30L), vars = "LoB", drop = TRUE, indices = list(
    c(3L, 4L, 7L, 8L, 10L, 14L, 17L, 20L, 23L, 26L), c(5L, 11L, 
    13L, 16L, 18L, 21L, 22L, 24L, 27L, 29L), c(0L, 1L, 2L, 6L, 
    9L, 12L, 15L, 19L, 25L, 28L)), group_sizes = c(10L, 10L, 
10L), biggest_group_size = 10L, labels = structure(list(LoB = c("A", 
"B", "C")), class = "data.frame", row.names = c(NA, -3L
), vars = "LoB", drop = TRUE, .Names = "LoB"), .Names = c("LoB", 
"word", "word_total", "word_prop_by_total_feedbacks"))

I am trying to plot using ggplot2 but fct_reorder and drlib::reorder_within(word, word_total, LoB) not working and giving me a warning message: Unequal factor levels: coercing to characterbinding character and factor vector, coercing into character vectorbinding character and factor vector, coercing into character vectorbinding character and factor vector, coercing into character vector

Here is the code:

   mutate(word = drlib::reorder_within(word, word_total, LoB)) %>% 

OR

  mutate(word = forcats::fct_reorder(word, word_total)) %>%
  ggplot(aes(word, word_prop_by_total_feedbacks, fill = LoB)) +
  geom_col() +
#  drlib::scale_x_reordered()+
  facet_wrap(~ LoB, scales = "free") +
  coord_flip()

it is not plotting in descending order. what am I missing?

Update: Was missing ungroup() before mutate(). thanks all

Shery
  • 1,808
  • 5
  • 27
  • 51
  • It's not plotting in descending order of what? `word`? With me it is and I did not run `mutate`, just your data as posted. And you are missing the name of the data frame both in the question and in the `ggplot(df, aes(...))`. – Rui Barradas Oct 27 '17 at 14:45
  • 6
    You may have been missing an `ungroup` at some earlier step. I've made this mistake before. – aosmith Nov 01 '17 at 23:39
  • this was exactly what I was missing...all sorted...thanks @aosmith – Shery Nov 03 '17 at 11:02

3 Answers3

4

Similar to @austensen, but using a different method for the factor averse.

You can just group_by and arrange accordingly, then ungroup and create and index. This way you don't have to worry about using factor, but you do have to create breaks and labels in scale_x_continuous.

library(ggplot2)
library(dplyr)

plot_data <- df %>% 
  group_by(LoB) %>% 
  arrange(word_total) %>% 
  ungroup() %>% 
  mutate(order = row_number())

ggplot(plot_data, aes(order, word_prop_by_total_feedbacks, fill = LoB)) +
  geom_col() +
  facet_wrap(~ LoB, scales = "free") +
  scale_x_continuous(breaks = plot_data$order, labels = plot_data$word) +
  coord_flip()

enter image description here

Jake Kaupp
  • 7,892
  • 2
  • 26
  • 36
1

It's a bit of an awkward work-around because you can have the same word appear in different order based on the value of LoB. There is a good example of this from the book Tidy Text Mining (see section 8.4.3 of this chapter). I followed that to create what's below.

Essentially you have to order word as the concatenation of word and LoB then strip the LoB part out when displaying the word labels on the graph.


library(tidyverse)
library(forcats)

df %>% 
  group_by(LoB) %>% 
  arrange(desc(word_total)) %>% 
  ungroup() %>% 
  mutate(word = factor(paste(word, LoB, sep = "__"), 
                       levels = rev(paste(word, LoB, sep = "__")))) %>%
  ggplot(aes(word, word_prop_by_total_feedbacks, fill = LoB)) +
  geom_col() +
  scale_x_discrete(labels = function(x) gsub("__.+$", "", x)) +
  facet_wrap(~ LoB, scales = "free") +
  coord_flip()

austensen
  • 2,857
  • 13
  • 24
0

You might consider tidytext::reorder_within

df %>% 
  group_by(LoB) %>% 
  arrange(desc(word_total)) %>% 
  ungroup() %>% 
  ggplot(aes(word_prop_by_total_feedbacks, tidytext::reorder_within(word, word_prop_by_total_feedbacks, LoB), fill = LoB)) +
  geom_col() +
  facet_wrap(~ LoB, scales = "free") +
  scale_y_reordered()