grouped barplot: order x-axis & keep constant bar width, in case of missing levels

前端 未结 4 561
情话喂你
情话喂你 2021-01-21 14:12

Here is my script (example inspired from here and using the reorder option from here):

library(ggplot2)
Animals <- read.table(
  header=TRUE, tex         


        
相关标签:
4条回答
  • 2021-01-21 14:26

    Along the same lines as the answer from user Alex, a less manual way of adding the categories might be

    d <- with(Animals, expand.grid(unique(Category), unique(Reason)))
    names(d) <- names(Animals)[1:2]
    Animals <- merge(d, Animals, all.x=TRUE)
    Animals$Species[is.na(Animals$Species)] <- 0
    
    0 讨论(0)
  • 2021-01-21 14:37

    To achieve something like that I would adjust the data frame when working with ggplot. Add the missing categories with a value of zero.

    Animals <- rbind(Animals, 
                     data.frame(Category = c("Improved", "Decline"), 
                                Reason = c("Hello", "Bla"), 
                                Species = c(0,0)
                                )
    )
    
    0 讨论(0)
  • 2021-01-21 14:41

    First let's fill your data.frame with missing combinations like this.

    library(dplyr)
    Animals2 <- expand.grid(Category=unique(Animals$Category), Reason=unique(Animals$Reason)) %>% data.frame %>% left_join(Animals)
    

    Then you can create an ordering variable for the x-scale:

    myorder <- Animals2 %>% filter(Category=="Decline") %>% arrange(desc(Species)) %>% .$Reason %>% as.character
    

    An then plot:

    ggplot(Animals2, aes(x=Reason, y=Species, fill = Category)) + 
      geom_bar(stat="identity", position = "dodge") + scale_x_discrete(limits=myorder)
    

    0 讨论(0)
  • Define new data frame with all combinations of "Category" and "Reason", merge with data of "Species" from data frame "Animals". Adapt ggplot by correct scale_x_discrete:

    Animals3 <-  expand.grid(Category=unique(Animals$Category),Reason=unique(Animals$Reason))
    Animals3 <- merge(Animals3,Animals,by=c("Category","Reason"),all.x=TRUE)
    Animals3[is.na(Animals3)] <- 0
    Animals3 <- Animals3[order(Animals3$Category,-Animals3$Species),]
    ggplot(Animals3, aes(x=Animals3$Reason, y=Species, fill = Category)) + geom_bar(stat="identity", position = "dodge") + scale_x_discrete(limits=as.character(Animals3[Animals3$Category=="Decline","Reason"]))
    
    0 讨论(0)
提交回复
热议问题