Introduction

ARD (Analysis Results Data) objects are data frames that contain statistical summaries. Because they are data frames, any value in the ARD can be updated using standard dplyr or base R functions.

Working with List Columns

ARD objects contain list columns such as stat, fmt_fun, stat_label, and others. List columns are columns where each cell can hold any R object—a number, a function, a vector, or even another data frame. If you’re unfamiliar with list columns, they may look unusual when printed:

ard <- ard_summary(ADSL, variables = AGE)
ard
#> # An ARD data frame: 8 × 8
#>   variable context stat_name stat_label   stat fmt_fun warning error 
#> * <chr>    <chr>   <chr>     <chr>      <list>  <list> <list>  <list>
#> 1 AGE      summary N         N          254          0 <NULL>  <NULL>
#> 2 AGE      summary mean      Mean        75.1        1 <NULL>  <NULL>
#> 3 AGE      summary sd        SD           8.25       1 <NULL>  <NULL>
#> 4 AGE      summary median    Median      77          1 <NULL>  <NULL>
#> 5 AGE      summary p25       Q1          70          1 <NULL>  <NULL>
#> 6 AGE      summary p75       Q3          81          1 <NULL>  <NULL>
#> 7 AGE      summary min       Min         51          1 <NULL>  <NULL>
#> 8 AGE      summary max       Max         89          1 <NULL>  <NULL>

While list columns can be updated just like any other column in a data frame, the syntax can be less intuitive. For example, to update the fmt_fun column for specific statistics, you might write:

ard |>
  mutate(
    fmt_fun = ifelse(stat_name %in% c("mean", "sd"), list(2L), fmt_fun)
  )
#> # An ARD data frame: 8 × 8
#>   variable context stat_name stat_label   stat fmt_fun warning error 
#>   <chr>    <chr>   <chr>     <chr>      <list>  <list> <list>  <list>
#> 1 AGE      summary N         N          254          0 <NULL>  <NULL>
#> 2 AGE      summary mean      Mean        75.1        2 <NULL>  <NULL>
#> 3 AGE      summary sd        SD           8.25       2 <NULL>  <NULL>
#> 4 AGE      summary median    Median      77          1 <NULL>  <NULL>
#> 5 AGE      summary p25       Q1          70          1 <NULL>  <NULL>
#> 6 AGE      summary p75       Q3          81          1 <NULL>  <NULL>
#> 7 AGE      summary min       Min         51          1 <NULL>  <NULL>
#> 8 AGE      summary max       Max         89          1 <NULL>  <NULL>

This requires wrapping values in list() and can become cumbersome for more complex updates.

Helper Functions

To simplify working with these list columns, {cards} provides helper functions:

These functions handle the list column mechanics for you, making it easier to customize your ARD objects.

Basic Usage

Updating Formatting Functions

By default, statistics may use simple formatting. You can update the formatting function for specific statistics:

# Create a basic ARD
ard <- ard_summary(ADSL, variables = AGE)

# Update formatting for mean and sd to show more decimal places
ard_updated <- ard |>
  update_ard_fmt_fun(
    stat_names = c("mean", "sd"),
    fmt_fun = 2L # 2 decimal places
  ) |>
  apply_fmt_fun()

# View results
ard_updated
#> # An ARD data frame: 8 × 9
#>   variable context stat_name stat_label   stat stat_fmt fmt_fun warning error 
#>   <chr>    <chr>   <chr>     <chr>      <list> <list>   <list>  <list>  <list>
#> 1 AGE      summary N         N          254    254      0       <NULL>  <NULL>
#> 2 AGE      summary mean      Mean        75.1  75.09    <fn>    <NULL>  <NULL>
#> 3 AGE      summary sd        SD           8.25 8.25     <fn>    <NULL>  <NULL>
#> 4 AGE      summary median    Median      77    77.0     1       <NULL>  <NULL>
#> 5 AGE      summary p25       Q1          70    70.0     1       <NULL>  <NULL>
#> 6 AGE      summary p75       Q3          81    81.0     1       <NULL>  <NULL>
#> 7 AGE      summary min       Min         51    51.0     1       <NULL>  <NULL>
#> 8 AGE      summary max       Max         89    89.0     1       <NULL>  <NULL>

Updating Statistic Labels

Combine formatting updates with custom labels:

ard_summary(ADSL, variables = AGE) |>
  update_ard_fmt_fun(stat_names = c("mean", "sd"), fmt_fun = 1L) |>
  update_ard_stat_label(
    stat_names = c("mean", "sd"),
    stat_label = "Mean (SD)"
  ) |>
  apply_fmt_fun()
#> # An ARD data frame: 8 × 9
#>   variable context stat_name stat_label   stat stat_fmt fmt_fun warning error 
#>   <chr>    <chr>   <chr>     <chr>      <list> <list>   <list>  <list>  <list>
#> 1 AGE      summary N         N          254    254      0       <NULL>  <NULL>
#> 2 AGE      summary mean      Mean (SD)   75.1  75.1     <fn>    <NULL>  <NULL>
#> 3 AGE      summary sd        Mean (SD)    8.25 8.2      <fn>    <NULL>  <NULL>
#> 4 AGE      summary median    Median      77    77.0     1       <NULL>  <NULL>
#> 5 AGE      summary p25       Q1          70    70.0     1       <NULL>  <NULL>
#> 6 AGE      summary p75       Q3          81    81.0     1       <NULL>  <NULL>
#> 7 AGE      summary min       Min         51    51.0     1       <NULL>  <NULL>
#> 8 AGE      summary max       Max         89    89.0     1       <NULL>  <NULL>

