Search code examples
rggplot2position-dodge

How to change the order of dodged columns in R?


I am trying to display dodged columns in descending order by the 'rank' variable, since they show up in ascending order, but I can't seem to figure that out.

I have tried to adapt some suggestions already posted to no avail. When I try the y=factor(rank, levels = rev(levels(rank))) it gives me an error, and including the reverse=TRUE inside the position_dodge2 function doesn't have any effect.

This is my code:

str1 <- data.frame(
  mo = c('jan', 'feb', 'mar', 'apr', 'may', 'jan', 'feb', 'jan', 'apr', 'apr', 
         'feb', 'may', 'feb', 'may', 'apr', 'jun', 'apr', 'jun', 'apr', 'jun'), 
  rank = c(9.5, 9.2, 9.1, 9.1, 9.0, 8.8, 8.7, 8.7, 8.6, 8.6, 8.6, 8.6, 8.5,
           8.5, 8.5, 8.4, 8.4, 8.4, 8.4, 8.8),
  value= c(2226, 139, 18428, 227899, 10000, 558, 1, 700, 10, 1313, 2, 1530, 1,
           700, 1530, 168, NA, 50, NA, 3022))

str1 <- with(str1, str1[order(mo, -as.numeric(rank)), ]) # I have tried this from another post to no avail

ggplot(str1, aes(x=reorder(mo, -value), y=rank, fill=value))+ 
  geom_col(position=position_dodge2(preserve = "single", reverse=T)) +
  coord_flip()

Solution

  • First, you need to fix the ordering:

    str1 <- with(str1, str1[order(mo, rank), ])
    

    I would then set the order of the mo order by making it a factor

    str1$mo <- factor(str1$mo, levels = c("jan", "feb", "mar", "apr", "may", "jun"))
    

    And then you don't need to use the reorder() function for the x aesthetic. Ten the reverse argument to position_dodge2() should work as you expect:

    ggplot(str1, aes(x=mo, y=rank, fill=value))+ 
      geom_col(position=position_dodge2(preserve = "single", reverse=T)) +
      coord_flip()
    

    This should give you this (I hope it is what you are after):

    enter image description here

    If you want to reverse the order of the months you can do that too with scale_x_discrete(limits=rev) (its x in this case cause you have used coord_flip().

    ggplot(str1, aes(x=mo, y=rank, fill=value))+ 
      geom_col(position=position_dodge2(preserve = "single")) +
      coord_flip() +
      scale_x_discrete(limits=rev)
    
    

    enter image description here