sjtable2df: Overview

The sjPlot R package is a great package for visualizing results.

However, the tables created using the functions sjPlot::tab_model or sjPlot::tab_xtab return HTML tables and are not straightforward to use in R, especially when trying to integrate them into pdf- or word-documents using Rmarkdown.

Various approaches/ tutorials exist to convert sjPlot HTML tables to R data.frame objects:

None of these approaches converts sjPlot HTML tables to R data.frame objects or integrates well with knitr::kable or the kableExtra R package.

The sjtable2df R package’s goal is to overcome this and to provide an easy interface for converting sjPlot’s HTML tables to data.frame, data.table, or kable objects for further usage in R or Rmarkdown.

Currently, sjtable2df provides two functions to convert tables created from sjPlot’s functions tab_model and tab_xtab: sjtable2df::mtab2df and sjtable2df::xtab2df.

Example: Contingency-Tables

Data Preprocessing

library(sjtable2df)

library(mlbench)
library(magrittr)

# load data
data("PimaIndiansDiabetes2")
dataset <- PimaIndiansDiabetes2 %>%
  data.table::as.data.table()

# create new binary variable
dataset[, ("preg_gt_4") := ifelse(get("pregnant") > 4, 1, 0) %>% factor()]

Create Contingency Table

xtab <- sjPlot::tab_xtab(
  var.row = dataset$diabetes,
  var.col = dataset$preg_gt_4,
  show.summary = TRUE,
  use.viewer = FALSE
)
xtab
diabetes preg_gt_4 Total
0 1
neg 356 144 500
pos 136 132 268
Total 492 276 768
χ2=30.823 · df=1 · φ=0.203 · p=0.000

Convert Contingency Table to data.frame

xtab_df <- sjtable2df::xtab2df(xtab = xtab, output = "data.frame")
class(xtab_df)
#> [1] "data.frame"
xtab_df
#>   diabetes preg_gt_4 0 preg_gt_4 1                                Total
#> 1      neg         356         144                                  500
#> 2      pos         136         132                                  268
#> 3    Total         492         276                                  768
#> 4                                  χ2=30.823 · df=1 · φ=0.203 · p=0.000

Convert Contingency Table to kable

xtab_kbl <- sjtable2df::xtab2df(
  xtab = xtab,
  output = "kable",
  caption = "Diabetes vs. preg>4",
  col.names = c("Diabetes", "No", "Yes", "Total")
)
class(xtab_kbl)
#> [1] "kableExtra"  "knitr_kable"
xtab_kbl %>%
  kableExtra::add_header_above(
    header = c(" " = 1, "Pregnant > 4" = 2, " " = 1)
  )
Diabetes vs. preg>4
Pregnant > 4
Diabetes No Yes Total
neg 356 144 500
pos 136 132 268
Total 492 276 768
\(χ2=30.823 · df=1 · φ=0.203 · p=0.000\)

Percentages in cells

This function also extracts further statistics from cells and writes them to parentheses:

xtab <- sjPlot::tab_xtab(
  var.row = dataset$diabetes,
  var.col = dataset$preg_gt_4,
  show.summary = TRUE,
  show.col.prc = TRUE,
  use.viewer = FALSE
)
xtab
diabetes preg_gt_4 Total
0 1
neg 356
72.4 %
144
52.2 %
500
65.1 %
pos 136
27.6 %
132
47.8 %
268
34.9 %
Total 492
100 %
276
100 %
768
100 %
χ2=30.823 · df=1 · φ=0.203 · p=0.000

Convert Contingency Table to data.frame

xtab_df <- sjtable2df::xtab2df(xtab = xtab, output = "data.frame")
xtab_df
#>   diabetes  preg_gt_4 0  preg_gt_4 1                                Total
#> 1      neg 356 (72.4 %) 144 (52.2 %)                         500 (65.1 %)
#> 2      pos 136 (27.6 %) 132 (47.8 %)                         268 (34.9 %)
#> 3    Total  492 (100 %)  276 (100 %)                          768 (100 %)
#> 4                                    χ2=30.823 · df=1 · φ=0.203 · p=0.000

Example: Model Tables: Linear Regression

Create Three Models

m0 <- lm(
  pressure ~ 1,
  data = dataset
)
m1 <- lm(
  pressure ~ glucose,
  data = dataset
)
m2 <- lm(
  pressure ~ glucose + diabetes,
  data = dataset
)

Create Model Table

m_table <- sjPlot::tab_model(
  m0, m1, m2,
  show.aic = TRUE
)
m_table
  pressure pressure pressure
