Skip to contents

Introduction

These vignettes will walk through examples for some of the most common tabling packages including gtsummary, kable/kableExtra, table1. All examples here work with the toy datasets such as mtcars.

gtsummary

gtsummary is commonly used for its flexibility and compatability with different types of output. The syntax is pretty straightforward and can make a table of all variables with one line of code and minimal adjusting.

gtsummary::tbl_summary(mtcars) 
Characteristic N = 321
mpg 19.2 (15.4, 22.8)
cyl
    4 11 (34%)
    6 7 (22%)
    8 14 (44%)
disp 196 (121, 334)
hp 123 (96, 180)
drat 3.70 (3.08, 3.92)
wt 3.33 (2.54, 3.65)
qsec 17.71 (16.89, 18.90)
vs 14 (44%)
am 13 (41%)
gear
    3 15 (47%)
    4 12 (38%)
    5 5 (16%)
carb
    1 7 (22%)
    2 10 (31%)
    3 3 (9.4%)
    4 10 (31%)
    6 1 (3.1%)
    8 1 (3.1%)
1 Median (Q1, Q3); n (%)

You can stratify by multiple variables using tbl_strata

trial |>
  gtsummary::tbl_strata(
    strata = trt,
    .tbl_fun =
      ~ .x |>
        gtsummary::tbl_summary(by = stage) 
  ) 
Characteristic
Drug A
Drug B
T1
N = 28
1
T2
N = 25
1
T3
N = 22
1
T4
N = 23
1
T1
N = 25
1
T2
N = 29
1
T3
N = 21
1
T4
N = 27
1
Age 43 (31, 53) 48 (41, 63) 48 (38, 61) 46 (36, 60) 47 (43, 57) 49 (42, 53) 53 (40, 59) 45 (37, 54)
    Unknown 2 1 2 2 0 0 0 4
Marker Level (ng/mL) 0.56 (0.22, 0.98) 1.00 (0.24, 1.92) 1.04 (0.28, 1.77) 0.80 (0.23, 1.94) 0.39 (0.13, 1.04) 0.59 (0.09, 1.63) 1.06 (0.25, 1.48) 0.45 (0.21, 1.20)
    Unknown 2 1 2 1 2 0 2 0
Grade







    I 8 (29%) 8 (32%) 11 (50%) 8 (35%) 9 (36%) 10 (34%) 7 (33%) 7 (26%)
    II 14 (50%) 8 (32%) 5 (23%) 5 (22%) 9 (36%) 9 (31%) 6 (29%) 12 (44%)
    III 6 (21%) 9 (36%) 6 (27%) 10 (43%) 7 (28%) 10 (34%) 8 (38%) 8 (30%)
Tumor Response 7 (25%) 6 (25%) 8 (40%) 7 (30%) 11 (46%) 7 (25%) 7 (35%) 8 (31%)
    Unknown 0 1 2 0 1 1 1 1
Patient Died 12 (43%) 11 (44%) 13 (59%) 16 (70%) 12 (48%) 16 (55%) 9 (43%) 23 (85%)
Months to Death/Censor 24.0 (18.1, 24.0) 24.0 (20.1, 24.0) 21.2 (15.7, 24.0) 19.8 (16.2, 24.0) 24.0 (18.2, 24.0) 20.4 (15.2, 24.0) 24.0 (17.5, 24.0) 15.6 (10.0, 21.9)
1 Median (Q1, Q3); n (%)

You can split tables by a variable, add missingness, change variable labels, adjust which statistics are presented and more… It is a very flexible package.

gtsummary::tbl_summary(trial, 
            by = trt,
            missing = "ifany",
            missing_text = "Missing",
            label = grade ~ "Tumor Grade",
            statistic = list(age~"{median} ({p25},{p75})",
                             marker ~ "{mean} ({sd})",
                             gtsummary::all_categorical() ~ "{n}/{N}")) |>
    gtsummary::add_p(pvalue_fun = ~ gtsummary::style_pvalue(.x, digits = 2)) |>
    gtsummary::add_overall() |>
    gtsummary::add_q(method = "fdr") |>
    gtsummary::modify_header(label = "**Variables**") |>
    gtsummary::bold_labels() |>
    gtsummary::italicize_levels() |>
    gtsummary::modify_caption("**Table 1**") 
