The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Demographic Table

Tingting Zhan

Introduction

This vignette of package DemographicTable (CRAN, Github) presents an idiot-proof interface to create a summary table of simple statistics, often known as a demographic table.

Package DemographicTable Imports packages

Prerequisite

Packages DemographicTable requires R version 4.5.0 (released 2025-04-11) or higher (macOS, Windows). An Integrated Development Environment (IDE), e.g., RStudio or Positron, is not required, but highly recommended. This vignette is created under R version 4.5.1 (2025-06-13) using packages knitr (Xie 2025, v1.50), quarto (Allaire and Dervieux 2025, v1.5.0 with Quarto v1.7.33) and rmarkdown (Allaire et al. 2024, v2.29).

Environment on author’s computer
Sys.info()[c('sysname', 'release', 'machine')]
#  sysname  release  machine 
# "Darwin" "24.6.0"  "arm64"
R.version
#                _                           
# platform       aarch64-apple-darwin20      
# arch           aarch64                     
# os             darwin20                    
# system         aarch64, darwin20           
# status                                     
# major          4                           
# minor          5.1                         
# year           2025                        
# month          06                          
# day            13                          
# svn rev        88306                       
# language       R                           
# version.string R version 4.5.1 (2025-06-13)
# nickname       Great Square Root

Experimental (and maybe unstable) features are released extremely frequently to Github. Stable releases to CRAN are typically updated every 2 to 3 months.

remotes::install_github('tingtingzhan/DemographicTable')
utils::install.packages('DemographicTable')

Getting Started

Examples in this vignette require that the search path has

library(DemographicTable)
library(flextable)

Users may remove the last pipe |> as_flextable() from all examples. This is required in the vignette to make quarto rendering work.

Demographic Table

Data example penguins from package datasets

Summary of all subjects

datasets::penguins |>
  DemographicTable(include = c('species', 'island', 'bill_len')) |> 
  as_flextable()

datasets::penguins

n=344

bill_len.
mean±sd
median; IQR
range

n*=342
43.9±5.5
44.5; 9.3
32.1~59.6

island: n (%).
Biscoe
Dream
Torgersen


168 (48.8%)
124 (36.0%)
52 (15.1%)

species: n (%).
Adelie
Chinstrap
Gentoo


152 (44.2%)
68 (19.8%)
124 (36.0%)

n=344

datasets::penguins

Summary by one group

Color of each individual group is determined by scales::pal_hue(), which is the default color pallete used in package ggplot2.

datasets::penguins |>
  DemographicTable(groups = 'sex', include = c('species', 'bill_dep')) |> 
  as_flextable()

datasets::penguins

n=344

sex
n=11 (3.2%) missing

female
n=165 (48.0%)

male
n=168 (48.8%)

Signif

bill_dep.
mean±sd
median; IQR
range

n*=342
17.2±2.0
17.3; 3.1
13.1~21.5


16.4±1.8
17.0; 3.3
13.1~20.7


17.9±1.9
18.4; 3.2
14.1~21.5

0.000★
Two-Sample t

species: n (%).
Adelie
Chinstrap
Gentoo


152 (44.2%)
68 (19.8%)
124 (36.0%)


73 (44.2%)
34 (20.6%)
58 (35.2%)


73 (43.5%)
34 (20.2%)
61 (36.3%)

0.979
Fisher's Exact

n=344

sex
n=11 (3.2%) missing

datasets::penguins

User may choose to hide the p-values with option compare = FALSE.

datasets::penguins |>
  DemographicTable(groups = 'sex', include = c('species', 'bill_dep'), compare = FALSE) |>
  as_flextable()

datasets::penguins

n=344

sex
n=11 (3.2%) missing

female
n=165 (48.0%)

male
n=168 (48.8%)

bill_dep.
mean±sd
median; IQR
range

n*=342
17.2±2.0
17.3; 3.1
13.1~21.5


16.4±1.8
17.0; 3.3
13.1~20.7


17.9±1.9
18.4; 3.2
14.1~21.5

species: n (%).
Adelie
Chinstrap
Gentoo


