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.
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")
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