Table 1
Variables Overall
N = 200
1
Drug A
N = 98
1
Drug B
N = 102
1
p-value2 q-value3
Age 47 (38,57) 46 (37,60) 48 (39,56) 0.72 0.87
    Missing 11 7 4

Marker Level (ng/mL) 0.92 (0.86) 1.02 (0.89) 0.82 (0.83) 0.085 0.51
    Missing 10 6 4

T Stage


0.87 0.87
    T1 53/200 28/98 25/102

    T2 54/200 25/98 29/102

    T3 43/200 22/98 21/102

    T4 50/200 23/98 27/102

Tumor Grade


0.87 0.87
    I 68/200 35/98 33/102

    II 68/200 32/98 36/102

    III 64/200 31/98 33/102

Tumor Response 61/193 28/95 33/98 0.53 0.87
    Missing 7 3 4

Patient Died 112/200 52/98 60/102 0.41 0.87
Months to Death/Censor 22.4 (15.9, 24.0) 23.5 (17.4, 24.0) 21.2 (14.5, 24.0) 0.14 0.51
1 Median (Q1,Q3); Mean (SD); n/N; Median (Q1, Q3)
2 Wilcoxon rank sum test; Pearson’s Chi-squared test
3 False discovery rate correction for multiple testing

gtsummary has themes that can be adjusted as shown below. This code sets the default gtsummary package theme to be “jama” theme” and will be used for all gtsummary objects unless otherwise specified.

# changing aesthetics using themes
gtsummary::theme_gtsummary_journal("jama", set_theme = T)
#> Setting theme "JAMA"
gtsummary::tbl_summary(mtcars) 
Characteristic N = 32
mpg, Median (IQR) 19.2 (15.4 – 22.8)
cyl, n (%)
    4 11 (34)
    6 7 (22)
    8 14 (44)
disp, Median (IQR) 196 (121 – 334)
hp, Median (IQR) 123 (96 – 180)
drat, Median (IQR) 3.70 (3.08 – 3.92)
wt, Median (IQR) 3.33 (2.54 – 3.65)
qsec, Median (IQR) 17.71 (16.89 – 18.90)
vs, n (%) 14 (44)
am, n (%) 13 (41)
gear, n (%)
    3 15 (47)
    4 12 (38)
    5 5 (16)
carb, n (%)
    1 7 (22)
    2 10 (31)
    3 3 (9.4)
    4 10 (31)
    6 1 (3.1)
    8 1 (3.1)

Themes can apply to more than visual aspects and can set how certain variables are displayed

# changing how continuous variables are presented using themes
gtsummary::theme_gtsummary_mean_sd(set_theme = TRUE)
gtsummary::tbl_summary(mtcars) 
Characteristic N = 32
mpg, Mean (SD) 20.1 (6.0)
cyl, n (%)
    4 11 (34%)
    6 7 (22%)
    8 14 (44%)
disp, Mean (SD) 231 (124)
hp, Mean (SD) 147 (69)
drat, Mean (SD) 3.60 (0.53)
wt, Mean (SD) 3.22 (0.98)
qsec, Mean (SD) 17.85 (1.79)
vs, n (%) 14 (44%)
am, n (%) 13 (41%)
gear, n (%)
    3 15 (47%)
    4 12 (38%)
    5 5 (16%)
carb, n (%)
    1 7 (22%)
    2 10 (31%)
    3 3 (9.4%)
    4 10 (31%)
    6 1 (3.1%)
    8 1 (3.1%)

Note this theme shows median, mean and IQR

gtsummary::theme_gtsummary_eda(set_theme = TRUE) #note this theme shows median, mean and IQR
#> Setting theme "Exploratory Data Analysis"
gtsummary::tbl_summary(mtcars) 
Characteristic N = 32
mpg
    Median (Q1, Q3) 19.2 (15.4, 22.8)
    Mean (SD) 20.1 (6.0)
    Min, Max 10.4, 33.9