152 (44.2%)
68 (19.8%)
124 (36.0%)


73 (44.2%)
34 (20.6%)
58 (35.2%)


73 (43.5%)
34 (20.2%)
61 (36.3%)

n=344

sex
n=11 (3.2%) missing

datasets::penguins

Summary by multiple groups

datasets::penguins |>
  DemographicTable(groups = c('sex', 'island'), include = c('species', 'bill_dep'), compare = FALSE) |> 
  as_flextable()

datasets::penguins

n=344

sex
n=11 (3.2%) missing

island

female
n=165 (48.0%)

male
n=168 (48.8%)

Biscoe
n=168 (48.8%)

Dream
n=124 (36.0%)

Torgersen
n=52 (15.1%)

bill_dep.
mean±sd
median; IQR
range

n*=342
17.2±2.0
17.3; 3.1
13.1~21.5


16.4±1.8
17.0; 3.3
13.1~20.7


17.9±1.9
18.4; 3.2
14.1~21.5

n*=167
15.9±1.8
15.5; 2.5
13.1~21.1


18.3±1.1
.
15.5~21.2

n*=51
18.4±1.3
.
15.9~21.5

species: n (%).
Adelie
Chinstrap
Gentoo


152 (44.2%)
68 (19.8%)
124 (36.0%)


73 (44.2%)
34 (20.6%)
58 (35.2%)


73 (43.5%)
34 (20.2%)
61 (36.3%)


44 (26.2%)
-
124 (73.8%)


56 (45.2%)
68 (54.8%)
-


52 (100.0%)
-
-

n=344

sex
n=11 (3.2%) missing

island

datasets::penguins

Combine multiple DemographicTables

tb1 = datasets::penguins |>
  subset(subset = (sex == 'male')) |>
  DemographicTable(groups = 'island', include = c('species', 'bill_dep'), data.name = 'Male Penguins', compare = FALSE)
tb2 = datasets::penguins |>
  subset(subset = (sex == 'female')) |>
  DemographicTable(groups = 'island', include = c('species', 'bill_dep'), data.name = 'Female Penguins', compare = FALSE)
c(tb1, tb2) |> as_flextable()

Male Penguins

Female Penguins

n=168

island

n=165

island

Biscoe
n=83 (49.4%)

Dream
n=62 (36.9%)

Torgersen
n=23 (13.7%)

Biscoe
n=80 (48.5%)

Dream
n=61 (37.0%)

Torgersen
n=24 (14.5%)

bill_dep.
mean±sd
median; IQR
range


17.9±1.9
18.4; 3.2
14.1~21.5


16.6±1.7
16.0; 2.3
14.1~21.1


19.1±0.9
.
17.0~21.2


19.4±1.1
.
17.6~21.5


16.4±1.8
17.0; 3.3
13.1~20.7


15.2±1.7
14.5; 2.3
13.1~20.7


17.6±0.8
.
15.5~19.4


17.6±0.9
.
15.9~19.3

species: n (%).
Adelie
Chinstrap
Gentoo


73 (43.5%)
34 (20.2%)
61 (36.3%)


22 (26.5%)
-
61 (73.5%)


28 (45.2%)
34 (54.8%)
-


23 (100.0%)
-
-


73 (44.2%)
34 (20.6%)
58 (35.2%)


22 (27.5%)
-
58 (72.5%)


27 (44.3%)
34 (55.7%)
-


24 (100.0%)
-
-

n=168

island

n=165

island

Male Penguins

Female Penguins

Exception Handling

Missing value in groups

datasets::penguins |>
  DemographicTable(groups = c('sex'), include = c('body_mass', 'species')) |>
  as_flextable()

datasets::penguins

n=344

sex
n=11 (3.2%) missing

female
n=165 (48.0%)

male
n=168 (48.8%)

Signif

body_mass.
mean±sd
median; IQR
range

n*=342
4201.8±802.0
4050.0; 1200.0
2700.0~6300.0


3862.3±666.2
3650.0; 1200.0
2700.0~5200.0


4545.7±787.6
4300.0; 1412.5
3250.0~6300.0