Selective Updates

Filtering by Variable

Update formatting for specific variables only:

ard_summary(ADSL, variables = c(AGE, BMIBL)) |>
  update_ard_fmt_fun(
    variables = AGE, # Only update AGE
    stat_names = "mean",
    fmt_fun = 3L
  ) |>
  apply_fmt_fun()
#> # An ARD data frame: 16 × 9
#>    variable context stat_name stat_label   stat stat_fmt fmt_fun warning error 
#>    <chr>    <chr>   <chr>     <chr>      <list> <list>   <list>  <list>  <list>
#>  1 AGE      summary N         N          254    254      0       <NULL>  <NULL>
#>  2 AGE      summary mean      Mean        75.1  75.087   <fn>    <NULL>  <NULL>
#>  3 AGE      summary sd        SD           8.25 8.2      1       <NULL>  <NULL>
#>  4 AGE      summary median    Median      77    77.0     1       <NULL>  <NULL>
#>  5 AGE      summary p25       Q1          70    70.0     1       <NULL>  <NULL>
#>  6 AGE      summary p75       Q3          81    81.0     1       <NULL>  <NULL>
#>  7 AGE      summary min       Min         51    51.0     1       <NULL>  <NULL>
#>  8 AGE      summary max       Max         89    89.0     1       <NULL>  <NULL>
#>  9 BMIBL    summary N         N          253    253      0       <NULL>  <NULL>
#> 10 BMIBL    summary mean      Mean        24.7  24.7     1       <NULL>  <NULL>
#> 11 BMIBL    summary sd        SD           4.09 4.1      1       <NULL>  <NULL>
#> 12 BMIBL    summary median    Median      24.2  24.2     1       <NULL>  <NULL>
#> 13 BMIBL    summary p25       Q1          21.9  21.9     1       <NULL>  <NULL>
#> 14 BMIBL    summary p75       Q3          27.3  27.3     1       <NULL>  <NULL>
#> 15 BMIBL    summary min       Min         13.7  13.7     1       <NULL>  <NULL>
#> 16 BMIBL    summary max       Max         40.1  40.1     1       <NULL>  <NULL>

Filtering by Group

When working with stratified analyses, use the filter argument to target specific groups:

# Update formatting only for the Placebo arm
ard_summary(
  ADSL,
  by = ARM,
  variables = AGE,
  statistic = ~ continuous_summary_fns(c("N", "mean"))
) |>
  update_ard_fmt_fun(
    stat_names = "mean",
    fmt_fun = 3L,
    filter = group1_level == "Placebo"
  ) |>
  apply_fmt_fun()
#> # An ARD data frame: 6 × 11
#>   group1 group1_level       variable context stat_name stat_label  stat stat_fmt
#>   <chr>  <list>             <chr>    <chr>   <chr>     <chr>      <lis> <list>  
#> 1 ARM    Placebo            AGE      summary N         N           86   86      
#> 2 ARM    Placebo            AGE      summary mean      Mean        75.2 75.209  
#> 3 ARM    Xanomeline High D… AGE      summary N         N           84   84      
#> 4 ARM    Xanomeline High D… AGE      summary mean      Mean        74.4 74.4    
#> 5 ARM    Xanomeline Low Do… AGE      summary N         N           84   84      
#> 6 ARM    Xanomeline Low Do… AGE      summary mean      Mean        75.7 75.7    
#> # ℹ 3 more variables: fmt_fun <list>, warning <list>, error <list>

Custom Formatting Functions

Beyond integer aliases, you can pass custom functions:

# Custom formatter that adds parentheses
format_with_parens <- function(x) {
  paste0("(", format(round(x, 1), nsmall = 1), ")")
}

ard_summary(ADSL, variables = AGE) |>
  update_ard_fmt_fun(
    stat_names = "sd",
    fmt_fun = format_with_parens
  ) |>
  apply_fmt_fun()
#> # An ARD data frame: 8 × 9
#>   variable context stat_name stat_label   stat stat_fmt fmt_fun warning error 
#>   <chr>    <chr>   <chr>     <chr>      <list> <list>   <list>  <list>  <list>
#> 1 AGE      summary N         N          254    254      0       <NULL>  <NULL>
#> 2 AGE      summary mean      Mean        75.1  75.1     1       <NULL>  <NULL>
#> 3 AGE      summary sd        SD           8.25 (8.2)    <fn>    <NULL>  <NULL>
#> 4 AGE      summary median    Median      77    77.0     1       <NULL>  <NULL>
#> 5 AGE      summary p25       Q1          70    70.0     1       <NULL>  <NULL>
#> 6 AGE      summary p75       Q3          81    81.0     1       <NULL>  <NULL>
#> 7 AGE      summary min       Min         51    51.0     1       <NULL>  <NULL>
#> 8 AGE      summary max       Max         89    89.0     1       <NULL>  <NULL>