rggplot2r-factor

Is there a quicker way to factor and relevel a column based on the levels in another column?


My code below works, but I feel like I'm missing a way to do this quicker (ie I don't know a better function). When I search forums for relevel based on another column all I am given are answers around factor(metric, levels = c(...) - which I've done through a series of calls - but I feel like there is a more elegant solution.

# Order of the week I would like to display in ggplot
week_order <- c('Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Mon', 'Tue' )

# Data
df <- tibble(metric = c(0, 8, 12, 18, 6, 12, 20),
                  label_day = c('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'),
                  legend_text = c('Off', 'ReEntry', 'Strength', 'Match 1', 'Recovery', 'Activation', 'Match 2'))

# Change `label_day` into a factor and order based on `week_order` 
df <- df |>
  mutate(label_day = factor(label_day, levels = week_order)) |>
  arrange(label_day)

# Is there a more elegant way to do this ? -------------------------------------------------------
# Now that the df is in the correct order, pull out the order that `legend_text` is in to use in ggplot
legend_text_order <- df |>
  distinct(legend_text) |>
  pull()

# Change `legend_text` into a factor and order based on `legend_text_order` 
df <- df |>
  mutate(legend_text = factor(legend_text, levels = legend_text_order))
#-------------------------------------------------------------------------------------------------

# Plot
ggplot(df, aes(x = legend_text, y = metric)) +
  geom_col()

Solution

  • You can do it all in one pipe:

    df <- df |>
      mutate(label_day = factor(label_day, levels = week_order)) |>
      arrange(label_day) |>
      mutate(legend_text = factor(legend_text, levels = unique(legend_text)))
    

    And as you don't actually need keep label_day as a factor, just use it's order to arrange the dataset, you can shrink it a little further:

    df <- df |>
      arrange(factor(label_day, levels = week_order)) |>
      mutate(legend_text = factor(legend_text, levels = unique(legend_text)))
    

    Output:

    enter image description here