1

I am trying in vain to get the segments within each bar of the bar chart to order based on the value (largest value within a bar on the bottom, smallest on top).

I've researched this and would think this should work, but something is not right and I can't find the issue. I tried this solution here, but no luck.

Here is a reproducible example:

library(dplyr)

my_repro <- structure(list(Date = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                  1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "2020-04-01", class = "factor"), 
               Grp = c("A", "A", "A", "B", "B", "B", "C", "C", "C", "D", 
                       "D", "D", "E", "E", "E"), Segment = structure(c(1L, 2L, 3L, 
                                                                       1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("Seg1", 
                                                                                                                                   "Seg2", "Seg3"), class = "factor", scores = structure(c(Seg1 = NA_real_, 
                                                                                                                                                                                           Seg2 = NA_real_, Seg3 = NA_real_), .Dim = 3L, .Dimnames = list(
                                                                                                                                                                                             c("Seg1", "Seg2", "Seg3")))), Value = c(220, 75, NA, 
                                                                                                                                                                                                                                     NA, 400, NA, 350, NA, NA, 170, NA, NA, 375, 100, 
                                                                                                                                                                                                                                     NA)), row.names = c(NA, -15L), class = c("tbl_df", "tbl", 
                                                                                                                                                                                                                                                                              "data.frame"))





   # Reorder the Group based on the Value 
   my_repro$Grp <- reorder(my_repro$Grp, -my_repro$Value)
   #my_repro$Grp <- as.character(my_repro$Grp)   # I later added this line too, no luck

   # Plot
   ggplot(my_repro, aes(x=Segment, y=Value, fill=Grp)) +
   geom_col()

This gives the following tibble:

# A tibble: 15 x 4
   Date       Grp   Segment Value
   <fct>      <fct> <fct>   <dbl>
 1 2020-04-01 A     Seg1      220
 2 2020-04-01 A     Seg2       75
 3 2020-04-01 A     Seg3       NA
 4 2020-04-01 B     Seg1       NA
 5 2020-04-01 B     Seg2      400
 6 2020-04-01 B     Seg3       NA
 7 2020-04-01 C     Seg1      350
 8 2020-04-01 C     Seg2       NA
 9 2020-04-01 C     Seg3       NA
10 2020-04-01 D     Seg1      170
11 2020-04-01 D     Seg2       NA
12 2020-04-01 D     Seg3       NA
13 2020-04-01 E     Seg1      375
14 2020-04-01 E     Seg2      100
15 2020-04-01 E     Seg3       NA

And the following graph:

plot

It appears that bars are being ordered alphabetically, which I know is an issue on many questions like this, but I thought this line of code would solve it: my_repro$Grp <- reorder(my_repro$Grp, -my_repro$Value)

I then added this line, just before the plot code, so that Grp would not be a factor that was put in alphabetical order: my_repro$Grp <- as.character(my_repro$Grp) but I get the same plot

Any idea how to fix?

Thanks!

DaveM
  • 664
  • 6
  • 19

1 Answers1

0

Try the fct_reorder function from the forcats package:

library(dplyr)
library(forcats)

my_repro <- my_repro %>% 
  group_by(Segment) %>% 
  mutate(Grp = fct_reorder(Grp, Value))

# Plot
ggplot(my_repro, aes(x=Segment, y=Value, fill=Grp)) +
  geom_col()

Plot_ordered

henhesu
  • 756
  • 4
  • 9
  • As it turns out, this would have worked as well: `my_repro <- my_repro %>% group_by(Segment) %>% mutate(Grp = reorder(Grp, Value))` Not sure why the original approach did not work since it worked in the prior question I referenced. – DaveM May 15 '20 at 16:39
  • The key seems to be to use `group_by` first. – DaveM May 15 '20 at 17:00