cyl, n (%)
    4 11 (34.4%)
    6 7 (21.9%)
    8 14 (43.8%)
disp
    Median (Q1, Q3) 196 (121, 334)
    Mean (SD) 231 (124)
    Min, Max 71, 472
hp
    Median (Q1, Q3) 123 (96, 180)
    Mean (SD) 147 (69)
    Min, Max 52, 335
drat
    Median (Q1, Q3) 3.70 (3.08, 3.92)
    Mean (SD) 3.60 (0.53)
    Min, Max 2.76, 4.93
wt
    Median (Q1, Q3) 3.33 (2.54, 3.65)
    Mean (SD) 3.22 (0.98)
    Min, Max 1.51, 5.42
qsec
    Median (Q1, Q3) 17.71 (16.89, 18.90)
    Mean (SD) 17.85 (1.79)
    Min, Max 14.50, 22.90
vs, n (%) 14 (43.8%)
am, n (%) 13 (40.6%)
gear, n (%)
    3 15 (46.9%)
    4 12 (37.5%)
    5 5 (15.6%)
carb, n (%)
    1 7 (21.9%)
    2 10 (31.3%)
    3 3 (9.38%)
    4 10 (31.3%)
    6 1 (3.13%)
    8 1 (3.13%)

Explore ?theme_gtsummary for more ways to set themes for GT Summary Tables.

Other functions that may be of interest:

tbl_uvregression() - For running a series of univariate analyses

gtsummary::tbl_uvregression(
  trial,
  method = glm,
  y = response,
  method.args = list(family = binomial),
  exponentiate = TRUE,
  include = c("age", "grade", "stage")
)
Characteristic N OR (95% CI) p-value
Age 183 1.02 (1.00 to 1.04) 0.10
Grade 193

    I

    II
0.95 (0.45 to 2.00) 0.88
    III
1.10 (0.52 to 2.29) 0.81
T Stage 193

    T1

    T2
0.63 (0.27 to 1.46) 0.29
    T3
1.13 (0.48 to 2.68) 0.77
    T4
0.83 (0.36 to 1.92) 0.67
Abbreviations: CI = Confidence Interval, OR = Odds Ratio

tbl_regression() - For summarizing a single regression model. Also supports survival models, and some Bayesian models from the rstanarm and brms packages

stats::glm(response ~ trt, data= trial) |> 
  gtsummary::tbl_regression(exponentiate = TRUE)
Characteristic exp(Beta) (95% CI) p-value
Chemotherapy Treatment

    Drug A
    Drug B 1.04 (0.91 to 1.19) 0.53
Abbreviation: CI = Confidence Interval

tbl_stack() or tbl_merge - to combine table results

# stacking two tbl_regression objects
t1 <-
  stats::glm(response ~ trt, trial, family = binomial) |>
  gtsummary::tbl_regression(
    exponentiate = TRUE,
    label = list(trt ~ "Treatment (unadjusted)")
  )

t2 <-
  stats::glm(response ~ trt + grade + stage + marker, trial, family = binomial) |>
  gtsummary::tbl_regression(
    include = "trt",
    exponentiate = TRUE,
    label = list(trt ~ "Treatment (adjusted)")
  )

gtsummary::tbl_stack(list(t1, t2))
Characteristic OR (95% CI) p-value
Treatment (unadjusted)

    Drug A
    Drug B 1.21 (0.66 to 2.24) 0.53
Treatment (adjusted)

    Drug A
    Drug B 1.48 (0.78 to 2.86) 0.24
Abbreviations: CI = Confidence Interval, OR = Odds Ratio
t3 <-
  stats::glm(response ~ trt + grade + age, trial, family = binomial) |>
  gtsummary::tbl_regression(exponentiate = TRUE)
t4 <-
  survival::coxph(survival::Surv(ttdeath, death) ~ trt + grade + age, trial) |>
  gtsummary::tbl_regression(exponentiate = TRUE)

