1

Help with reordering facets.

I am using reorder_within and scale_x_reordered from Julia Silge's blog (https://juliasilge.com/blog/reorder-within/)

I am using nested facets here and reordering facets within a parent facet. In this use case the labeller function doesn't seem to drop the suffix after the "___" separator.

I tried passing a function into labeller but I just got an error.

Dataset:

data <- structure(list(YEAR = c(2017L, 2018L, 2019L, 2020L, 2017L, 2018L, 
2019L, 2020L, 2017L, 2018L, 2019L, 2020L, 2017L, 2018L, 2019L, 
2020L, 2017L, 2018L, 2019L, 2020L, 2017L, 2018L, 2019L, 2020L, 
2017L, 2018L, 2019L, 2020L, 2017L, 2018L, 2019L, 2020L, 2017L, 
2018L, 2019L, 2020L, 2017L, 2018L, 2019L, 2020L), Level = c("Lvl 2", 
"Lvl 2", "Lvl 2", "Lvl 2", "Lvl 1", "Lvl 1", "Lvl 1", "Lvl 1", 
"Lvl 1", "Lvl 1", "Lvl 1", "Lvl 1", "Lvl 2", "Lvl 2", "Lvl 2", 
"Lvl 2", "Lvl 1", "Lvl 1", "Lvl 1", "Lvl 1", "Lvl 2", "Lvl 2", 
"Lvl 2", "Lvl 2", "Lvl 2", "Lvl 2", "Lvl 2", "Lvl 2", "Lvl 1", 
"Lvl 1", "Lvl 1", "Lvl 1", "Lvl 1", "Lvl 1", "Lvl 1", "Lvl 1", 
"Lvl 2", "Lvl 2", "Lvl 2", "Lvl 2"), Company = c("Company 1", 
"Company 1", "Company 1", "Company 1", "Company 1", "Company 1", 
"Company 1", "Company 1", "Company 2", "Company 2", "Company 2", 
"Company 2", "Company 2", "Company 2", "Company 2", "Company 2", 
"Company 3", "Company 3", "Company 3", "Company 3", "Company 3", 
"Company 3", "Company 3", "Company 3", "Company 4", "Company 4", 
"Company 4", "Company 4", "Company 4", "Company 4", "Company 4", 
"Company 4", "Company 5", "Company 5", "Company 5", "Company 5", 
"Company 5", "Company 5", "Company 5", "Company 5"), Colour_flag = c("Flag_1", 
"Flag_1", "Flag_1", "Flag_1", "Flag_1", "Flag_1", "Flag_1", "Flag_1", 
"Flag_1", "Flag_1", "Flag_1", "Flag_1", "Flag_1", "Flag_1", "Flag_1", 
"Flag_1", "Flag_1", "Flag_1", "Flag_1", "Flag_1", "Flag_1", "Flag_1", 
"Flag_1", "Flag_1", "Flag_2", "Flag_2", "Flag_2", "Flag_2", "Flag_2", 
"Flag_2", "Flag_2", "Flag_2", "Flag_1", "Flag_1", "Flag_1", "Flag_1", 
"Flag_1", "Flag_1", "Flag_1", "Flag_1"), Result = c(77.2, 76.9, 
77.5, 58.1, 77.5, 77.9, 77.6, 52.3, 78.2, 78.6, 78.6, 60.4, 74.2, 
74.7, 74.7, 60.2, 74.9, 74.3, 74.2, 63.6, 72.1, 72.5, 73.4, 58.9, 
75.3, 75, 72, 65, 73.7, 74.4, 62.9, 59.7, 80.8, 81.1, 80, 66.3, 
76.1, 76.3, 75.5, 64.6), Rank = c(58.1, 58.1, 58.1, 58.1, 52.3, 
52.3, 52.3, 52.3, 60.4, 60.4, 60.4, 60.4, 60.2, 60.2, 60.2, 60.2, 
63.6, 63.6, 63.6, 63.6, 58.9, 58.9, 58.9, 58.9, 65, 65, 65, 65, 
59.7, 59.7, 59.7, 59.7, 66.3, 66.3, 66.3, 66.3, 64.6, 64.6, 64.6, 
64.6)), class = "data.frame", row.names = c(NA, -40L))

The dataset is structured as follows:

> head(data, 5)
  YEAR Level   Company Colour_flag Result Rank
1 2017 Lvl 2 Company 1      Flag_1   77.2 58.1
2 2018 Lvl 2 Company 1      Flag_1   76.9 58.1
3 2019 Lvl 2 Company 1      Flag_1   77.5 58.1
4 2020 Lvl 2 Company 1      Flag_1   58.1 58.1
5 2017 Lvl 1 Company 1      Flag_1   77.5 52.3
> 

