Home > Net >  Sorting facets in ggplot using facet_grid
Sorting facets in ggplot using facet_grid

Time:12-04

I have scoured SO trying to find a fix for this. I've found a few answers, but when I apply them, they don't work as I am intending (or maybe I"m just doing something wrong). Basically, I have a dataset that I am trying to plot using facet_grid. My problem is twofold:

  1. I want the the grids to be sorted according to a numeric value
  2. I have a grouping variable that I also want sorted by a numeric value (descending) but I want to be able to assign an ascending count number to a group (i.e., highest group gets a 1, 2nd highest gets a 2, etc) so that I can select the highest group first, then the 2nd highest group, etc. I have many many groups and the values and names that come with those groups are random, so I don't want to manually assign the values.

Here is an example of what I am trying to do:

  grp.name   = c("T","F","P","T","F","P","T","F","P","T","F","P"), 
  grp.num   = c(0.995,0.875,0.500,0.995,0.875,0.500,0.995,0.875,0.500,0.995,0.875,0.500),
  ind.name  = c("L","N","M","C","A","B","I","H","G","D","F","E"),
  amount = c(48.4, 48.1, 46.8, 25.9, 26, 24.9, 21.1, 21.4, 20.1, 20.8, 21.5, 16.5)
)

df <- df[order(-df$grp.num,-df$amount),]

t <-  ggplot(data=subset(df,grp.name=="T"), aes(grp.name, amount, fill=grp.name, group=grp.name, shape=grp.name, facets=grp.name))  
  geom_col(width=0.5, position = position_dodge(width=0.6))   
  facet_grid(grp.name   paste0("Number: ",grp.num)  ~ ind.name   paste0("Number: ",amount),switch = "y") 
t

My reason for subsetting just group T in this case is because I want to plot out the 10 highest groups and then stack them in another plot using grid.arrange. I would like to be able to just subset group 1, then 2, then 3, etc without knowing the name, because, again, these names change.

Here is what I get. Instead of sorting the facets by amount it is sorting them alphabetically by ind.name. I would like the "L" group first, as it has the highest amount, followed by "C", then "I", then "D". Again, I don't want to do this manually, as these values change and I am redoing these plots over many many groups.
enter image description here

CodePudding user response:

How about this:

t <-  ggplot(data=subset(df,grp.name=="T"), aes(grp.name, amount, fill=grp.name, group=grp.name, shape=grp.name))  
  geom_col(width=0.5, position = position_dodge(width=0.6))   
  facet_grid(grp.name   paste0("Number: ",grp.num)  ~ reorder(ind.name, -amount, mean)   paste0("Number: ",amount),switch = "y") 
t

enter image description here

CodePudding user response:

Sometimes, its simpler to carry out the preparation of data prior to passing to the ggplot function.

Faceting order works on factors, so convert ind.name to a factor ordered by amount. Create a grp_nr based on factor order.

Revised following OP's comments and new dataset.

library(ggplot2)
library(forcats)
library(dplyr)

df %>%
  mutate(ind.name = fct_rev(fct_reorder(ind.name, amount)),
         amount = round(amount, 3),
         grp.num_lev = as.integer(fct_rev(factor(grp.num))),
         grp.num = round(grp.num, 3))%>%
  filter(grp.num_lev==1) %>%
  ggplot(aes(grp.name, amount, fill=grp.name, group=grp.name, shape=grp.name))     
  geom_col(width=0.5, position = position_dodge(width=0.6))     
  facet_grid(grp.name   paste0("Number: ", grp.num)  ~ ind.name   paste0("Number: ", amount), switch = "y")

Created on 2021-12-03 by the reprex package (v2.0.1)

data

df <- data.frame(grp.name   = c("T","F","P","T","F","P","T","F","P","T","F","P"),
                 grp.num   = c(0.9954,0.8754,0.5006,0.9954,0.8754,0.5006,0.9954,0.8754,0.5006,0.9954,0.8754,0.5006),   
                 ind.name  = c("L","N","M","C","A","B","I","H","G","D","F","E"),   
                 amount = c(48.41234, 48.12343, 46.83546, 25.9454, 26.01568, 24.946454, 21.1, 21.4545, 20.1, 20.8, 21.5644, 16.5) )

  • Related