gtsummary::tbl_merge(
  tbls = list(t3, t4),
  tab_spanner = c("**Tumor Response**", "**Time to Death**")
)
Characteristic
Tumor Response
Time to Death
OR (95% CI) p-value HR (95% CI) p-value
Chemotherapy Treatment



    Drug A

    Drug B 1.13 (0.60 to 2.13) 0.70 1.30 (0.88 to 1.92) 0.18
Grade



    I

    II 0.85 (0.39 to 1.85) 0.68 1.21 (0.73 to 1.99) 0.46
    III 1.01 (0.47 to 2.15) 0.98 1.79 (1.12 to 2.86) 0.014
Age 1.02 (1.00 to 1.04) 0.10 1.01 (0.99 to 1.02) 0.35
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio, OR = Odds Ratio

Flextable

Flextable plays well with gtsummary with the function as_flex_table. This may be of interest as flextable advertises itself as one of the few tabling packages that plays well with HTML, PDF and Word outputs. Most packages handle html well but sometimes struggle with losing capability with word or pdf outputting. Note the autofit function should fix any width problems that may occur with tables running off the page.

ft <- flextable::flextable(airquality[ sample.int(10),])
ft <- flextable::add_header_row(ft,
  colwidths = c(4, 2),
  values = c("Air quality", "Time")
)
ft <- flextable::theme_vanilla(ft)
ft <- flextable::add_footer_lines(ft, "Daily air quality measurements in New York, May to September 1973.")
ft <- flextable::color(ft, part = "footer", color = "#666666")
ft <- flextable::set_caption(ft, caption = "New York Air Quality Measurements")
ft
New York Air Quality Measurements

Air quality

Time

Ozone

Solar.R

Wind

Temp

Month

Day

41

190

7.4

67

5

1

28

14.9

66

5

6

19

99

13.8

59

5

8

8

19

20.1

61

5

9

36

118

8.0

72

5

2

23

299

8.6

65

5

7

194

8.6

69

5

10

14.3

56

5

5

18

313

11.5

62

5

4

12

149

12.6

74

5

3

Daily air quality measurements in New York, May to September 1973.

Flextable also offers a variety of themes / settings that can be adjusted.

flextable::flextable(airquality[ sample.int(10),]) |> flextable::theme_box()

Ozone

Solar.R

Wind

Temp

Month

Day

194

8.6

69

5

10

41

190

7.4

67

5

1

18

313

11.5

62

5

4

8

19

20.1

61

5

9

36

118

8.0

72

5

2

14.3

56

5

5

23

299

8.6

65

5

7

19

99

13.8

59

5

8

12

149

12.6

74

5

3

28

14.9

66

5

6

Or changing default settings like below

flextable::set_flextable_defaults(
  font.size = 10, theme_fun = flextable::theme_vanilla,
  padding = 6,
  background.color = "#EFEFEF")
flextable::flextable(airquality[ sample.int(10),]) |> flextable::autofit()

Ozone

Solar.R

Wind

Temp

Month

Day

19

99

13.8

59

5

8

12

149

12.6

74

5

3

18

313

11.5

62

5

4

41

190

7.4

67

5

1

8

19

20.1

61

5

9

23

299

8.6

65

5

7

194

8.6

69

5

10

28

14.9

66

5

6

14.3

56

5

5

36

118

8.0

72

5

2

Kable/KableExtra

Kable can be viewed as the base package that can be built on or styled with KableExtra. Note if you load KableExtra, kable will be loaded in the background if it is not already. KableExtra also allows working with piping (%>% or |> ) for added simplicity when editing a table.

The first step, the kable call is pretty simple but is fairly limited in themes etc.

kableExtra::kable(mtcars, align = "lccrr")
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2

Adding a simple kable_styling() call makes it much better visually

kableExtra::kable(mtcars, align = "lccrr") |> kableExtra::kable_styling()
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2

Below are a handful of other options found within the “Kable universe”.

