简体   繁体   中英

How do I order bars in a grouped bar chart?

I'd like to order the bars in a grouped bar chart.

This is my tibble.

# A tibble: 13 x 3                
   number    name                   prop     
       <dbl> <chr>                  <int>    
           1 Dog                     0.0664  
           1 Cow                     0.0628  
           1 Pig                     0.0166  
           1 Garden                  0.0163  
           2 Moose                   0.0619  
           2 Cliff                   0.0517  
           2 Hike                    0.0214  
           2 Dog                     0.0147  
           2 Cow                     0.0141  
           3 Pig                     0.0615  
           3 Garden                  0.0245  
           3 Moose                   0.0135  
           3 Cow                     0.0132  

I'd like to make a grouped bar chart where the groups are sorted from greatest to least for values of prop . I want the groups to be sorted from greatest to least, so the x-axis should read from left to right: 1, 2, 3 and then, within each group, I want it to be greatest to least.

The bars for the number 1 should be Dog then Cow then Pig then Garden

This is what I tried.

library(tidyverse)
library(ggplot2)

tib.ready <- tib %>% 
  mutate(name = fct_reorder(name, prop, sum)) %>% 
  group_by(number) %>% 
  mutate(name = fct_reorder(name, prop, sum)) %>% 
  ungroup() %>% 
  mutate(number = fct_reorder(factor(number), prop, sum)) 

I tried the solution that Matias Andina linked to.

tib_ready <- with(tib_ready, 
       tib_ready[order(name, -as.numeric(prop)), ])

tib_ready %>%
ggplot(aes(number, prop, fill = name, label = name)) +
      geom_col(position = "dodge") +
      coord_flip()

Tidyverse solution:

library(tidyverse)
df %>% 
  mutate(prop = as.double(prop), rank = as.numeric(rank)) %>%
  ggplot(., aes(x = number, y = reorder(prop, rank), fill = name)) +
  geom_col(position = "dodge") +
  ylab("Prop") +
  coord_flip()

Data:

df <- structure(list(number = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 
    3L, 3L, 3L, 3L), name = c("Dog", "Cow", "Pig", "Garden", "Moose", 
    "Cliff", "Hike", "Dog", "Cow", "Pig", "Garden", "Moose", "Cow"
    ), prop = c(0.0664, 0.0628, 0.0166, 0.0163, 0.0619, 0.0517, 0.0214, 
    0.0147, 0.0141, 0.0615, 0.0245, 0.0135, 0.0132), rank = c(1L, 
    2L, 3L, 4L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L)), row.names = c(NA, 
    -13L), class = "data.frame")

Since you already ordered all the rows by the appropriate groups you could add another column that represents the order within the groups and use the group aesthetic argument. That should order them as desired within the number group.

tib.ready <- tib %>% 
  mutate(name = fct_reorder(name, prop, sum)) %>% 
  group_by(number) %>% 
  mutate(name = fct_reorder(name, prop, sum)) %>% 
  ungroup() %>% 
  mutate(number = fct_reorder(factor(number), prop, sum))

ggplot(tib.ready, aes(x = number, y = prop, fill = name, group = rank, label = name)) +
  geom_col(position = "dodge")

edit: Updated to just use the rank variable

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM