Skip to contents

tbl_summary() calculates descriptive statistics for continuous, categorical and dichotomous variables and presents them in a publication-ready table, the kind that opens a clinical paper as Table 1. The interface is that of gtsummary::tbl_summary(), so the tbl_summary() tutorial and the FAQ and gallery cover the same ground as gtsummary's.

Usage

tbl_summary(
  data,
  by = NULL,
  label = NULL,
  statistic = list(all_continuous() ~ "{median} ({p25}, {p75})", all_categorical() ~
    "{n} ({p}%)"),
  digits = NULL,
  type = NULL,
  value = NULL,
  missing = c("ifany", "no", "always"),
  missing_text = "Unknown",
  missing_stat = "{N_miss}",
  sort = all_categorical(FALSE) ~ "alphanumeric",
  percent = c("column", "row", "cell"),
  include = everything()
)

Arguments

data

(data.frame)
A data frame.

by

(selector)
A single column of data. The statistics are stratified by its levels, one column per level. Rows with a missing by value are dropped with a message. Default is NULL.

label

(formula-list)
Variable labels, e.g. list(age = "Age, years"). The default for each variable is its label attribute, attr(., "label"), or the column name when there is none.

statistic

(formula-list)
The statistics shown for each variable, as strings with statistic names in curly braces. The default is list(all_continuous() ~ "{median} ({p25}, {p75})", all_categorical() ~ "{n} ({p}%)"). See the section below.

digits

(formula-list)
How the statistics are rounded: integers or formatting functions. When not specified, the defaults come from assign_summary_digits(). See the section below.

type

(formula-list)
The summary type, one of c("continuous", "continuous2", "categorical", "dichotomous"). When not specified, the default comes from assign_summary_type(). See the section below.

value

(formula-list)
The level of a variable to show on a single row, e.g. list(grade = "III"). Selectors such as all_dichotomous() cannot be used here. Default is NULL. See the section below.

missing, missing_text, missing_stat

How missing values are presented:

  • missing: one of c("ifany", "no", "always"), or a formula-list giving one of them per variable.

  • missing_text: the label of the missing-value row. Default is "Unknown".

  • missing_stat: the statistic shown on the missing-value row. Default is "{N_miss}"; N_obs, N_nonmiss, p_miss and p_nonmiss are also available.

sort

(formula-list)
The order of the levels of categorical variables: "alphanumeric" (the order of the factor levels) or "frequency" (most frequent first). Default is all_categorical(FALSE) ~ "alphanumeric".

percent

(string)
The denominator of the percentages of categorical variables: "column" (the default), "row" or "cell".

include

(selector)
Variables to include in the table. Default is everything(); the by variable is never summarized.

Value

A table of class c("tbl_summary", "ltsummary").

statistic argument

The statistic argument specifies the statistics presented in the table. statistic = list(age ~ "{mean} ({sd})") reports the mean and standard deviation of age; statistic = list(all_continuous() ~ "{mean} ({sd})") reports them for every continuous variable.

A name between curly braces is a statistic, and the formatted value of that statistic replaces it in the table.

For categorical variables the available statistics are {n} (frequency), {N} (denominator) and {p} (percentage).

For continuous variables the built-in statistics are {median}, {mean}, {sd}, {var}, {min}, {max} and {sum}, plus {p##} for any percentile, where ## is an integer from 0 to 100; for example {p25} is quantile(x, probs = 0.25, type = 2). Beyond these, the name of any function of one argument may be used, for example "{IQR}" or "{my_trimmed_mean}". The function is called on the non-missing values.

When the summary type is "continuous2", pass a vector of statistics. Each element of the vector becomes a row of the table.

For both categorical and continuous variables, the number and proportion of missing and non-missing observations can be displayed:

  • {N_obs} total number of observations

  • {N_miss} number of missing observations

  • {N_nonmiss} number of non-missing observations

  • {p_miss} percentage of observations missing

  • {p_nonmiss} percentage of observations not missing

digits argument

The digits argument specifies the number of decimal places, or the formatting function, for each statistic.

The value for a variable can be a single integer, a vector of integers, a function, or a list of functions. A single integer or function is recycled over the statistics in the order they appear. For the statistic "{mean} ({sd})", the values 1, c(1, 1), label_style_number(digits = 1) and list(label_style_number(digits = 1), label_style_number(digits = 1)) are equivalent.

A named list changes the formatting of single statistics and leaves the defaults of the others in place, e.g. list(sd = label_style_number(digits = 1)).

Integers passed for percentages (p, p_miss, p_nonmiss) are applied after scaling to 0-100, so digits = list(grade ~ c(0, 1)) shows whole counts with percentages to one decimal place, such as "83 (41.5%)".

type and value arguments

There are four summary types. Use the type argument to change the default.

  • "continuous" summaries are shown on a single row. Most numeric variables default to this type.

  • "continuous2" summaries are shown on two or more rows, one per statistic.

  • "categorical" summaries are multi-line, one row per level. Character variables, factors and numeric variables with fewer than 10 distinct values default to this type. To summarize such a numeric variable as continuous, use type = list(varname ~ "continuous").

  • "dichotomous" variables are categorical variables shown on a single row rather than one row per level. Variables coded TRUE/FALSE, 0/1 or yes/no are assumed to be dichotomous, and the TRUE, 1 and yes rows are shown. For any other variable the value to show must be given in the value argument, e.g. value = list(varname ~ "level to show").

Examples

# Example 1 ----------------------------------
# the default table: labels from the data, variable types detected
trial |>
  tbl_summary(include = c(age, grade, response))
# Example 2 ---------------------------------- # stratified by treatment, with custom statistics, digits and a label trial |> tbl_summary( by = trt, include = c(age, grade, response), label = list(age = "Patient Age"), statistic = list(all_continuous() ~ "{mean} ({sd})"), digits = list(age = c(0, 1)) )
# Example 3 ---------------------------------- # continuous variables on several lines, without the missing row trial |> tbl_summary( include = c(age, marker), type = all_continuous() ~ "continuous2", statistic = all_continuous() ~ c("{median} ({p25}, {p75})", "{min}, {max}"), missing = "no" )
# Example 4 ---------------------------------- # row percentages, levels sorted by frequency, and a dichotomous level trial |> tbl_summary( by = trt, include = c(stage, grade), percent = "row", sort = stage ~ "frequency", value = grade ~ "III", label = grade ~ "Grade III" )