Predictors Estimates CI p Estimates CI p Estimates CI p
(Intercept) 72.41 71.51 – 73.30 <0.001 61.46 57.85 – 65.06 <0.001 62.65 58.85 – 66.44 <0.001
glucose 0.09 0.06 – 0.12 <0.001 0.07 0.04 – 0.11 <0.001
diabetes [pos] 2.06 -0.06 – 4.18 0.056
Observations 733 728 728
R2 / R2 adjusted 0.000 / 0.000 0.050 / 0.049 0.055 / 0.052
AIC 5771.995 5697.909 5696.248

Convert Model Table to data.frame

mtab_df <- sjtable2df::mtab2df(
  mtab = m_table,
  n_models = 3,
  output = "data.frame"
)
class(mtab_df)
#> [1] "data.frame"
mtab_df
#>         Predictors     Estimates            CI      p     Estimates
#> 1      (Intercept)         72.41 71.51 – 73.30 <0.001         61.46
#> 2          glucose                                             0.09
#> 3   diabetes [pos]                                                 
#> 4     Observations           733                                728
#> 5 R2 / R2 adjusted 0.000 / 0.000                      0.050 / 0.049
#> 6              AIC      5771.995                           5697.909
#>              CI      p     Estimates            CI      p
#> 1 57.85 – 65.06 <0.001         62.65 58.85 – 66.44 <0.001
#> 2   0.06 – 0.12 <0.001          0.07   0.04 – 0.11 <0.001
#> 3                               2.06  -0.06 – 4.18  0.056
#> 4                                728                     
#> 5                      0.055 / 0.052                     
#> 6                           5696.248

Convert Model Table to kable

mtab_kbl <- sjtable2df::mtab2df(
  mtab = m_table,
  n_models = 3,
  output = "kable"
)
class(mtab_kbl)
#> [1] "kableExtra"  "knitr_kable"
mtab_kbl
pressure
Predictors Estimates CI p Estimates CI p Estimates CI p
(Intercept) 72.41 71.51 – 73.30 <0.001 61.46 57.85 – 65.06 <0.001 62.65 58.85 – 66.44 <0.001
glucose 0.09 0.06 – 0.12 <0.001 0.07 0.04 – 0.11 <0.001
diabetes [pos] 2.06 -0.06 – 4.18 0.056
Observations 733 728 728
\(R^2\) / \(R^2\) adjusted 0.000 / 0.000 0.050 / 0.049 0.055 / 0.052
AIC 5771.995 5697.909 5696.248

Example: Model Tables: Logistic Regression

Create Three Models

m0 <- stats::glm(
  diabetes ~ 1,
  data = dataset,
  family = binomial(link = "logit")
)
m1 <- stats::glm(
  diabetes ~ glucose,
  data = dataset,
  family = binomial(link = "logit")
)
m2 <- stats::glm(
  diabetes ~ glucose + pressure,
  data = dataset,
  family = binomial(link = "logit")
)

Create Model Table

m_table <- sjPlot::tab_model(
  m0, m1, m2,
  show.aic = TRUE
)
m_table
  diabetes diabetes diabetes
Predictors Odds Ratios CI p Odds Ratios CI p Odds Ratios CI p
(Intercept) 0.54 0.46 – 0.62 <0.001 0.00 0.00 – 0.01 <0.001 0.00 0.00 – 0.01 <0.001
glucose 1.04 1.03 – 1.05 <0.001 1.04 1.03 – 1.05 <0.001
pressure 1.01 1.00 – 1.03 0.060
Observations 768 763 728
R2 Tjur 0.000 0.249 0.246
AIC 995.484 790.560 754.636

Convert Model Table to data.frame

mtab_df <- sjtable2df::mtab2df(
  mtab = m_table,
  n_models = 3,
  output = "data.frame"
)
class(mtab_df)
#> [1] "data.frame"
mtab_df
#>     Predictors Odds Ratios          CI      p Odds Ratios          CI      p
#> 1  (Intercept)        0.54 0.46 – 0.62 <0.001        0.00 0.00 – 0.01 <0.001
#> 2      glucose                                       1.04 1.03 – 1.05 <0.001
#> 3     pressure                                                              
#> 4 Observations         768                            763                   
#> 5      R2 Tjur       0.000                          0.249                   
#> 6          AIC     995.484                        790.560                   
#>   Odds Ratios          CI      p
#> 1        0.00 0.00 – 0.01 <0.001
#> 2        1.04 1.03 – 1.05 <0.001
#> 3        1.01 1.00 – 1.03  0.060
#> 4         728                   
#> 5       0.246                   
#> 6     754.636

Convert Model Table to kable

