Publication-ready Regression Tables to Compare Models

Using {gtsummary} & {kableExtra}

Author

Lennart Klein

Published

March 7, 2024

1 Define Your Models

mtcars$cyl <- as.factor(mtcars$cyl)
mtcars$am <- as.factor(mtcars$am)

m1 <- lm(mpg ~ wt + cyl, data = mtcars)
m2 <- lm(mpg ~ wt + cyl + am, data = mtcars)
m3 <- lm(mpg ~ wt + cyl + am + hp, data = mtcars)
m4 <- lm(mpg ~ ., data = mtcars)

all_models <- list(
  m1, m2, m3, m4
)

2 Create a Summary Table with gtsummary

# define custom gtsummary function for regression tables
gt_tbl_custom <- function(model) {
  model |>
    tbl_regression(
      intercept = TRUE,
      estimate_fun = function(x) gtsummary::style_number(x, digits = 2)
    ) |>
    add_significance_stars(hide_se = TRUE) |>
    bold_labels() |>
    italicize_levels()
    # add_glance_table()
}

# create a regression table for each model
all_tbl <- map(all_models, gt_tbl_custom)

3 Merge the Tables

all_tbl_merged <- all_tbl |>
  tbl_merge(tab_spanner = FALSE)

4 Export to kableExtra

# number of models for labels
n <- all_tbl_merged$tbls |> length()

all_tbl_kable <- all_tbl_merged |>
  gtsummary::as_kable_extra(
    format = "latex",
    booktabs = TRUE,
    digits = 2,
    escape = TRUE,
    addtl_fmt = TRUE,
    format.args = list(nsmall = 2, big.mark = ","),
    linesep = "",
    align = "l",
    col.names = c("Variables", paste0("M", seq(n)))
  )

# all_tbl_kable |>
#   save_kable(here::here("tables", "all_tbl_kable.tex"))

5 See LaTeX Results

all_tbl_kable
Variables M1 M2 M3 M4
(Intercept) 33.99*** 33.75*** 33.71*** 17.82
wt -3.21*** -3.15** -2.50** -3.81
cyl
4
6 -4.26** -4.26** -3.03* -1.66
8 -6.07*** -6.08** -2.16 1.64
am
0
1 0.15 1.81 2.62
hp -0.03* -0.05
disp 0.01
drat 0.03
qsec 0.65
vs 1.75
gear 0.76
carb 0.51
1 *p<0.05; **p<0.01; ***p<0.001
cat(all_tbl_kable)

\begin{tabular}{>{}lllll}
\toprule
Variables & M1 & M2 & M3 & M4\\
\midrule
\textbf{(Intercept)} & 33.99*** & 33.75*** & 33.71*** & 17.82\\
\textbf{wt} & -3.21*** & -3.15** & -2.50** & -3.81\\
\textbf{cyl} &  &  &  & \\
\hspace{1em}\em{4} & — & — & — & —\\
\hspace{1em}\em{6} & -4.26** & -4.26** & -3.03* & -1.66\\
\hspace{1em}\em{8} & -6.07*** & -6.08** & -2.16 & 1.64\\
\textbf{am} &  &  &  & \\
\hspace{1em}\em{0} &  & — & — & —\\
\hspace{1em}\em{1} &  & 0.15 & 1.81 & 2.62\\
\textbf{hp} &  &  & -0.03* & -0.05\\
\textbf{disp} &  &  &  & 0.01\\
\textbf{drat} &  &  &  & 0.03\\
\textbf{qsec} &  &  &  & 0.65\\
\textbf{vs} &  &  &  & 1.75\\
\textbf{gear} &  &  &  & 0.76\\
\textbf{carb} &  &  &  & 0.51\\
\bottomrule
\multicolumn{5}{l}{\rule{0pt}{1em}\textsuperscript{1} *p<0.05; **p<0.01; ***p<0.001}\\
\end{tabular}