Search code examples
rggplot2r-forestplot

ggplot forest plot change order of variables


I would like to order the variable "test" by the largest OR.

structure(list(test = c("a", "b", "c", "d", "e", "f", "g"), OR = c(2.78, 
1.74, 1.32, 1.16, 0.92, 0.75, 0.53), LowerLimit = c(2.11, 0.96, 
1.11, 0.74, 0.61, 0.52, 0.4), UpperLimit = c(3.72, 3.25, 1.58, 
1.85, 1.4, 1.09, 0.71), Group = 1:7), class = "data.frame", row.names = c(NA, 
-7L)

p = ggplot(data=table,
       aes(x = reorder (test, -OR), y = OR, ymin = LowerLimit, ymax = UpperLimit )) +
geom_pointrange(aes(col=test), size = 1.5)+
  geom_hline(aes(fill=test),  yintercept =1, linetype=2)+
  xlab('test')+ 
  ylab("Odd's Ratio (95% Confidence Interval)")+
  geom_errorbar(aes(ymin=LowerLimit, ymax=UpperLimit,col=test),width=0.5,cex=1)+ 
  facet_wrap(~test,strip.position="left",nrow=9,scales = "free_y") +
  theme(plot.title=element_text(size=16,face="bold"),
    axis.text.y=element_blank(),
    axis.ticks.y=element_blank(),
    axis.text.x=element_text(face="bold"),
    axis.title=element_text(size=12,face="bold"),
    strip.text.y = element_text(hjust=0,vjust = 1,angle=180,face="bold"))+
  coord_flip()
p

I have reviewed this post Order Bars in ggplot2 bar graph

I have tried the reorder command and also the example of creating a "positions" list and neither work.


Solution

  • This works as expected if you reorder the variable test first, rather than trying to mutate your data inside the aes function.

    Compare this:

    table %>% 
      mutate(test = reorder(test, OR)) %>%       
      ggplot(aes(x = test, y = OR, ymin = LowerLimit, ymax = UpperLimit )) +
      geom_pointrange(aes(col = test), size = 1.5) +
      geom_hline(yintercept = 1, linetype = 2) +
      geom_errorbar(aes(ymin = LowerLimit, ymax = UpperLimit, col = test),
                    width = 0.5, cex = 1) + 
      coord_flip() +
      facet_wrap(~test, strip.position = "left", nrow = 9, scales = "free_y") +
      xlab('test') + 
      ylab("Odds Ratio (95% Confidence Interval)") +
      theme(plot.title   = element_text(size=16,face="bold"),
            axis.text.y  = element_blank(),
            axis.ticks.y = element_blank(),
            axis.text.x  = element_text(face="bold"),
            axis.title   = element_text(size=12,face="bold"),
            strip.text.y = element_text(hjust = 0, vjust = 1,
                                        angle = 180, face = "bold"))
    

    enter image description here

    To exactly the same code with a - sign in front of OR inside reorder:

    table %>% 
      mutate(test = reorder(test, -OR)) %>%       
      ggplot(aes(x = test, y = OR, ymin = LowerLimit, ymax = UpperLimit )) +
      geom_pointrange(aes(col = test), size = 1.5) +
      geom_hline(yintercept = 1, linetype = 2) +
      geom_errorbar(aes(ymin = LowerLimit, ymax = UpperLimit, col = test),
                    width = 0.5, cex = 1) + 
      coord_flip() +
      facet_wrap(~test, strip.position = "left", nrow = 9, scales = "free_y") +
      xlab('test') + 
      ylab("Odds Ratio (95% Confidence Interval)") +
      theme(plot.title   = element_text(size=16,face="bold"),
            axis.text.y  = element_blank(),
            axis.ticks.y = element_blank(),
            axis.text.x  = element_text(face="bold"),
            axis.title   = element_text(size=12,face="bold"),
            strip.text.y = element_text(hjust = 0, vjust = 1,
                                        angle = 180, face = "bold"))
    

    enter image description here