Display results of a regression model in a table



This post use the gtsummary package to show the results of a regression model in a table. We’ll go through how to show p-values, confidence intervals, compare models and more with gtsummary.

Table Data to Viz

Packages


For this post, we need to load the following library:

# install.packages("gtsummary")
library(gtsummary)


Default output for regression results


The gtsummary uses the tbl_regression() function to automatically generate results of the model in a table.

In this case, we use the Titanic dataset, with the Survived variable as the target.

# create dataset
data("Titanic")
df = as.data.frame(Titanic)

# create the model
model = glm(Survived ~ Age + Class + Sex + Freq,
            family=binomial, data=df)

# generate table 
model %>%
  tbl_regression()
Characteristic log(OR)1 95% CI1 p-value
Age


    Child
    Adult 0.62 -1.0, 2.4 0.5
Class


    1st
    2nd -0.03 -2.0, 2.0 >0.9
    3rd 0.25 -1.8, 2.4 0.8
    Crew 0.27 -1.8, 2.4 0.8
Sex


    Male
    Female -0.37 -1.9, 1.1 0.6
Freq -0.01 -0.02, 0.00 0.3
1 OR = Odds Ratio, CI = Confidence Interval

Add more statistical details


If we take the code from above, we can add other elements to the table that will make the table much more informative and detailed: - add_glance_source_note(): Adds a footnote to the table with information from the glance() function, like the number of observations, R-squared for regression models, etc - add_global_p(): Appends a global p-value to the table which assesses the overall significance of categorical variables. - add_q(): Incorporates q-values in the table, which are adjusted p-values used in multiple testing to control the false discovery rate.

# create dataset
data("Titanic")
df = as.data.frame(Titanic)

# create the model
model = glm(Survived ~ Age + Class + Sex + Freq,
            family=binomial, data=df)

# generate table 
model %>%
  tbl_regression(intercept=TRUE, conf.level=0.9) %>%
  add_glance_source_note() %>%
  add_global_p() %>%
  add_q() 
Characteristic log(OR)1 90% CI1 p-value q-value2
(Intercept) 0.10 -1.4, 1.6 >0.9 >0.9
Age

0.5 >0.9
    Child

    Adult 0.62 -0.78, 2.1

Class

>0.9 >0.9
    1st

    2nd -0.03 -1.7, 1.7

    3rd 0.25 -1.5, 2.0

    Crew 0.27 -1.5, 2.0

Sex

0.6 >0.9
    Male

    Female -0.37 -1.7, 0.89

Freq -0.01 -0.02, 0.00 0.2 0.9
Null deviance = 44.4; Null df = 31.0; Log-likelihood = -21.3; AIC = 56.5; BIC = 66.8; Deviance = 42.5; Residual df = 25; No. Obs. = 32
1 OR = Odds Ratio, CI = Confidence Interval
2 False discovery rate correction for multiple testing

Display results of different models


One easy way to show the results of 2 different models into a single table is to: - create a first table with the first model (logistic regression) - create a second table with the second model (Cox proportional hazards regression) - merge these tables with tbl_merge() - add a spanner for each model with the tab_spanner argument

In this case we use the trial dataset:

library(survival)
library(gtsummary)

data(trial)

model_reglog = glm(response ~ trt + grade, data=trial, family = binomial) %>% tbl_regression()
model_cox = coxph(Surv(ttdeath, death) ~ trt + grade, data=trial) %>% tbl_regression()

tbl_merge(
  list(model_reglog, model_cox),
  tab_spanner = c("**Tumor Response**", "**Time to Death**")
)
Characteristic Tumor Response Time to Death
log(OR)1 95% CI1 p-value log(HR)1 95% CI1 p-value
Chemotherapy Treatment





    Drug A

    Drug B 0.19 -0.41, 0.81 0.5 0.22 -0.15, 0.59 0.2
Grade





    I

    II -0.06 -0.82, 0.68 0.9 0.25 -0.22, 0.72 0.3
    III 0.08 -0.66, 0.82 0.8 0.52 0.07, 0.98 0.024
1 OR = Odds Ratio, CI = Confidence Interval, HR = Hazard Ratio

Conclusion

This post explained how to display the results of a regression model in a table using the gtsummary library. For more of this package, see the dedicated section or the table section.

Related chart types


Line plot
Area
Stacked area
Streamchart
Time Series



❤️ 10 best R tricks ❤️

👋 After crafting hundreds of R charts over 12 years, I've distilled my top 10 tips and tricks. Receive them via email! One insight per day for the next 10 days! 🔥