table1: Generate an HTML table of descriptive statistics.

View source: R/table1.R

table1R Documentation

Generate an HTML table of descriptive statistics.


Produces a nicely formatted table of descriptive statistics for any number of numeric or categorical variables, optionally stratified by a factor.


table1(x, ...)

## Default S3 method:
  groupspan = NULL,
  rowlabelhead = "",
  transpose = FALSE,
  topclass = "Rtable1",
  footnote = NULL,
  caption = NULL,
  render = render.default,
  render.strat = render.strat.default,
  extra.col = NULL,
  extra.col.pos = NULL,

## S3 method for class 'formula'
  overall = "Overall",
  rowlabelhead = "",
  transpose = FALSE,
  droplevels = TRUE,
  topclass = "Rtable1",
  footnote = NULL,
  caption = NULL,
  render = render.default,
  render.strat = render.strat.default,
  extra.col = NULL,
  extra.col.pos = NULL,



An object, typically a formula or list of data.frames (see Details).


Further arguments, passed to render.


A list containing labels for variables, strata and groups (see Details).


A vector of integers specifying the number of strata to group together.


A heading for the first column of the table, which contains the row labels.


Logical. Should the table be transposed (i.e. strata as rows and variables as columns)?


A class attribute for the outermost (i.e. <table>) tag.


A character string to be added as a footnote to the table. Can also be a vector which results in multiple lines of footnotes. The default NULL causes the footnote to be omitted.


A character string to be added as a caption to the table. The default NULL causes the caption to be omitted.


A function to render the table cells (see Details).


A function to render the stratum labels. Accepts 3 arguments: the stratum label, the stratum size (number of observations), and a flag indicating whether we are in transpose mode or not. See render.strat.default for an example.


An optional names list of functions that produce extra columns in the table (see Details).


An optional integer vector given the positions of extra columns (see Details).


For the formula interface, a data.frame from which the variables in x should be taken.


A label for the "Overall" column. Specify NULL or FALSE to omit the column altogether. By default, the "Overall" column appears at the right end of the table; to place it on the left instead use a named character with the name "left", e.g. c(left="Overall").


Should empty factor levels be dropped?


There are two interfaces, the default, which typically takes a list of data.frames for x, and the formula interface. The formula interface is less flexible, but simpler to use and designed to handle the most common use cases. It is important to use factors appropriately for categorical variables (i.e. have the levels labeled properly and in the desired order). The contents of the table can be customized by providing user-defined ‘renderer’ functions. Customization of the table appearance is deliberately not attempted, as this is best accomplished with CSS. To facilitate this, some tags (such as row labels) are given specific classes for easy CSS selection.

For the formula version, the formula is expected to be a one-sided formula, optionally with a vertical bar separating the variables that are to appear as data in the table (as rows) from those used for stratification (i.e. columns). There can be at most 2 variables for stratification (and only one if transpose = TRUE is specified), and if 2 are specified, the second is nested within the first. Stratification variables may not contain missing values. The formula may contain a dot (".") to refer to "all variables in data other than those that appear elsewhere in the formula". It is legitimate to use functions inside the formula to create new variables.

For the default version, is is expected that x is a named list of data.frames, one for each stratum, with names corresponding to strata labels.

Extra columns can be added to the table using the extra.col argument. This is an optional named list of functions, with the names corresponding to the column headings. Each function will be called once for each variable included in the table. Each function should expect 2 arguments, the first being a list, the second the name of the variable. The contents of the list passed in as the first argument will be the data associated with each stratum in the table; i.e., one element for each normal column (not extra column). It is then up the function to compute the value to appear in the extra column and return it as a string. By default, extra columns will be placed to the far right, after the normal columns, in the order they are specified in. This can be overridden, however, using the extra.col.pos vector of integer positions. For example, to place the first extra column in position 1 (far left), and the second extra column in position 3, use extra.col.pos = c(1, 3); any extra columns that are not assigned positions will be placed to the far right. A typical use case for extra columns would be a column of p-values for differences between strata. Note that this feature is not available when the option transpose = TRUE is specified.


An object of class "table1".

Methods (by class)

  • table1(default): The default interface, where x is a data.frame.

  • table1(formula): The formula interface.


dat <- expand.grid(id=1:10, sex=c("Male", "Female"), treat=c("Treated", "Placebo"))
dat$age <- runif(nrow(dat), 10, 50)
dat$age[3] <- NA  # Add a missing value
dat$wt <- exp(rnorm(nrow(dat), log(70), 0.2))

label(dat$sex) <- "Sex"
label(dat$age) <- "Age"
label(dat$treat) <- "Treatment Group"
label(dat$wt) <- "Weight"

units(dat$age) <- "years"
units(dat$wt) <- "kg"

# One level of stratification
table1(~ sex + age + wt | treat, data=dat)

# Two levels of stratification (nesting)
table1(~ age + wt | treat*sex, data=dat)

# Switch the order or nesting
table1(~ age + wt | sex*treat, data=dat)

# No stratification
table1(~ treat + sex + age + wt, data=dat)

# Something more complicated

dat$dose <- ifelse(dat$treat=="Placebo", "Placebo",
                   sample(c("5 mg", "10 mg"), nrow(dat), replace=TRUE))
dat$dose <- factor(dat$dose, levels=c("Placebo", "5 mg", "10 mg"))

strata <- c(split(dat, dat$dose),
            list("All treated"=subset(dat, treat=="Treated")),

labels <- list(
    groups=list("", "Treated", ""))

my.render.cont <- function(x) {
        sprintf("%0.2f (%0.1f)", MEAN, SD))

table1(strata, labels, groupspan=c(1, 3, 1), render.continuous=my.render.cont)

# Transposed table
table1(~ age + wt | treat, data=dat, transpose=TRUE)

table1 documentation built on Jan. 6, 2023, 5:07 p.m.