rdropsjplotcrosstable

argument drop.empty not working in sjt.xtab function from sjPlot package


Lets say I have a factor level that I need to delete for the analysis for whatever reasons. I make a subset, but the factor level still exists.

Luckily, there is an argument in sjt.xtab that specifies:

drop.empty: Logical, if TRUE and the variable’s values are labeled, values that have no observations are still printed in the table (with frequency 0). If FALSE, values / factor levels with no occurrence in the data are omitted from the output.

Source: https://cran.r-project.org/web/packages/sjPlot/sjPlot.pdf

But it isn't working. Here is a minimal working example:

color <- factor(c("blue", "yellow", "red", "red", "blue"))
object <- factor(c("table", "chair", "table", "chair", "chair"))
df <- data.frame(color, object)

sjPlot::sjt.xtab(df$color, df$object) # We decide to delete "yellow" case(s)

df <- subset(df, color == "red" | color == "blue")
sjPlot::sjt.xtab(df$color, df$object, drop.empty = FALSE) 

Does anybody knows why is it not working?

I know we could use the droplevels() function but I would like to know if I am doing something wrong with the drop.empty argument

Best,


Solution

  • It seems that you are confusing factor labels, which are base R, and variable labels, which are implemented in some packages such as haven.

    Here is an example:

    library(tidyverse)
    library(sjPlot)
    #> Learn more about sjPlot with 'browseVignettes("sjPlot")'.
    data(efc)
    x = efc %>% filter(e42dep!=4) %>% pull(e16sex)
    y = efc %>% filter(e42dep!=4) %>% pull(e42dep)
    sjPlot::sjt.xtab(x, y, drop.empty=TRUE) 
    

    output1

    sjPlot::sjt.xtab(x, y, drop.empty=FALSE) 
    

    output2 Created on 2022-07-04 by the reprex package (v2.0.1)

    As you used the crosstable tag, note that you can use the crosstable package as well for this kind of work (disclaimer: I'm the creator of the package).

    However, there is no drop.empty option yet so you have to use forcats::fct_drop() to get rid of them beforehand. I should definitely add this kind of option someday!

    Here is some code:

    color <- factor(c("blue", "yellow", "red", "red", "blue"))
    object <- factor(c("table", "chair", "table", "chair", "chair"))
    df <- data.frame(color, object)
    library(tidyverse)
    library(crosstable)
    df %>% 
      mutate(color=fct_drop(color)) %>% 
      crosstable::crosstable(color, by=object) %>% 
      as_flextable()
    

    output1

    df %>% 
      mutate(color=fct_drop(color)) %>% 
      crosstable::crosstable(color, by=object, test=TRUE) %>% 
      as_flextable(compact=TRUE)
    

    output2

    Created on 2022-07-04 by the reprex package (v2.0.1)