Search code examples
rggplot2facettidytext

ggplot sort descending points within group


I want to arrange the plot below so that 'group' is arranged in descending order by 'Distance' within Community (Out, In).

enter image description here

I've tried using dplyr::arrange and tidytext::reorder_within(group, -value, MPA_type), but neither of these work - ggplot continues to default to sorted by group name in descending order (see legend). If facetwrap is part of the solution, I'd prefer to have the labels at the bottom as in the example figure, rather than the typical facet header.

Here is my data:

sig_distance <- structure(list(Var1 = structure(c(2L, 2L, 5L, 5L, 2L, 2L, 5L, 
5L, 2L, 2L, 5L, 5L, 2L, 2L, 5L, 5L, 2L, 2L, 5L, 5L), .Label = c("ref after", 
"ref before", "ref during", "smr after", "smr before", "smr during"
), class = "factor"), Var2 = structure(c(1L, 3L, 4L, 6L, 1L, 
3L, 4L, 6L, 1L, 3L, 4L, 6L, 1L, 3L, 4L, 6L, 1L, 3L, 4L, 6L), .Label = c("ref after", 
"ref before", "ref during", "smr after", "smr before", "smr during"
), class = "factor"), value = c(0.0781171338765429, 0.070131485880327, 
0.124219180798504, 0.0642584499973571, 0.16882716299913, 0.123057288279708, 
0.185404402405965, 0.113660097900038, 0.14628853013894, 0.106462687516074, 
0.179579889492142, 0.146317072898829, 0.163284273893779, 0.130083096905712, 
0.0991349070859965, 0.106610448830353, 0.0499622399107518, 0.0563330614755333, 
0.0391975833642552, 0.0435817314833789), MPA = structure(c(3L, 
2L, 4L, 1L, 3L, 2L, 4L, 1L, 3L, 2L, 4L, 1L, 3L, 2L, 4L, 1L, 3L, 
2L, 4L, 1L), .Label = c("MPA___before-to-during", "Reference___before-to-during", 
"Reference___before-to-after", "MPA___before-to-after"), scores = structure(c(`MPA___before-to-after` = 0.125507192629372, 
`MPA___before-to-during` = 0.0948855602219911, `Reference___before-to-after` = 0.121295868163829, 
`Reference___before-to-during` = 0.0972135240114708), .Dim = 4L, .Dimnames = list(
    c("MPA___before-to-after", "MPA___before-to-during", "Reference___before-to-after", 
    "Reference___before-to-during"))), class = "factor"), name = c("sd_ref_pooled_before_after", 
"sd_ref_pooled_before_during", "sd_smr_pooled_before_after", 
"sd_smr_pooled_before_during", "sd_ref_pooled_before_after", 
"sd_ref_pooled_before_during", "sd_smr_pooled_before_after", 
"sd_smr_pooled_before_during", "sd_ref_pooled_before_after", 
"sd_ref_pooled_before_during", "sd_smr_pooled_before_after", 
"sd_smr_pooled_before_during", "sd_ref_pooled_before_after", 
"sd_ref_pooled_before_during", "sd_smr_pooled_before_after", 
"sd_smr_pooled_before_during", "sd_ref_pooled_before_after", 
"sd_ref_pooled_before_during", "sd_smr_pooled_before_after", 
"sd_smr_pooled_before_during"), sd_pooled = c(0.0640133632403095, 
0.059224209496302, 0.0418411590759088, 0.0420366263878186, 0.0697371748889264, 
0.0713939572229526, 0.0662209469675998, 0.0673861920919254, 0.0952259175162696, 
0.0973881903133112, 0.104688903793631, 0.104123442035945, 0.0831395386888112, 
0.0736773344066338, 0.0870890086043125, 0.082205340195828, 0.0622386704700814, 
0.0506360166386964, 0.0776340589400514, 0.057490214920967), group = structure(c(1L, 
1L, 1L, 1L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 2L, 
2L, 2L, 2L), .Label = c("Group 5", "Group 4", "Group 3", "Group 2", 
"Group 1"), class = "factor"), period = structure(c(1L, 2L, 1L, 
2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
2L), .Label = c("Before-to-after", "Before-to-during"), class = "factor"), 
    MPA_type = structure(c(1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 
    1L, 2L, 2L, 1L, 1L, 2L, 2L, 1L, 1L, 2L, 2L), .Label = c("Out", 
    "In"), class = "factor"), Df = c(1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), SumOfSqs = c(0.644667474362213, 
    0.163718859184403, 0.531883138574452, 0.172377817596512, 
    1.36062525175964, 0.561260198791761, 1.26106114133322, 0.478287656340437, 
    1.12522630961807, 0.502450621711331, 0.779126478533436, 0.349888339609262, 
    0.64822862542131, 0.198815304465667, 0.329502905266225, 0.124876688005652, 
    0.197752601704789, 0.10862759418973, 0.142471900603864, 0.0840130152284379
    ), R2 = c(0.190110542714351, 0.0631029576320754, 0.217228522650464, 
    0.089364183731598, 0.076782933708657, 0.0349456770960147, 
    0.0732327885619086, 0.0303186954655169, 0.0788241854776924, 
    0.0376889492950336, 0.0656167575864088, 0.0312644101580068, 
    0.288412156204619, 0.123882033933067, 0.158350315762715, 
    0.0838360162000489, 0.0226863909348303, 0.0137219062151816, 
    0.0222248102598127, 0.0150399647150649), F = c(9.62419276009816, 
    2.4247130389196, 11.3779943270621, 3.53281801227694, 10.4792794679964, 
    4.27290961706825, 9.00823614929462, 3.37679925864692, 10.610568411745, 
    4.50397942095095, 7.93538804068383, 3.45325589560756, 6.07961811151075, 
    1.83818447230295, 2.44585620771756, 1.18959949296437, 3.29624747150235, 
    1.85040460507006, 2.25026799494279, 1.42007459023087), `p-val` = c(0.001, 
    0.05, 0.001, 0.006, 0.001, 0.001, 0.001, 0.002, 0.001, 0.001, 
    0.001, 0.005, 0.001, 0.076, 0.017, 0.31, 0.005, 0.069, 0.037, 
    0.195), sig = c("*", "", "*", "*", "*", "*", "*", "*", "*", 
    "*", "*", "*", "*", "", "*", "", "*", "", "*", "")), row.names = c(NA, 
-20L), class = "data.frame")

