knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.path = "man/figures/README-",
  out.width = "100%"
)

tidytableone

The goal of tidytableone is to enable a tidy approach to creating the "Table 1" of study characteristics common in biomedical research.

Installation

You can install the released version of tidytableone from CRAN with:

# install.packages("devtools")
devtools::install_github("emilelatour/tidytableone)

Example

Load the packages for the example

library(tidytableone)
library(tidyverse)
library(knitr)

Take a glimpse at the data that comes in the tidytableone package:

dplyr::glimpse(pbc_mayo)

Use the main function of this package to make a tidy table one

tab1 <- tidytableone::create_tidy_table_one(data = pbc_mayo, 
                                            strata = "trt", 
                                            .vars = c("time", "status", "trt", "age", "sex", "ascites", "hepato",
                                                      "spiders", "edema", "bili", "chol", "albumin", "copper", "alk_phos",
                                                      "ast", "trig", "platelet", "protime", "stage"))

Use the dplyr::glimpse command to see the tidy table one

dplyr::glimpse(tab1)

Some information is only available for categorical variables and some information for continuous variables.

tab1 %>% 
  dplyr::filter(var_type == "categorical") %>% 
  dplyr::select(strata, var, level:check_categorical_test, smd:var_type)
tab1 %>% 
  dplyr::filter(var_type == "continuous") %>% 
  dplyr::select(strata, var, n:shapiro_test, oneway_test:bartlett_test, smd:var_type)

Then with some simple data manipulation we can reshape to make a table one...

tab1 %>% 
  mutate(strata = forcats::fct_inorder(strata), 
         n_pct = scales::percent(n_level / n_strata), 
         mean = scales::number(mean, accuracy = 0.1), 
         value = dplyr::if_else(mean == "NA", n_pct, mean), 
         p_value = dplyr::coalesce(oneway_test, chisq_test), 
         p_value = scales::pvalue(p_value)) %>% 
  dplyr::distinct(strata, 
                  var, 
                  level, 
                  value, 
                  p_value) %>% 
  tidyr::spread(., 
                key = strata, 
                value = value) %>% 
  dplyr::select(-p_value, dplyr::everything(), p_value) %>% 
  knitr::kable()

This is rough, but you get the idea. The plan is to next create a function to make the table based on specifications.

Or possibly with some nesting...

tab1 %>% 
  tidyr::nest(con_res = c(n:shapiro_test, oneway_test:bartlett_test)) %>% 
  tidyr::nest(cat_res = c(n_level:check_categorical_test)) %>% 
  mutate(mean_sd = purrr::map_chr(.x = con_res, 
                                  .f = ~ paste0(round(.x$mean, 1), 
                                                " (", 
                                                round(.x$sd, 1), 
                                                ")"))) %>% 
  mutate(n_pct = purrr::map_chr(.x = cat_res, 
                                .f = ~ tryCatch(suppressWarnings(paste0(.x$n_level, 
                                                       " (", 
                                                       scales::percent(.x$n_level / .x$n_strata), 
                                                       ")")), 
                                                error = function(err) NA))) %>% 
  mutate(value = dplyr::if_else(var_type == "continuous", mean_sd, n_pct)) %>% 
  dplyr::select(-mean_sd, -n_pct, -class)


emilelatour/tidytableone documentation built on Jan. 6, 2025, 9:20 a.m.