---
title: "Example 2: ARDS in Serial"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Example 2: ARDS in Serial}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```
The **ards** package also supports a design that separates the analysis 
from the reporting.  This approach is called creating an ARDS in serial.
## Serial ARDS Example
For this example, there are two programs.  The first program performs the analysis and
saves the results in ARDS format.  The second program picks up the ARDS data,
transposes it back into a usable structure, and generates the report.
A diagram of the serial approach looks like this:
 First, we'll create a program to perform the analysis.  Note the following
about the program below:
* The same data from [Example 1](ards-example1.html) is used here.
* The `init_ards()` function is called again at the top of the program. This 
call will prepare the bucket in which the analysis is dumped.
* The analysis is performed, and `add_ards()` is called to add the analysis
to the ARDS.
* This time, however, the additional steps for formatting and combining
the data are skipped.  Instead, the ARDS
data is simply extracted and stored.
Observe:
```{r eval=FALSE, echo=TRUE}
library(dplyr)
library(tibble)
library(tidyr)
library(ards)
# Create input data
adsl <- read.table(header = TRUE, text = '
STUDYID	DOMAIN	USUBJID	SUBJID	SITEID	BRTHDTC	AGE	AGEU	SEX	RACE	ARMCD	ARM
ABC	DM	ABC-01-049	49	1	11/12/1966	39	YEARS	M	"WHITE"		4	"ARM D"
ABC	DM	ABC-01-050	50	1	12/19/1958	47	YEARS	M	"WHITE"		2	"ARM B"
ABC	DM	ABC-01-051	51	1	5/2/1972	34	YEARS	M	"WHITE"		  1	"ARM A"
ABC	DM	ABC-01-052	52	1	6/27/1961	45	YEARS	F	"WHITE"	    3	"ARM C"
ABC	DM	ABC-01-053	53	1	4/7/1980	26	YEARS	F	"WHITE"		  2	"ARM B"
ABC	DM	ABC-01-054	54	1	9/13/1962	44	YEARS	M	"WHITE"		  4	"ARM D"
ABC	DM	ABC-01-055	55	1	6/11/1959	47	YEARS	F	"BLACK OR AFRICAN AMERICAN" 3	"ARM C"
ABC	DM	ABC-01-056	56	1	5/2/1975	31	YEARS	M	"WHITE"		  1	"ARM A"
ABC	DM	ABC-01-113	113	1	2/8/1932	74	YEARS	M	"WHITE"		  4	"ARM D"')
# Create factors for categorical variables
# to get zero counts
adsl$SEX <- as.factor(adsl$SEX)
adsl$RACE <- as.factor(adsl$RACE)
adsl$ARM <- factor(adsl$ARM, levels = c("ARM A", "ARM B", "ARM C", "ARM D"))
# Initalize ARDS
init_ards(studyid = "ABC",
          tableid = "01", adsns = "adsl",
          population = "safety population",
          time = "SCREENING", where = "saffl = TRUE", reset = TRUE)
# Perform analysis on AGE variable
agedf <- adsl |>
  select(AGE, ARM) |>
  group_by(ARM, .drop = FALSE) |>
  summarize(n = n(),
            mean = mean(AGE),
            std = sd(AGE),
            median = median(AGE),
            min = min(AGE),
            max = max(AGE)) |>
  mutate(analvar = "AGE") |>
  ungroup() |>
  add_ards(statvars = c("n", "mean", "std", "median", "min", "max"),
           statdesc = c("N", "Mean", "Std", "Median", "Min", "Max"),
           anal_var = "AGE", trtvar = "ARM") 
# View analysis results
agedf
# # A tibble: 4 × 8
#   ARM       n  mean   std median   min   max analvar
#             
# 1 ARM A     2  32.5  2.12   32.5    31    34 AGE    
# 2 ARM B     2  36.5 14.8    36.5    26    47 AGE    
# 3 ARM C     2  46    1.41   46      45    47 AGE    
# 4 ARM D     3  52.3 18.9    44      39    74 AGE    
# Get population counts
trt_pop <- count(adsl, ARM) |> deframe()
trt_pop
# ARM A ARM B ARM C ARM D 
#   2     2     2     3 
# Perform analysis on SEX variable
sexdf <- adsl |>
  mutate(denom = trt_pop[paste0(adsl$ARM)]) |>
  group_by(SEX, ARM, denom, .drop = FALSE) |>
  summarize(cnt = n()) |>
  transmute(SEX, ARM, cnt, analvar = "SEX", label = SEX,  
            pct =  if_else(is.na(denom), 0, cnt / denom * 100)) |>
  ungroup() |>
  add_ards(statvars = c("cnt", "pct"), statdesc = "label",
           anal_var = "SEX", trtvar = "ARM") 
# View analysis results
sexdf
# # A tibble: 8 × 6
#   SEX   ARM     cnt analvar label   pct
#          
# 1 F     ARM A     0 SEX     F         0
# 2 F     ARM B     1 SEX     F        50
# 3 F     ARM C     2 SEX     F       100
# 4 F     ARM D     0 SEX     F         0
# 5 M     ARM A     2 SEX     M       100
# 6 M     ARM B     1 SEX     M        50
# 7 M     ARM C     0 SEX     M         0
# 8 M     ARM D     3 SEX     M       100
# Perform analysis on RACE
racedf <- adsl |>
  mutate(denom = trt_pop[paste0(adsl$ARM)]) |>
  group_by(RACE, ARM, denom, .drop = FALSE) |>
  summarize(cnt = n()) |>
  transmute(RACE, ARM, cnt, analvar = "RACE", label = RACE,  
            pct =  if_else(is.na(denom), 0, cnt / denom * 100)) |>
  ungroup() |>
  add_ards(statvars = c("cnt", "pct"), statdesc = "label",
           anal_var = "RACE", trtvar = "ARM") 
# View analysis results
racedf
# # A tibble: 8 × 6
#   RACE                      ARM     cnt analvar label                       pct
#                                                  
# 1 BLACK OR AFRICAN AMERICAN ARM A     0 RACE    BLACK OR AFRICAN AMERICAN     0
# 2 BLACK OR AFRICAN AMERICAN ARM B     0 RACE    BLACK OR AFRICAN AMERICAN     0
# 3 BLACK OR AFRICAN AMERICAN ARM C     1 RACE    BLACK OR AFRICAN AMERICAN    50
# 4 BLACK OR AFRICAN AMERICAN ARM D     0 RACE    BLACK OR AFRICAN AMERICAN     0
# 5 WHITE                     ARM A     2 RACE    WHITE                       100
# 6 WHITE                     ARM B     2 RACE    WHITE                       100
# 7 WHITE                     ARM C     1 RACE    WHITE                        50
# 8 WHITE                     ARM D     3 RACE    WHITE                       100
# Extract ARDS
ards <- get_ards() 
# Save ARDS data to file or database here
# Remove some variables to improve readability
ards_reduced <- ards |> 
  select(trtvar, trtval, anal_var, anal_val, 
         statname, statval)
# View results
ards_reduced
#    trtvar trtval anal_var                  anal_val statname    statval
# 1     ARM  ARM A      AGE                              n   2.000000
# 2     ARM  ARM B      AGE                              n   2.000000
# 3     ARM  ARM C      AGE                              n   2.000000
# 4     ARM  ARM D      AGE                              n   3.000000
# 5     ARM  ARM A      AGE                           mean  32.500000
# 6     ARM  ARM B      AGE                           mean  36.500000
# 7     ARM  ARM C      AGE                           mean  46.000000
# 8     ARM  ARM D      AGE                           mean  52.333333
# 9     ARM  ARM A      AGE                            std   2.121320
# 10    ARM  ARM B      AGE                            std  14.849242
# 11    ARM  ARM C      AGE                            std   1.414214
# 12    ARM  ARM D      AGE                            std  18.929694
# 13    ARM  ARM A      AGE                         median  32.500000
# 14    ARM  ARM B      AGE                         median  36.500000
# 15    ARM  ARM C      AGE                         median  46.000000
# 16    ARM  ARM D      AGE                         median  44.000000
# 17    ARM  ARM A      AGE                            min  31.000000
# 18    ARM  ARM B      AGE                            min  26.000000
# 19    ARM  ARM C      AGE                            min  45.000000
# 20    ARM  ARM D      AGE                            min  39.000000
# 21    ARM  ARM A      AGE                            max  34.000000
# 22    ARM  ARM B      AGE                            max  47.000000
# 23    ARM  ARM C      AGE                            max  47.000000
# 24    ARM  ARM D      AGE                            max  74.000000
# 25    ARM  ARM A      SEX                         F      cnt   0.000000
# 26    ARM  ARM B      SEX                         F      cnt   1.000000
# 27    ARM  ARM C      SEX                         F      cnt   2.000000
# 28    ARM  ARM D      SEX                         F      cnt   0.000000
# 29    ARM  ARM A      SEX                         M      cnt   2.000000
# 30    ARM  ARM B      SEX                         M      cnt   1.000000
# 31    ARM  ARM C      SEX                         M      cnt   0.000000
# 32    ARM  ARM D      SEX                         M      cnt   3.000000
# 33    ARM  ARM A      SEX                         F      pct   0.000000
# 34    ARM  ARM B      SEX                         F      pct  50.000000
# 35    ARM  ARM C      SEX                         F      pct 100.000000
# 36    ARM  ARM D      SEX                         F      pct   0.000000
# 37    ARM  ARM A      SEX                         M      pct 100.000000
# 38    ARM  ARM B      SEX                         M      pct  50.000000
# 39    ARM  ARM C      SEX                         M      pct   0.000000
# 40    ARM  ARM D      SEX                         M      pct 100.000000
# 41    ARM  ARM A     RACE BLACK OR AFRICAN AMERICAN      cnt   0.000000
# 42    ARM  ARM B     RACE BLACK OR AFRICAN AMERICAN      cnt   0.000000
# 43    ARM  ARM C     RACE BLACK OR AFRICAN AMERICAN      cnt   1.000000
# 44    ARM  ARM D     RACE BLACK OR AFRICAN AMERICAN      cnt   0.000000
# 45    ARM  ARM A     RACE                     WHITE      cnt   2.000000
# 46    ARM  ARM B     RACE                     WHITE      cnt   2.000000
# 47    ARM  ARM C     RACE                     WHITE      cnt   1.000000
# 48    ARM  ARM D     RACE                     WHITE      cnt   3.000000
# 49    ARM  ARM A     RACE BLACK OR AFRICAN AMERICAN      pct   0.000000
# 50    ARM  ARM B     RACE BLACK OR AFRICAN AMERICAN      pct   0.000000
# 51    ARM  ARM C     RACE BLACK OR AFRICAN AMERICAN      pct  50.000000
# 52    ARM  ARM D     RACE BLACK OR AFRICAN AMERICAN      pct   0.000000
# 53    ARM  ARM A     RACE                     WHITE      pct 100.000000
# 54    ARM  ARM B     RACE                     WHITE      pct 100.000000
# 55    ARM  ARM C     RACE                     WHITE      pct  50.000000
# 56    ARM  ARM D     RACE                     WHITE      pct 100.000000
```
Notice that the ARDS dataset is the exact same dataset as that produced in 
Example 1.  In this program, however, the final reporting dataset
was not created.  We will create the reporting dataset in the next program.
## Reporting from ARDS
The next program will pick up the ARDS dataset from the analysis program, 
and produce a final data frame for reporting. Note the following about this 
program:
* The first step is to convert the ARDS data back into wide form, using
the `restore_ards()` function.
* Subsequent steps format and combine the restored data to create analysis
blocks.
* The analysis blocks are combined into a single final data frame.  At this
point, the data can be fed to a reporting package of your choice.
Here is the code:
```{r eval=FALSE, echo=TRUE}
# Extract ARDS data from file or database here
# Restore to wide format
res <- restore_ards(ards)
# View results
res
# $AGE
#     ARM anal_var n     mean       std median min max
# 1 ARM A      AGE 2 32.50000  2.121320   32.5  31  34
# 2 ARM B      AGE 2 36.50000 14.849242   36.5  26  47
# 3 ARM C      AGE 2 46.00000  1.414214   46.0  45  47
# 4 ARM D      AGE 3 52.33333 18.929694   44.0  39  74
# 
# $SEX
#     ARM anal_var SEX cnt pct
# 1 ARM A      SEX   F   0   0
# 2 ARM B      SEX   F   1  50
# 3 ARM C      SEX   F   2 100
# 4 ARM D      SEX   F   0   0
# 5 ARM A      SEX   M   2 100
# 6 ARM B      SEX   M   1  50
# 7 ARM C      SEX   M   0   0
# 8 ARM D      SEX   M   3 100
# 
# $RACE
#     ARM anal_var                      RACE cnt pct
# 1 ARM A     RACE BLACK OR AFRICAN AMERICAN   0   0
# 2 ARM B     RACE BLACK OR AFRICAN AMERICAN   0   0
# 3 ARM C     RACE BLACK OR AFRICAN AMERICAN   1  50
# 4 ARM D     RACE BLACK OR AFRICAN AMERICAN   0   0
# 5 ARM A     RACE                     WHITE   2 100
# 6 ARM B     RACE                     WHITE   2 100
# 7 ARM C     RACE                     WHITE   1  50
# 8 ARM D     RACE                     WHITE   3 100
# Perform formatting on AGE analysis
agedf <- res$AGE |>
  transmute(anal_var, ARM,
            n = sprintf("%d", n),
            mean_sd = sprintf("%.1f (%.2f)", mean, std),
            median = sprintf("%.1f", median),
            min_max = sprintf("%.1f-%.1f", min, max)) |>
  pivot_longer(c(n, mean_sd, median, min_max),
               names_to = "label", values_to = "stats") |>
  pivot_wider(names_from = ARM,
              values_from = c(stats)) |>
  transmute(anal_var, label = c("N", "Mean (Std)", "Median", "Min-Max"),
            trtA = `ARM A`, trtB = `ARM B`, trtC = `ARM C`, trtD = `ARM D`)
# View analysis results
agedf
# # A tibble: 4 × 6
#   anal_var label      trtA        trtB         trtC        trtD        
#                                          
# 1 AGE      N          2           2            2           3           
# 2 AGE      Mean (Std) 32.5 (2.12) 36.5 (14.85) 46.0 (1.41) 52.3 (18.93)
# 3 AGE      Median     32.5        36.5         46.0        44.0        
# 4 AGE      Min-Max    31.0-34.0   26.0-47.0    45.0-47.0   39.0-74.0 
# Perform formatting on SEX analysis
sexdf <- res$SEX |>
  pivot_wider(names_from = ARM,
              values_from = c(cnt, pct)) |>
  transmute(anal_var, label = SEX,
            trtA = sprintf("%1d (%3.0f%%)", `cnt_ARM A`, `pct_ARM A`),
            trtB = sprintf("%1d (%3.0f%%)", `cnt_ARM B`, `pct_ARM B`),
            trtC = sprintf("%1d (%3.0f%%)", `cnt_ARM C`, `pct_ARM C`),
            trtD = sprintf("%1d (%3.0f%%)", `cnt_ARM D`, `pct_ARM D`))
# View analysis results
sexdf
# # A tibble: 2 × 6
# analvar label trtA     trtB     trtC     trtD    
#                      
# 1 SEX     F     0 (  0%) 1 ( 50%) 2 (100%) 0 (  0%)
# 2 SEX     M     2 (100%) 1 ( 50%) 0 (  0%) 3 (100%)
# Perform formatting on RACE analysis
racedf <- res$RACE |>
  pivot_wider(names_from = ARM,
              values_from = c(cnt, pct)) |>
  transmute(anal_var, label = RACE,
            trtA = sprintf("%1d (%3.0f%%)", `cnt_ARM A`, `pct_ARM A`),
            trtB = sprintf("%1d (%3.0f%%)", `cnt_ARM B`, `pct_ARM B`),
            trtC = sprintf("%1d (%3.0f%%)", `cnt_ARM C`, `pct_ARM C`),
            trtD = sprintf("%1d (%3.0f%%)", `cnt_ARM D`, `pct_ARM D`))
# View analysis results
racedf
# # A tibble: 2 × 6
#   anal_var RACE                      trtA     trtB     trtC     trtD    
#                                           
# 1 RACE     BLACK OR AFRICAN AMERICAN 0 (  0%) 0 (  0%) 1 ( 50%) 0 (  0%)
# 2 RACE     WHITE                     2 (100%) 2 (100%) 1 ( 50%) 3 (100%)
# Combine all analysis into final data frame
final <- bind_rows(agedf, sexdf, racedf)
# View final data frame
# - This data frame is ready reporting
final
# # A tibble: 8 × 6
#   anal_var label                     trtA        trtB         trtC        trtD        
#                                                         
# 1 AGE      N                         2           2            2           3           
# 2 AGE      Mean (Std)                32.5 (2.12) 36.5 (14.85) 46.0 (1.41) 52.3 (18.93)
# 3 AGE      Median                    32.5        36.5         46.0        44.0        
# 4 AGE      Min-Max                   31.0-34.0   26.0-47.0    45.0-47.0   39.0-74.0   
# 5 SEX      F                         0 (  0%)    1 ( 50%)     2 (100%)    0 (  0%)    
# 6 SEX      M                         2 (100%)    1 ( 50%)     0 (  0%)    3 (100%)    
# 7 RACE     BLACK OR AFRICAN AMERICAN 0 (  0%)    0 (  0%)     1 ( 50%)    0 (  0%)    
# 8 RACE     WHITE                     2 (100%)    2 (100%)     1 ( 50%)    3 (100%) 
# Perform reporting here
```
While somewhat more complicated, the serial ARDS approach provides more 
flexibility.  If desired, you could create additional
programs for intext tables, figures, or for uploads to 
[ClinicalTrials.gov](https://clinicaltrials.gov/).
All of these outputs can be created from the ARDS dataset.
Next Steps: [Frequently Asked Questions](ards-faq.html)
First, we'll create a program to perform the analysis.  Note the following
about the program below:
* The same data from [Example 1](ards-example1.html) is used here.
* The `init_ards()` function is called again at the top of the program. This 
call will prepare the bucket in which the analysis is dumped.
* The analysis is performed, and `add_ards()` is called to add the analysis
to the ARDS.
* This time, however, the additional steps for formatting and combining
the data are skipped.  Instead, the ARDS
data is simply extracted and stored.
Observe:
```{r eval=FALSE, echo=TRUE}
library(dplyr)
library(tibble)
library(tidyr)
library(ards)
# Create input data
adsl <- read.table(header = TRUE, text = '
STUDYID	DOMAIN	USUBJID	SUBJID	SITEID	BRTHDTC	AGE	AGEU	SEX	RACE	ARMCD	ARM
ABC	DM	ABC-01-049	49	1	11/12/1966	39	YEARS	M	"WHITE"		4	"ARM D"
ABC	DM	ABC-01-050	50	1	12/19/1958	47	YEARS	M	"WHITE"		2	"ARM B"
ABC	DM	ABC-01-051	51	1	5/2/1972	34	YEARS	M	"WHITE"		  1	"ARM A"
ABC	DM	ABC-01-052	52	1	6/27/1961	45	YEARS	F	"WHITE"	    3	"ARM C"
ABC	DM	ABC-01-053	53	1	4/7/1980	26	YEARS	F	"WHITE"		  2	"ARM B"
ABC	DM	ABC-01-054	54	1	9/13/1962	44	YEARS	M	"WHITE"		  4	"ARM D"
ABC	DM	ABC-01-055	55	1	6/11/1959	47	YEARS	F	"BLACK OR AFRICAN AMERICAN" 3	"ARM C"
ABC	DM	ABC-01-056	56	1	5/2/1975	31	YEARS	M	"WHITE"		  1	"ARM A"
ABC	DM	ABC-01-113	113	1	2/8/1932	74	YEARS	M	"WHITE"		  4	"ARM D"')
# Create factors for categorical variables
# to get zero counts
adsl$SEX <- as.factor(adsl$SEX)
adsl$RACE <- as.factor(adsl$RACE)
adsl$ARM <- factor(adsl$ARM, levels = c("ARM A", "ARM B", "ARM C", "ARM D"))
# Initalize ARDS
init_ards(studyid = "ABC",
          tableid = "01", adsns = "adsl",
          population = "safety population",
          time = "SCREENING", where = "saffl = TRUE", reset = TRUE)
# Perform analysis on AGE variable
agedf <- adsl |>
  select(AGE, ARM) |>
  group_by(ARM, .drop = FALSE) |>
  summarize(n = n(),
            mean = mean(AGE),
            std = sd(AGE),
            median = median(AGE),
            min = min(AGE),
            max = max(AGE)) |>
  mutate(analvar = "AGE") |>
  ungroup() |>
  add_ards(statvars = c("n", "mean", "std", "median", "min", "max"),
           statdesc = c("N", "Mean", "Std", "Median", "Min", "Max"),
           anal_var = "AGE", trtvar = "ARM") 
# View analysis results
agedf
# # A tibble: 4 × 8
#   ARM       n  mean   std median   min   max analvar
#             
# 1 ARM A     2  32.5  2.12   32.5    31    34 AGE    
# 2 ARM B     2  36.5 14.8    36.5    26    47 AGE    
# 3 ARM C     2  46    1.41   46      45    47 AGE    
# 4 ARM D     3  52.3 18.9    44      39    74 AGE    
# Get population counts
trt_pop <- count(adsl, ARM) |> deframe()
trt_pop
# ARM A ARM B ARM C ARM D 
#   2     2     2     3 
# Perform analysis on SEX variable
sexdf <- adsl |>
  mutate(denom = trt_pop[paste0(adsl$ARM)]) |>
  group_by(SEX, ARM, denom, .drop = FALSE) |>
  summarize(cnt = n()) |>
  transmute(SEX, ARM, cnt, analvar = "SEX", label = SEX,  
            pct =  if_else(is.na(denom), 0, cnt / denom * 100)) |>
  ungroup() |>
  add_ards(statvars = c("cnt", "pct"), statdesc = "label",
           anal_var = "SEX", trtvar = "ARM") 
# View analysis results
sexdf
# # A tibble: 8 × 6
#   SEX   ARM     cnt analvar label   pct
#          
# 1 F     ARM A     0 SEX     F         0
# 2 F     ARM B     1 SEX     F        50
# 3 F     ARM C     2 SEX     F       100
# 4 F     ARM D     0 SEX     F         0
# 5 M     ARM A     2 SEX     M       100
# 6 M     ARM B     1 SEX     M        50
# 7 M     ARM C     0 SEX     M         0
# 8 M     ARM D     3 SEX     M       100
# Perform analysis on RACE
racedf <- adsl |>
  mutate(denom = trt_pop[paste0(adsl$ARM)]) |>
  group_by(RACE, ARM, denom, .drop = FALSE) |>
  summarize(cnt = n()) |>
  transmute(RACE, ARM, cnt, analvar = "RACE", label = RACE,  
            pct =  if_else(is.na(denom), 0, cnt / denom * 100)) |>
  ungroup() |>
  add_ards(statvars = c("cnt", "pct"), statdesc = "label",
           anal_var = "RACE", trtvar = "ARM") 
# View analysis results
racedf
# # A tibble: 8 × 6
#   RACE                      ARM     cnt analvar label                       pct
#                                                  
# 1 BLACK OR AFRICAN AMERICAN ARM A     0 RACE    BLACK OR AFRICAN AMERICAN     0
# 2 BLACK OR AFRICAN AMERICAN ARM B     0 RACE    BLACK OR AFRICAN AMERICAN     0
# 3 BLACK OR AFRICAN AMERICAN ARM C     1 RACE    BLACK OR AFRICAN AMERICAN    50
# 4 BLACK OR AFRICAN AMERICAN ARM D     0 RACE    BLACK OR AFRICAN AMERICAN     0
# 5 WHITE                     ARM A     2 RACE    WHITE                       100
# 6 WHITE                     ARM B     2 RACE    WHITE                       100
# 7 WHITE                     ARM C     1 RACE    WHITE                        50
# 8 WHITE                     ARM D     3 RACE    WHITE                       100
# Extract ARDS
ards <- get_ards() 
# Save ARDS data to file or database here
# Remove some variables to improve readability
ards_reduced <- ards |> 
  select(trtvar, trtval, anal_var, anal_val, 
         statname, statval)
# View results
ards_reduced
#    trtvar trtval anal_var                  anal_val statname    statval
# 1     ARM  ARM A      AGE                              n   2.000000
# 2     ARM  ARM B      AGE                              n   2.000000
# 3     ARM  ARM C      AGE                              n   2.000000
# 4     ARM  ARM D      AGE                              n   3.000000
# 5     ARM  ARM A      AGE                           mean  32.500000
# 6     ARM  ARM B      AGE                           mean  36.500000
# 7     ARM  ARM C      AGE                           mean  46.000000
# 8     ARM  ARM D      AGE                           mean  52.333333
# 9     ARM  ARM A      AGE                            std   2.121320
# 10    ARM  ARM B      AGE                            std  14.849242
# 11    ARM  ARM C      AGE                            std   1.414214
# 12    ARM  ARM D      AGE                            std  18.929694
# 13    ARM  ARM A      AGE                         median  32.500000
# 14    ARM  ARM B      AGE                         median  36.500000
# 15    ARM  ARM C      AGE                         median  46.000000
# 16    ARM  ARM D      AGE                         median  44.000000
# 17    ARM  ARM A      AGE                            min  31.000000
# 18    ARM  ARM B      AGE                            min  26.000000
# 19    ARM  ARM C      AGE                            min  45.000000
# 20    ARM  ARM D      AGE                            min  39.000000
# 21    ARM  ARM A      AGE                            max  34.000000
# 22    ARM  ARM B      AGE                            max  47.000000
# 23    ARM  ARM C      AGE                            max  47.000000
# 24    ARM  ARM D      AGE                            max  74.000000
# 25    ARM  ARM A      SEX                         F      cnt   0.000000
# 26    ARM  ARM B      SEX                         F      cnt   1.000000
# 27    ARM  ARM C      SEX                         F      cnt   2.000000
# 28    ARM  ARM D      SEX                         F      cnt   0.000000
# 29    ARM  ARM A      SEX                         M      cnt   2.000000
# 30    ARM  ARM B      SEX                         M      cnt   1.000000
# 31    ARM  ARM C      SEX                         M      cnt   0.000000
# 32    ARM  ARM D      SEX                         M      cnt   3.000000
# 33    ARM  ARM A      SEX                         F      pct   0.000000
# 34    ARM  ARM B      SEX                         F      pct  50.000000
# 35    ARM  ARM C      SEX                         F      pct 100.000000
# 36    ARM  ARM D      SEX                         F      pct   0.000000
# 37    ARM  ARM A      SEX                         M      pct 100.000000
# 38    ARM  ARM B      SEX                         M      pct  50.000000
# 39    ARM  ARM C      SEX                         M      pct   0.000000
# 40    ARM  ARM D      SEX                         M      pct 100.000000
# 41    ARM  ARM A     RACE BLACK OR AFRICAN AMERICAN      cnt   0.000000
# 42    ARM  ARM B     RACE BLACK OR AFRICAN AMERICAN      cnt   0.000000
# 43    ARM  ARM C     RACE BLACK OR AFRICAN AMERICAN      cnt   1.000000
# 44    ARM  ARM D     RACE BLACK OR AFRICAN AMERICAN      cnt   0.000000
# 45    ARM  ARM A     RACE                     WHITE      cnt   2.000000
# 46    ARM  ARM B     RACE                     WHITE      cnt   2.000000
# 47    ARM  ARM C     RACE                     WHITE      cnt   1.000000
# 48    ARM  ARM D     RACE                     WHITE      cnt   3.000000
# 49    ARM  ARM A     RACE BLACK OR AFRICAN AMERICAN      pct   0.000000
# 50    ARM  ARM B     RACE BLACK OR AFRICAN AMERICAN      pct   0.000000
# 51    ARM  ARM C     RACE BLACK OR AFRICAN AMERICAN      pct  50.000000
# 52    ARM  ARM D     RACE BLACK OR AFRICAN AMERICAN      pct   0.000000
# 53    ARM  ARM A     RACE                     WHITE      pct 100.000000
# 54    ARM  ARM B     RACE                     WHITE      pct 100.000000
# 55    ARM  ARM C     RACE                     WHITE      pct  50.000000
# 56    ARM  ARM D     RACE                     WHITE      pct 100.000000
```
Notice that the ARDS dataset is the exact same dataset as that produced in 
Example 1.  In this program, however, the final reporting dataset
was not created.  We will create the reporting dataset in the next program.
## Reporting from ARDS
The next program will pick up the ARDS dataset from the analysis program, 
and produce a final data frame for reporting. Note the following about this 
program:
* The first step is to convert the ARDS data back into wide form, using
the `restore_ards()` function.
* Subsequent steps format and combine the restored data to create analysis
blocks.
* The analysis blocks are combined into a single final data frame.  At this
point, the data can be fed to a reporting package of your choice.
Here is the code:
```{r eval=FALSE, echo=TRUE}
# Extract ARDS data from file or database here
# Restore to wide format
res <- restore_ards(ards)
# View results
res
# $AGE
#     ARM anal_var n     mean       std median min max
# 1 ARM A      AGE 2 32.50000  2.121320   32.5  31  34
# 2 ARM B      AGE 2 36.50000 14.849242   36.5  26  47
# 3 ARM C      AGE 2 46.00000  1.414214   46.0  45  47
# 4 ARM D      AGE 3 52.33333 18.929694   44.0  39  74
# 
# $SEX
#     ARM anal_var SEX cnt pct
# 1 ARM A      SEX   F   0   0
# 2 ARM B      SEX   F   1  50
# 3 ARM C      SEX   F   2 100
# 4 ARM D      SEX   F   0   0
# 5 ARM A      SEX   M   2 100
# 6 ARM B      SEX   M   1  50
# 7 ARM C      SEX   M   0   0
# 8 ARM D      SEX   M   3 100
# 
# $RACE
#     ARM anal_var                      RACE cnt pct
# 1 ARM A     RACE BLACK OR AFRICAN AMERICAN   0   0
# 2 ARM B     RACE BLACK OR AFRICAN AMERICAN   0   0
# 3 ARM C     RACE BLACK OR AFRICAN AMERICAN   1  50
# 4 ARM D     RACE BLACK OR AFRICAN AMERICAN   0   0
# 5 ARM A     RACE                     WHITE   2 100
# 6 ARM B     RACE                     WHITE   2 100
# 7 ARM C     RACE                     WHITE   1  50
# 8 ARM D     RACE                     WHITE   3 100
# Perform formatting on AGE analysis
agedf <- res$AGE |>
  transmute(anal_var, ARM,
            n = sprintf("%d", n),
            mean_sd = sprintf("%.1f (%.2f)", mean, std),
            median = sprintf("%.1f", median),
            min_max = sprintf("%.1f-%.1f", min, max)) |>
  pivot_longer(c(n, mean_sd, median, min_max),
               names_to = "label", values_to = "stats") |>
  pivot_wider(names_from = ARM,
              values_from = c(stats)) |>
  transmute(anal_var, label = c("N", "Mean (Std)", "Median", "Min-Max"),
            trtA = `ARM A`, trtB = `ARM B`, trtC = `ARM C`, trtD = `ARM D`)
# View analysis results
agedf
# # A tibble: 4 × 6
#   anal_var label      trtA        trtB         trtC        trtD        
#                                          
# 1 AGE      N          2           2            2           3           
# 2 AGE      Mean (Std) 32.5 (2.12) 36.5 (14.85) 46.0 (1.41) 52.3 (18.93)
# 3 AGE      Median     32.5        36.5         46.0        44.0        
# 4 AGE      Min-Max    31.0-34.0   26.0-47.0    45.0-47.0   39.0-74.0 
# Perform formatting on SEX analysis
sexdf <- res$SEX |>
  pivot_wider(names_from = ARM,
              values_from = c(cnt, pct)) |>
  transmute(anal_var, label = SEX,
            trtA = sprintf("%1d (%3.0f%%)", `cnt_ARM A`, `pct_ARM A`),
            trtB = sprintf("%1d (%3.0f%%)", `cnt_ARM B`, `pct_ARM B`),
            trtC = sprintf("%1d (%3.0f%%)", `cnt_ARM C`, `pct_ARM C`),
            trtD = sprintf("%1d (%3.0f%%)", `cnt_ARM D`, `pct_ARM D`))
# View analysis results
sexdf
# # A tibble: 2 × 6
# analvar label trtA     trtB     trtC     trtD    
#                      
# 1 SEX     F     0 (  0%) 1 ( 50%) 2 (100%) 0 (  0%)
# 2 SEX     M     2 (100%) 1 ( 50%) 0 (  0%) 3 (100%)
# Perform formatting on RACE analysis
racedf <- res$RACE |>
  pivot_wider(names_from = ARM,
              values_from = c(cnt, pct)) |>
  transmute(anal_var, label = RACE,
            trtA = sprintf("%1d (%3.0f%%)", `cnt_ARM A`, `pct_ARM A`),
            trtB = sprintf("%1d (%3.0f%%)", `cnt_ARM B`, `pct_ARM B`),
            trtC = sprintf("%1d (%3.0f%%)", `cnt_ARM C`, `pct_ARM C`),
            trtD = sprintf("%1d (%3.0f%%)", `cnt_ARM D`, `pct_ARM D`))
# View analysis results
racedf
# # A tibble: 2 × 6
#   anal_var RACE                      trtA     trtB     trtC     trtD    
#                                           
# 1 RACE     BLACK OR AFRICAN AMERICAN 0 (  0%) 0 (  0%) 1 ( 50%) 0 (  0%)
# 2 RACE     WHITE                     2 (100%) 2 (100%) 1 ( 50%) 3 (100%)
# Combine all analysis into final data frame
final <- bind_rows(agedf, sexdf, racedf)
# View final data frame
# - This data frame is ready reporting
final
# # A tibble: 8 × 6
#   anal_var label                     trtA        trtB         trtC        trtD        
#                                                         
# 1 AGE      N                         2           2            2           3           
# 2 AGE      Mean (Std)                32.5 (2.12) 36.5 (14.85) 46.0 (1.41) 52.3 (18.93)
# 3 AGE      Median                    32.5        36.5         46.0        44.0        
# 4 AGE      Min-Max                   31.0-34.0   26.0-47.0    45.0-47.0   39.0-74.0   
# 5 SEX      F                         0 (  0%)    1 ( 50%)     2 (100%)    0 (  0%)    
# 6 SEX      M                         2 (100%)    1 ( 50%)     0 (  0%)    3 (100%)    
# 7 RACE     BLACK OR AFRICAN AMERICAN 0 (  0%)    0 (  0%)     1 ( 50%)    0 (  0%)    
# 8 RACE     WHITE                     2 (100%)    2 (100%)     1 ( 50%)    3 (100%) 
# Perform reporting here
```
While somewhat more complicated, the serial ARDS approach provides more 
flexibility.  If desired, you could create additional
programs for intext tables, figures, or for uploads to 
[ClinicalTrials.gov](https://clinicaltrials.gov/).
All of these outputs can be created from the ARDS dataset.
Next Steps: [Frequently Asked Questions](ards-faq.html)