Conditional sort of factors in ggplot2

Hi all!

I'm trying to sort a factor variable in a plot, using forcats and ggplot2. However, since I have two values of the value I want to sort by for each factor level, it is sorted by the mean of those values, see the example below. I know that I can change to the max, using .fun = "max", but it doesn't lead to the result I want. I want to sort by just one of values (where group == a), i.e., in the example below, I want to sort the months by the values in group a, and only if the value is the same in a for two months, I want to sort by the value in b. In other words, I want the red dots to be sorted from higher to lower values.

Any suggestions on how I can accomplish this? Any help would be greatly appreciated.
Best, R

library(tidyverse)
df <- tibble(month = rep(month.name, each = 2),
             group = rep(c("a","b"), 12),
             value = rnorm(24))

df |> 
  mutate(month = fct_reorder(month, value)) |> 
  ggplot(aes(value, month, color = group)) +
  geom_point(position = position_dodge(.5))

Created on 2023-11-13 with reprex v2.0.2

Come to think of it, if I don't care about the sorting of b in cases where a has the same value, I could do something like this. But I assume there's a better solution.

library(tidyverse)
df <- tibble(month = rep(month.name, each = 2),
             group = rep(c("a","b"), 12),
             value = rnorm(24))

df |> 
  mutate(month = fct_reorder(month, if_else(group == "a", value, 0))) |> 
  ggplot(aes(value, month, color = group)) +
  geom_point(position = position_dodge(.5))

Created on 2023-11-13 with reprex v2.0.2

library(tidyverse)
df <- structure(list(month = c("January", "January", "February", "February", 
                               "March", "March", "April", "April", "May", "May", "June", "June", 
                               "July", "July", "August", "August", "September", "September", 
                               "October", "October", "November", "November", "December", "December"
), group = c("a", "b", "a", "b", "a", "b", "a", "b", "a", "b", 
             "a", "b", "a", "b", "a", "b", "a", "b", "a", "b", "a", "b", "a", 
             "b"), value = c(-1.3, -0.3, -0.8, -0.2, -0.8, -0.1, -0.3, -1, 
                             0.8, 1, -0.3, 0.9, -0.6, 0.3, 0.1, 0.7, -1.1, -2, 0.1, 0.3, 0.1, 
                             1.2, -0.4, -0.8)), row.names = c(NA, -24L), class = c("tbl_df", 
                                                                                   "tbl", "data.frame"))
(piv_df <- df |> pivot_wider(names_from="group",
                             values_from="value") |> 
    arrange(a,b))

df$month <- factor(df$month,levels=piv_df$month)

df |> 
  ggplot(aes(value, month, color = group)) +
  geom_point(position = position_dodge(.5))
1 Like

Thank you for the suggestion! It works fine. I'm still wondering, however, if there's some simpler solution.