mtab_kbl <- sjtable2df::mtab2df(
  mtab = m_table,
  n_models = 3,
  output = "kable"
)
class(mtab_kbl)
#> [1] "kableExtra"  "knitr_kable"
mtab_kbl
diabetes
Predictors Odds Ratios CI p Odds Ratios CI p Odds Ratios CI p
(Intercept) 0.54 0.46 – 0.62 <0.001 0.00 0.00 – 0.01 <0.001 0.00 0.00 – 0.01 <0.001
glucose 1.04 1.03 – 1.05 <0.001 1.04 1.03 – 1.05 <0.001
pressure 1.01 1.00 – 1.03 0.060
Observations 768 763 728
\(R^2\) Tjur 0.000 0.249 0.246
AIC 995.484 790.560 754.636

Example: Model Tables: GLMM

Create Three Models

set.seed(1)
dataset$city <- sample(
  x = paste0("city_", 1:7),
  size = nrow(dataset),
  replace = TRUE
)
m0 <- lme4::glmer(
  diabetes ~ 1 + (1 | city),
  data = dataset,
  family = binomial(link = "logit")
)
#> boundary (singular) fit: see help('isSingular')
m1 <- lme4::glmer(
  diabetes ~ mass + (1 | city),
  data = dataset,
  family = binomial(link = "logit")
)
m2 <- lme4::glmer(
  diabetes ~ mass + log(pressure) + (1 | city),
  data = dataset,
  family = binomial(link = "logit")
)

Create Model Table

m_table <- sjPlot::tab_model(
  m0, m1, m2,
  show.aic = TRUE
)
m_table
  diabetes diabetes diabetes
Predictors Odds Ratios CI p Odds Ratios CI p Odds Ratios CI p
(Intercept) 0.54 0.46 – 0.62 <0.001 0.02 0.01 – 0.04 <0.001 0.00 0.00 – 0.01 <0.001
mass 1.11 1.08 – 1.14 <0.001 1.10 1.07 – 1.13 <0.001
pressure [log] 3.31 1.26 – 8.67 0.015
Random Effects
σ2 3.29 3.29 3.29
τ00 0.00 city 0.01 city 0.00 city
ICC   0.00 0.00
N 7 city 7 city 7 city
Observations 768 757 729
Marginal R2 / Conditional R2 0.000 / NA 0.133 / 0.135 0.137 / 0.137
AIC 997.484 910.822 871.890

Convert Model Table to data.frame

mtab_df <- sjtable2df::mtab2df(
  mtab = m_table,
  n_models = 3,
  output = "data.frame"
)
class(mtab_df)
#> [1] "data.frame"
mtab_df
#>                      Predictors Odds Ratios          CI      p   Odds Ratios
#> 1                   (Intercept)        0.54 0.46 – 0.62 <0.001          0.02
#> 2                          mass                                         1.11
#> 3                pressure [log]                                             
#> 4                Random Effects                                             
#> 5                            σ2        3.29                             3.29
#> 6                           τ00   0.00 city                        0.01 city
#> 7                           ICC                                         0.00
#> 8                             N      7 city                           7 city
#> 9                  Observations         768                              757
#> 10 Marginal R2 / Conditional R2  0.000 / NA                    0.133 / 0.135
#> 11                          AIC     997.484                          910.822
#>             CI      p   Odds Ratios          CI      p
#> 1  0.01 – 0.04 <0.001          0.00 0.00 – 0.01 <0.001
#> 2  1.08 – 1.14 <0.001          1.10 1.07 – 1.13 <0.001
#> 3                              3.31 1.26 – 8.67  0.015
#> 4                                                     
#> 5                              3.29                   
#> 6                         0.00 city                   
#> 7                              0.00                   
#> 8                            7 city                   
#> 9                               729                   
#> 10                    0.137 / 0.137                   
#> 11                          871.890

Convert Model Table to kable

mtab_kbl <- sjtable2df::mtab2df(
  mtab = m_table,
  n_models = 3,
  output = "kable"
)
class(mtab_kbl)
#> [1] "kableExtra"  "knitr_kable"
mtab_kbl
diabetes
Predictors Odds Ratios CI p Odds Ratios CI p Odds Ratios CI p
(Intercept) 0.54 0.46 – 0.62 <0.001 0.02 0.01 – 0.04 <0.001 0.00 0.00 – 0.01 <0.001
mass 1.11 1.08 – 1.14 <0.001 1.10 1.07 – 1.13 <0.001
pressure [log] 3.31 1.26 – 8.67 0.015
Random Effects
σ2 3.29 3.29 3.29
τ00 0.00 city 0.01 city 0.00 city
ICC 0.00 0.00
N 7 city 7 city 7 city
Observations 768 757 729
Marginal \(R^2\) / Conditional \(R^2\) 0.000 / NA 0.133 / 0.135 0.137 / 0.137
AIC 997.484 910.822 871.890