Plotting code:

p1 <- 
  sig_distance %>%
  rename("Period"=period)%>%
  filter(Period == "Before-to-during")%>%
  mutate(group = factor(group))%>%
  arrange(MPA_type, -value, group)%>%
  ggplot(aes(x=reorder(MPA_type, -value), y=value, color=group, 
             #shape=group, 
             #fill=MPA_type
             ))+
  geom_point(position = position_dodge(width=0.8),
             size=3)+
  geom_errorbar(aes(ymin=value-sd_pooled,
                    ymax = value+sd_pooled), stat="identity",
                position = position_dodge(width=0.8), size=0.3, width=.3)+
  #add significance level
  geom_text(aes(label=sig), size=5, vjust=-0.01,
            position = position_dodge(width=0.8),
            show.legend = FALSE)+
  ylab("Distance (Bray-Curtis)")+
  xlab("Community")+
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        legend.key=element_blank())

Solution

  • One option would be to add a helper column to you dataset as the interaction of MPA_type and group for which you set the order using forcats::fct_inorder after you arranged your dataset according to your desired order. Thus helper column could then be mapped on the group aes:

    library(ggplot2)
    library(dplyr)
    library(forcats)
    
    sig_distance %>%
      rename("Period" = period) %>%
      filter(Period == "Before-to-during") %>%
      mutate(group = factor(group)) %>%
      arrange(MPA_type, -value, group) %>%
      mutate(mpa_ordered = fct_inorder(paste(MPA_type, group, sep = "."))) |> 
      ggplot(aes(x = MPA_type, y = value, color = group, group = mpa_ordered)) +
      geom_point(
        position = position_dodge(width = 0.8),
        size = 3
      ) +
      geom_errorbar(
        aes(
          ymin = value - sd_pooled,
          ymax = value + sd_pooled
        ),
        stat = "identity",
        position = position_dodge(width = 0.8), size = 0.3, width = .3
      ) +
      geom_text(aes(label = sig),
        size = 5, vjust = -0.01,
        position = position_dodge(width = 0.8),
        show.legend = FALSE
      ) +
      ylab("Distance (Bray-Curtis)") +
      xlab("Community") +
      theme(
        panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
        panel.background = element_blank(), axis.line = element_line(colour = "black"),
        legend.key = element_blank()
      )
    

    enter image description here