Search code examples
rlabelbar-chartsjplot

Problem with sjPlot::plot_xtab mislabelling factor levels


sjPlot::plot_xtab is a useful tool to quickly generate grouped bar plots with count and % labels on the bars. I have been experiencing a very annoying issue with it though. plot_xtab is reordering and mislabeling the levels of my factor of interest. What seems to be happening is that it's ordering the levels by lexical order, but then mislabels them with the actual factor labels in labelled order. This is a serious problem of course. Here's a reproducible example:

library(tidyverse)
library(forcats)
library(gtools)
library(sjPlot)
data("mtcars")

cars <- as_tibble(mtcars) %>% 
  mutate(carb_cat=case_when(carb <3~"Low", carb==3 | carb ==4~"Med", carb>4~"High"), 
    carb_cat=fct_relevel(carb_cat, "Low", "Med", "High"))

unique(cars$carb_cat)

cars$mpg_3 <- quantcut(cars$mpg, q=3)

plot_xtab(cars$mpg_3, cars$carb_cat, show.total = F)

When I plot cars$carb_cat by cars$mpg_3, plot_xtab reorders and mislabels my factor levels. If you compare the counts on the bars to the frequency table below, you'll note that the actual level "High" is labelled in the bars and legends as "Low", "Medium" is labelled as "High", and "Low" is labelled "Medium".

cars %>% count(carb_cat)

  carb_cat     n
  <fct>    <int>
1 Low         17
2 Med         13
3 High         2

I've run into this issue several times now using real data, and there is no argument that I see in plot_xtab that seems to address this.

enter image description here


Solution

  • Looks like a bug has been introduced in the latest version of sjPlot (since 2.8.2). In version 2.8.0, I get the correct graph:

    library(tidyverse)
    library(forcats)
    library(gtools)
    library(sjPlot)
    
    data(mtcars)
    
    cars <- mtcars %>% 
      mutate(carb_cat=case_when(carb <3~"Low", 
                                carb==3 | carb ==4~"Med", 
                                carb>4~"High"), 
             carb_cat=fct_relevel(carb_cat, "Low", "Med", "High"))
    
    cars$mpg_3 <- quantcut(cars$mpg, q=3)
    
    plot_xtab(cars$mpg_3, cars$carb_cat, show.total = F) +
       ggtitle("sjPlot version 2.8.0")
    

    enter image description here

                 carb_cat
    mpg_3         Low Med High
      [10.4,16.7]   2   8    1
      (16.7,21.4]   5   5    1
      (21.4,33.9]  10   0    0