I am trying to reorder the facets within the nested facets. The facets are ordered by the value for the max year, in this case the facets in each level are sorted by the 2020 value.

The code I am using:

library (ggplot2)
library (ggh4x)
library (tidytext)

Col = c("Flag_1" = "#0067A8", "Flag_2" = "#FFDC00")

data %>%
  mutate(
  Level = as.factor(Level),
  YEAR = as.factor(YEAR),
  Company = reorder_within(Company, -Rank, Level)) %>%
  
  #plot
  ggplot(aes(x = YEAR, y = Result, fill = Colour_flag)) +
  facet_nested(. ~ Level + Company, 
               scales = "free_x", 
               labeller = label_wrap_gen(width = 15, multi_line = TRUE)) +
  # labeller = function(x) gsub("_", " ", x, fixed=TRUE)) - throws following error:
  #! `rows` must be `NULL` or a `vars()` list if `cols` is a `vars()` list
  scale_x_reordered () +
  geom_bar(stat = "identity") +
  geom_text(aes(y = Result, label = round(Result, 0)), 
            position = position_dodge(0.9), 
            hjust = 1.5, vjust = 0.5, angle = 90, size = 3.5) +

  scale_fill_manual(values = Col) +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    axis.text.x = element_text(angle = 90, hjust = 0, vjust = 0.5, size = 10),
    strip.text.x = element_text(size = 11),
    axis.text.y = element_blank(),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    legend.position = 'none',
    panel.spacing = unit(c(0.5,0.5,0.5,0.5,30,
                           0.5,0.5,0.5,0.5), "pt")
  )

The output of the ggplot looks like this:

enter image description here

Is there anyway to remove the suffix in the facet labels (e.g.___Lvl1)? I can change the separator to be a space and this looks a little better but I have failed at finding a way to modify the facet labels.

Any help would be greatly appreciated.

Keelin
  • 367
  • 1
  • 10

1 Answers1

2

You were very close with your attempt of gsub. What you needed was a labeller function as

labeller = function(x) {x$Company <- sub('_+Lvl \\d+', '', x$Company);x}

The x here is a dataframe with two columns, Level and Company. We need to change the value in only Company column and return the dataframe back.

x

#   Level           Company
#1  Lvl 1 Company 5___Lvl 1
#2  Lvl 1 Company 3___Lvl 1
#3  Lvl 1 Company 2___Lvl 1
#4  Lvl 1 Company 4___Lvl 1
#5  Lvl 1 Company 1___Lvl 1
#6  Lvl 2 Company 4___Lvl 2
#7  Lvl 2 Company 5___Lvl 2
#8  Lvl 2 Company 2___Lvl 2
#9  Lvl 2 Company 3___Lvl 2
#10 Lvl 2 Company 1___Lvl 2

Here's the complete code -

data %>%
  mutate(
    Level = as.factor(Level),
    YEAR = as.factor(YEAR),
    Company = reorder_within(Company, -Rank, Level)) %>%
  
  #plot
  ggplot(aes(x = YEAR, y = Result, fill = Colour_flag)) +
  facet_nested(. ~ Level + Company, 
               scales = "free_x", 
               labeller = function(x) {
                 x$Company <- sub('_+Lvl \\d+', '', x$Company)
                 x
                 }) + 
  geom_bar(stat = "identity") +
  geom_text(aes(y = Result, label = round(Result, 0)), 
            position = position_dodge(0.9), 
            hjust = 1.5, vjust = 0.5, angle = 90, size = 3.5) +
  
  scale_fill_manual(values = Col) +
  theme_minimal() +
  theme(
    axis.title.x = element_blank(),
    axis.title.y = element_blank(),
    axis.text.x = element_text(angle = 90, hjust = 0, vjust = 0.5, size = 10),
    strip.text.x = element_text(size = 11),
    axis.text.y = element_blank(),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    legend.position = 'none',
    panel.spacing = unit(c(0.5,0.5,0.5,0.5,30,
                           0.5,0.5,0.5,0.5), "pt")
  )

enter image description here

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • that is fantastic!!! Thank you so very much. Is it at all possible to keep the original Lvl 1 and Lvl 2 in the parent facet? Its now labelled 1 and 2. Its important the correct titles are in the report. – Keelin Jun 18 '22 at 08:20
  • Thank you Ronak, really appreciated. I also learned from your really clear explanation. I was able to get the right labels for the parent facet by a small edit: facet_nested(. ~ Level + Company, scales = "free_x", labeller = labeller( Company = function(x) { x <- str_remove(x, pattern = "\\_.*") x})) + – Keelin Jun 19 '22 at 00:17