0.000★
Two-Sample t

species: n (%).
Adelie
Chinstrap
Gentoo


152 (44.2%)
68 (19.8%)
124 (36.0%)


73 (44.2%)
34 (20.6%)
58 (35.2%)


73 (43.5%)
34 (20.2%)
61 (36.3%)

0.979
Fisher's Exact

n=344

sex
n=11 (3.2%) missing

datasets::penguins

Use of logical values

Using logical values is discouraged, as this practice is proved confusing to scientists without a strong data background.

mtc = datasets::mtcars |>
  within.data.frame(expr = {
    vs_straight = as.logical(vs)
    am_manual = as.logical(am)
  })

A warning message will be printed if logical variables are used in groups and/or include.

tryCatch(DemographicTable(mtc, groups = 'am_manual', include = c('drat', 'vs_straight')), warning = identity)
# <simpleWarning in DemographicTable(mtc, groups = "am_manual", include = c("drat",     "vs_straight")): 
# Some scientists do not understand logical value (e.g., arm_intervention being TRUE/FALSE)
# Consider using 2-level factor (e.g., arm being intervention/control)>

Instead of using logical variables

mtc |>
  DemographicTable(groups = 'am_manual', include = c('drat', 'vs_straight')) |>
  as_flextable()

mtc

n=32

am_manual

FALSE
n=19 (59.4%)

TRUE
n=13 (40.6%)

Signif

drat.
mean±sd
median; IQR
range


3.6±0.5
.
2.8~4.9


3.3±0.4
3.1; 0.6
2.8~3.9


4.0±0.4
.
3.5~4.9

0.000★
Wilcoxon-
Mann-Whitney

vs_straight: n (%)

14 (43.8%)

7 (36.8%)

7 (53.8%)

0.556
χ² (chi-square)

n=32

am_manual

mtc

We recommend using 2-level factors.

mtcars |>
  within.data.frame(expr = {
    vs = ifelse(vs, yes = 'Straight', no = 'V-shaped')
    am = ifelse(am, yes = 'manual', no = 'automatic')
  }) |> 
  DemographicTable(groups = 'am', include = c('drat', 'vs'), data.name = 'mtcars') |>
  as_flextable()

mtcars

n=32

am

automatic
n=19 (59.4%)

manual
n=13 (40.6%)

Signif

drat.
mean±sd
median; IQR
range


3.6±0.5
.
2.8~4.9


3.3±0.4
3.1; 0.6
2.8~3.9


4.0±0.4
.
3.5~4.9

0.000★
Wilcoxon-
Mann-Whitney

vs: n (%).
Straight
V-shaped


14 (43.8%)
18 (56.2%)


7 (36.8%)
12 (63.2%)


7 (53.8%)
6 (46.2%)

0.473
Fisher's Exact

n=32

am

mtcars

Allaire, JJ, and Christophe Dervieux. 2025. quarto: R Interface to ’Quarto’ Markdown Publishing System. https://doi.org/10.32614/CRAN.package.quarto.
Allaire, JJ, Yihui Xie, Christophe Dervieux, Jonathan McPherson, Javier Luraschi, Kevin Ushey, Aron Atkins, et al. 2024. rmarkdown: Dynamic Documents for r. https://github.com/rstudio/rmarkdown.
Csárdi, Gábor. 2025. cli: Helpers for Developing Command Line Interfaces. https://doi.org/10.32614/CRAN.package.cli.
Gohel, David, Stefan Moog, and Mark Heckmann. 2025. officer: Manipulation of Microsoft Word and PowerPoint Documents. https://doi.org/10.32614/CRAN.package.officer.
Gohel, David, and Panagiotis Skintzos. 2025. flextable: Functions for Tabular Reporting. https://doi.org/10.32614/CRAN.package.flextable.
Wickham, Hadley, Thomas Lin Pedersen, and Dana Seidel. 2025. scales: Scale Functions for Visualization. https://doi.org/10.32614/CRAN.package.scales.
Xie, Yihui. 2025. knitr: A General-Purpose Package for Dynamic Report Generation in R. https://yihui.org/knitr/.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.