Search code examples
rggplot2geom-bar

Reorder ggplot axis by one value, display labels from another


Situation is as follows:
I have many names and many corresponding codes for those names.
All different names have a unique code, but not all different codes have a unique name.

This has created an issue when plotting the data, as I need to group_by(code), and reorder(name,code) when plotting, but the codes are nonsense and I want to display the names. Since some codes share names, this creates a bit of an issue.

Example to illustrate below:

library(tidyverse)
set.seed(1)

# example df
df <- tibble("name" = c('apple','apple','pear','pear','pear',
                        'orange','banana','peach','pie','soda',
                        'pie','tie','beer','picnic','cigar'),
             "code" = seq(1,15),
             "value" = round(runif(15,0,100)))
df %>% 
  ggplot(aes(x=reorder(name,value)))+
  geom_bar(aes(y=value),
           stat='identity')+
  coord_flip()+
  ggtitle("The axis labels I want, but the order I don't")

plot example 1

df %>% 
  ggplot(aes(x=reorder(code,value)))+
  geom_bar(aes(y=value),
           stat='identity')+
  coord_flip()+
  ggtitle("The order I want, but the axis labels I don't")

enter image description here


Not quite sure how to get ggplot to keep the display and order of the second plot while being able to replace the axis labels with the names from the first plot.


Solution

  • What about using interaction to bind names and code and in scale_x_discrete replace labels by appropriate one such as follow:

    df %>% 
      ggplot(aes(x=interaction(reorder(name, value),reorder(code,value))))+
      geom_bar(aes(y=value),
                 stat='identity')+
      scale_x_discrete(labels = function(x) sub("\\..*$","",x), name = "name")+
      coord_flip()
    

    enter image description here

    is it what you are looking for ?