mtcars |>
  kableExtra::kbl(caption = "Recreating booktabs style table") |>
  kableExtra::kable_classic(full_width = F, html_font = "Cambria")
Recreating booktabs style table
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2
mtcars |>
  kableExtra::kbl() |>
  kableExtra::kable_material(c("striped", "hover"))
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2
mtcars |>
  kableExtra::kbl() |>
  kableExtra::kable_paper(bootstrap_options = "striped", full_width = F)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2

Please visit the following website for more examples on the kable package: https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html

Table1

Table1 uses quick and easy syntax but is not very friendly with testing/pvals. Note the label function is helpful here (changed the names / levels of wt to weight and am to automatic)

Hmisc::label(mtcars$wt) <- "weight"

mtcars$am <- 
  factor(mtcars$am, 
         levels=c(0,1),
         labels=c("Automatic", # Reference
                  "Manual"))

table1::table1(~ mpg + cyl + wt | am * vs, data=mtcars)
#> Warning in table1.formula(~mpg + cyl + wt | am * vs, data = mtcars): Terms to
#> the right of '|' in formula 'x' define table columns and are expected to be
#> factors with meaningful labels.
Automatic
Manual
Overall
0
(N=12)
1
(N=7)
0
(N=6)
1
(N=7)
0
(N=18)
1
(N=14)
mpg
Mean (SD) 15.1 (2.77) 20.7 (2.47) 19.8 (4.01) 28.4 (4.76) 16.6 (3.86) 24.6 (5.38)
Median [Min, Max] 15.2 [10.4, 19.2] 21.4 [17.8, 24.4] 20.4 [15.0, 26.0] 30.4 [21.4, 33.9] 15.7 [10.4, 26.0] 22.8 [17.8, 33.9]
cyl
Mean (SD) 8.00 (0) 5.14 (1.07) 6.33 (1.51) 4.00 (0) 7.44 (1.15) 4.57 (0.938)
Median [Min, Max] 8.00 [8.00, 8.00] 6.00 [4.00, 6.00] 6.00 [4.00, 8.00] 4.00 [4.00, 4.00] 8.00 [4.00, 8.00] 4.00 [4.00, 6.00]
weight
Mean (SD) 4.10 (0.768) 3.19 (0.348) 2.86 (0.487) 2.03 (0.440) 3.69 (0.904) 2.61 (0.715)
Median [Min, Max] 3.81 [3.44, 5.42] 3.22 [2.47, 3.46] 2.82 [2.14, 3.57] 1.94 [1.51, 2.78] 3.57 [2.14, 5.42] 2.62 [1.51, 3.46]

tableone

Here is the simplest approach to creating a summary table with the tableone package.

tableone::CreateTableOne(data = mtcars)
#>                   
#>                    Overall        
#>   n                    32         
#>   mpg (mean (SD))   20.09 (6.03)  
#>   cyl (mean (SD))    6.19 (1.79)  
#>   disp (mean (SD)) 230.72 (123.94)
#>   hp (mean (SD))   146.69 (68.56) 
#>   drat (mean (SD))   3.60 (0.53)  
#>   wt (mean (SD))     3.22 (0.98)  
#>   qsec (mean (SD))  17.85 (1.79)  
#>   vs (mean (SD))     0.44 (0.50)  
#>   am = Manual (%)      13 (40.6)  
#>   gear (mean (SD))   3.69 (0.74)  
#>   carb (mean (SD))   2.81 (1.62)

You can specify which variables in included and which are factor variables easily in the table call.

tableone::CreateTableOne(data = mtcars,
               vars = c("mpg", "cyl", "disp", "hp"),
               factorVars = c("cyl"))
#>                   
#>                    Overall        
#>   n                    32         
#>   mpg (mean (SD))   20.09 (6.03)  
#>   cyl (%)                         
#>      4                 11 (34.4)  
#>      6                  7 (21.9)  
#>      8                 14 (43.8)  
#>   disp (mean (SD)) 230.72 (123.94)
#>   hp (mean (SD))   146.69 (68.56)