The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Complete Example 2

Program

Here is another example of a complete program that demonstrates several of the key functions in the libr package. The example also shows how the package integrates with sassy.

library(sassy)

options("logr.autolog" = TRUE,
        "logr.notes" = FALSE)

# Get temp location for log and report output
tmp <- tempdir()

# Open log
lf <- log_open(file.path(tmp, "example1.log"))


# Prepare Data ------------------------------------------------------------

sep("Prepare Data")

# Get path to sample data
pkg <- system.file("extdata", package = "libr")

# Create libname for csv data
libname(sdtm, pkg, "csv", quiet = TRUE) 


put("Join and prepare data")

put("Join DM to VS and keep desired columns")
datastep(sdtm$DM, merge = sdtm$VS, merge_by = USUBJID,
         keep = v(USUBJID, VSTESTCD, VISIT, VISITNUM, VSSTRESN, ARM, VSBLFL), 
         where = expression(VSTESTCD %in% c("PULSE", "RESP", "TEMP", "DIABP", "SYSBP") & 
                            !(VISIT == "SCREENING" & VSBLFL != "Y")), {}) -> dm_joined

put("Sort by variables")
proc_sort(dm_joined, by = v(USUBJID, VSTESTCD, VISITNUM)) -> dm_sorted

put("Differentiate baseline from treated vital signs")
datastep(dm_sorted, by = v(USUBJID, VSTESTCD),
         retain = list(BSTRESN = 0), {
  
  # Combine treatment groups
  # And distinguish baseline time points
  if (ARM == "ARM A") {
    if (VSBLFL %eq% "Y") {
      GRP <- "A_BASE"
    } else {
      GRP <- "A_TRT"
    }
  } else {
    if (VSBLFL %eq% "Y") {
      GRP <- "O_BASE"
    } else {
      GRP <- "O_TRT"
    }
  }
  
  # Populate baseline value
  if (first.)
    BSTRESN = VSSTRESN
  
}) -> prep
         

put("Get population counts")
pop_A <- subset(prep, GRP == "A_BASE", v(USUBJID, GRP)) |> 
  proc_sort(options = nodupkey) |> 
  proc_freq(tables = GRP, 
            options = v(nocum, nonobs, nopercent), 
            output = long) |> 
  subset(select = "A_BASE", drop = TRUE)

pop_O <- subset(prep, GRP == "O_BASE", v(USUBJID, GRP)) |> 
  proc_sort(options = nodupkey) |> 
  proc_freq(tables = GRP, 
            options = v(nocum, nonobs, nopercent), 
            output = long) |> 
  subset(select = "O_BASE", drop = TRUE)


# Prepare formats ---------------------------------------------------------

sep("Prepare formats")



put("Vital sign lookup format")
vs_fmt <- c(PULSE = "Pulse", 
            TEMP = "Temperature °C", 
            RESP = "Respirations/min", 
            SYSBP = "Systolic Blood Pressure", 
            DIABP = "Diastolic Blood Pressure") |> put()

put("Statistics lookup format")                
stat_fmt <- c(MEANSTD = "Mean (SD)",
              MEDIAN = "Median",
              Q1Q3 = "Q1 - Q3",
              MINMAX = "Min - Max") |> put()


put("Create format catalog")
fc <- fcat(MEAN = "%.1f", 
           STD = "(%.2f)", 
           MEDIAN = "%.1f",
           Q1 = "%.1f",
           Q3 = "%.1f",
           MIN = "%.1f", 
           MAX = "%.1f")

# Prepare final data frame ------------------------------------------------

sep("Prepare final data")

put("Calculate statistics and prepare final data frame")
proc_means(prep, var = VSSTRESN, class = VSTESTCD, by = GRP,
           stats = v(mean, std, median, q1, q3, min, max),
           options = v(notype, nofreq, nway)) |> 
  datastep(format = fc, 
           drop = v(MEAN, STD, Q1, Q3, MIN, MAX, VAR),
           rename = c("CLASS" = "VAR"),
           {
             MEANSTD <- fapply2(MEAN, STD)
             Q1Q3 <- fapply2(Q1, Q3, sep = " - ")
             MINMAX <- fapply2(MIN, MAX, sep = " - ")
           }) |> 
  proc_transpose(id = BY, var = v(MEANSTD, MEDIAN, Q1Q3, MINMAX),
                 by = VAR, name = "LABEL") -> final

put("Prepare factor for sorting")
final$VAR <- factor(final$VAR, names(vs_fmt))


put("Final sort")
proc_sort(final, by = VAR) -> final


# Create Report -----------------------------------------------------------
sep("Create Report")


# Define table object
tbl <- create_table(final) |> 
  spanning_header(A_BASE, A_TRT, "Placebo", n = pop_A) |> 
  spanning_header(O_BASE, O_TRT, "Treated", n = pop_O) |> 
  column_defaults(width = 1.25, align = "center") |> 
  stub(c(VAR, LABEL), width = 2.5) |> 
  define(VAR, "Vital Sign", format = vs_fmt, 
         blank_after = TRUE, dedupe = TRUE, label_row = TRUE) |> 
  define(LABEL, indent = .25, format = stat_fmt) |> 
  define(A_BASE, "Baseline") |> 
  define(A_TRT, "After Treatment") |> 
  define(O_BASE, "Baseline") |> 
  define(O_TRT, "After Treatment")


# Define report object
rpt <- create_report(file.path(tmp, "./output/example2.rtf"), output_type = "RTF", 
                     font = "Times", font_size = 12) |> 
  page_header("Sponsor: Company", "Study: ABC") |> 
  titles("Table 4.0", "Selected Vital Signs", bold = TRUE) |> 
  add_content(tbl, align = "center") |> 
  page_footer(Sys.time(), "CONFIDENTIAL", "Page [pg] of [tpg]")

# Write report to file system  
res <- write_report(rpt) 


# Clean Up ----------------------------------------------------------------
sep("Clean Up")

# Close log
log_close()

# View report
# file.show(res$file_path)

# View log
# file.show(lf)

Log

Here is the log from the above program:

=========================================================================
Log Path: C:/Users/dbosa/AppData/Local/Temp/RtmpiipZo8/log/example1.log
Program Path: C:/packages/Testing/Example2.R
Working Directory: C:/packages/Testing
User Name: dbosa
R Version: 4.3.1 (2023-06-16 ucrt)
Machine: SOCRATES x86-64
Operating System: Windows 10 x64 build 22621
Base Packages: stats graphics grDevices utils datasets methods base Other
Packages: tidylog_1.0.2 procs_1.0.3 reporter_1.4.2 libr_1.2.8 logr_1.3.5
fmtr_1.6.1 common_1.1.0 sassy_1.2.1
Log Start Time: 2023-11-17 13:03:47.835721
=========================================================================

=========================================================================
Prepare Data
=========================================================================

# library 'sdtm': 8 items
- attributes: csv not loaded
- path: C:/Users/dbosa/AppData/Local/R/win-library/4.3/libr/extdata
- items:
  Name Extension Rows Cols     Size        LastModified
1   AE       csv  150   27  88.5 Kb 2023-09-09 22:45:51
2   DA       csv 3587   18 528.2 Kb 2023-09-09 22:45:51
3   DM       csv   87   24  45.5 Kb 2023-09-09 22:45:51
4   DS       csv  174    9  34.1 Kb 2023-09-09 22:45:51
5   EX       csv   84   11  26.4 Kb 2023-09-09 22:45:51
6   IE       csv    2   14  13.4 Kb 2023-09-09 22:45:51
7   SV       csv  685   10  70.3 Kb 2023-09-09 22:45:51
8   VS       csv 3358   17 467.4 Kb 2023-09-09 22:45:51

Join and prepare data

Join DM to VS and keep desired columns

datastep: columns decreased from 24 to 7

# A tibble: 2,768 × 7
   USUBJID    VSTESTCD VISIT   VISITNUM VSSTRESN ARM   VSBLFL
   <chr>      <chr>    <chr>      <dbl>    <dbl> <chr> <chr> 
 1 ABC-01-049 DIABP    DAY 1          1       76 ARM D Y     
 2 ABC-01-049 DIABP    WEEK 2         2       66 ARM D <NA>  
 3 ABC-01-049 DIABP    WEEK 4         4       84 ARM D <NA>  
 4 ABC-01-049 DIABP    WEEK 6         6       68 ARM D <NA>  
 5 ABC-01-049 DIABP    WEEK 8         8       80 ARM D <NA>  
 6 ABC-01-049 DIABP    WEEK 12       12       70 ARM D <NA>  
 7 ABC-01-049 DIABP    WEEK 16       16       70 ARM D <NA>  
 8 ABC-01-049 PULSE    DAY 1          1       84 ARM D Y     
 9 ABC-01-049 PULSE    WEEK 2         2       84 ARM D <NA>  
10 ABC-01-049 PULSE    WEEK 4         4       76 ARM D <NA>  
# ℹ 2,758 more rows
# ℹ Use `print(n = ...)` to see more rows

Sort by variables

proc_sort: input data set 2768 rows and 7 columns
           by: USUBJID VSTESTCD VISITNUM
           keep: USUBJID VSTESTCD VISIT VISITNUM VSSTRESN ARM VSBLFL
           order: a a a
           output data set 2768 rows and 7 columns

# A tibble: 2,768 × 7
   USUBJID    VSTESTCD VISIT   VISITNUM VSSTRESN ARM   VSBLFL
   <chr>      <chr>    <chr>      <dbl>    <dbl> <chr> <chr> 
 1 ABC-01-049 DIABP    DAY 1          1       76 ARM D Y     
 2 ABC-01-049 DIABP    WEEK 2         2       66 ARM D <NA>  
 3 ABC-01-049 DIABP    WEEK 4         4       84 ARM D <NA>  
 4 ABC-01-049 DIABP    WEEK 6         6       68 ARM D <NA>  
 5 ABC-01-049 DIABP    WEEK 8         8       80 ARM D <NA>  
 6 ABC-01-049 DIABP    WEEK 12       12       70 ARM D <NA>  
 7 ABC-01-049 DIABP    WEEK 16       16       70 ARM D <NA>  
 8 ABC-01-049 PULSE    DAY 1          1       84 ARM D Y     
 9 ABC-01-049 PULSE    WEEK 2         2       84 ARM D <NA>  
10 ABC-01-049 PULSE    WEEK 4         4       76 ARM D <NA>  
# ℹ 2,758 more rows
# ℹ Use `print(n = ...)` to see more rows

Differentiate baseline from treated vital signs

datastep: columns increased from 7 to 9

# A tibble: 2,768 × 9
   USUBJID    VSTESTCD VISIT   VISITNUM VSSTRESN ARM   VSBLFL GRP    BSTRESN
   <chr>      <chr>    <chr>      <dbl>    <dbl> <chr> <chr>  <chr>    <dbl>
 1 ABC-01-049 DIABP    DAY 1          1       76 ARM D Y      O_BASE      76
 2 ABC-01-049 DIABP    WEEK 2         2       66 ARM D <NA>   O_TRT       76
 3 ABC-01-049 DIABP    WEEK 4         4       84 ARM D <NA>   O_TRT       76
 4 ABC-01-049 DIABP    WEEK 6         6       68 ARM D <NA>   O_TRT       76
 5 ABC-01-049 DIABP    WEEK 8         8       80 ARM D <NA>   O_TRT       76
 6 ABC-01-049 DIABP    WEEK 12       12       70 ARM D <NA>   O_TRT       76
 7 ABC-01-049 DIABP    WEEK 16       16       70 ARM D <NA>   O_TRT       76
 8 ABC-01-049 PULSE    DAY 1          1       84 ARM D Y      O_BASE      84
 9 ABC-01-049 PULSE    WEEK 2         2       84 ARM D <NA>   O_TRT       84
10 ABC-01-049 PULSE    WEEK 4         4       76 ARM D <NA>   O_TRT       84
# ℹ 2,758 more rows
# ℹ Use `print(n = ...)` to see more rows

Get population counts

proc_sort: input data set 20 rows and 2 columns
           by: USUBJID GRP
           keep: USUBJID GRP
           order: a
           options: nodupkey
           output data set 20 rows and 2 columns

# A tibble: 20 × 2
   USUBJID    GRP   
   <chr>      <chr> 
 1 ABC-01-051 A_BASE
 2 ABC-01-056 A_BASE
 3 ABC-02-034 A_BASE
 4 ABC-02-038 A_BASE
 5 ABC-02-109 A_BASE
 6 ABC-03-002 A_BASE
 7 ABC-03-006 A_BASE
 8 ABC-03-091 A_BASE
 9 ABC-04-075 A_BASE
10 ABC-04-080 A_BASE
11 ABC-04-126 A_BASE
12 ABC-06-068 A_BASE
13 ABC-06-069 A_BASE
14 ABC-07-012 A_BASE
15 ABC-07-016 A_BASE
16 ABC-08-104 A_BASE
17 ABC-08-106 A_BASE
18 ABC-09-020 A_BASE
19 ABC-09-023 A_BASE
20 ABC-09-137 A_BASE

proc_freq: input data set 20 rows and 2 columns
           tables: GRP
           output: long
           view: TRUE
           output: 1 datasets

# A tibble: 1 × 3
  VAR   STAT  A_BASE
  <chr> <chr>  <dbl>
1 GRP   CNT       20

proc_sort: input data set 67 rows and 2 columns
           by: USUBJID GRP
           keep: USUBJID GRP
           order: a
           options: nodupkey
           output data set 67 rows and 2 columns

# A tibble: 67 × 2
   USUBJID    GRP   
   <chr>      <chr> 
 1 ABC-01-049 O_BASE
 2 ABC-01-050 O_BASE
 3 ABC-01-052 O_BASE
 4 ABC-01-053 O_BASE
 5 ABC-01-054 O_BASE
 6 ABC-01-055 O_BASE
 7 ABC-01-113 O_BASE
 8 ABC-01-114 O_BASE
 9 ABC-02-033 O_BASE
10 ABC-02-035 O_BASE
# ℹ 57 more rows
# ℹ Use `print(n = ...)` to see more rows

proc_freq: input data set 67 rows and 2 columns
           tables: GRP
           output: long
           view: TRUE
           output: 1 datasets

# A tibble: 1 × 3
  VAR   STAT  O_BASE
  <chr> <chr>  <dbl>
1 GRP   CNT       67

=========================================================================
Prepare formats
=========================================================================

Vital sign lookup format

Pulse
Temperature °C
Respirations/min
Systolic Blood Pressure
Diastolic Blood Pressure

Statistics lookup format

Mean (SD)
Median
Q1 - Q3
Min - Max

Create format catalog

# A format catalog: 7 formats
- $MEAN: type S, "%.1f"
- $STD: type S, "(%.2f)"
- $MEDIAN: type S, "%.1f"
- $Q1: type S, "%.1f"
- $Q3: type S, "%.1f"
- $MIN: type S, "%.1f"
- $MAX: type S, "%.1f"

=========================================================================
Prepare final data
=========================================================================

Calculate statistics and prepare final data frame

proc_means: input data set 2768 rows and 9 columns
            by: GRP
            class: VSTESTCD
            var: VSSTRESN
            stats: mean std median q1 q3 min max
            view: TRUE
            output: 1 datasets

   CLASS     BY      VAR      MEAN        STD MEDIAN    Q1    Q3   MIN   MAX
1  DIABP A_BASE VSSTRESN  77.15000 10.6537614   78.5  70.0  83.0  54.0  96.0
2  PULSE A_BASE VSSTRESN  72.75000 10.0518393   72.0  66.0  76.0  60.0 103.0
3   RESP A_BASE VSSTRESN  16.50000  2.5026302   16.0  16.0  18.0  12.0  20.0
4  SYSBP A_BASE VSSTRESN 128.15000 16.7120347  125.5 117.0 140.0  98.0 161.0
5   TEMP A_BASE VSSTRESN  36.52105  0.4171050   36.4  36.2  36.9  35.9  37.4
6  DIABP  A_TRT VSSTRESN  77.08547  8.1182772   78.0  72.0  82.0  50.0  98.0
7  PULSE  A_TRT VSSTRESN  74.58120 10.2201958   74.0  67.0  80.0  54.0 102.0
8   RESP  A_TRT VSSTRESN  15.80342  3.4372185   16.0  16.0  18.0   8.0  24.0
9  SYSBP  A_TRT VSSTRESN 130.43590 17.6304911  126.0 118.0 140.0  95.0 184.0
10  TEMP  A_TRT VSSTRESN  36.45431  0.2857157   36.5  36.2  36.6  35.8  37.3
11 DIABP O_BASE VSSTRESN  77.48485  8.1415221   78.0  70.0  82.0  61.0  95.0
12 PULSE O_BASE VSSTRESN  73.55224  9.7051745   72.0  67.0  80.0  52.0 100.0
13  RESP O_BASE VSSTRESN  15.97015  3.1477272   16.0  15.0  18.0   8.0  22.0
14 SYSBP O_BASE VSSTRESN 126.68182 15.4672449  123.0 116.0 138.0 100.0 164.0
15  TEMP O_BASE VSSTRESN  36.42239  0.5376213   36.4  36.2  36.6  35.3  39.8
16 DIABP  O_TRT VSSTRESN  76.94286  9.2058374   78.0  70.0  84.0  50.0 104.0
17 PULSE  O_TRT VSSTRESN  74.02279  9.8592694   72.0  66.0  80.0  50.0 109.0
18  RESP  O_TRT VSSTRESN  15.44444  3.4312291   16.0  12.0  18.0   8.0  24.0
19 SYSBP  O_TRT VSSTRESN 125.90571 15.1715962  124.0 115.0 135.0  82.0 180.0
20  TEMP  O_TRT VSSTRESN  36.31057  0.3903231   36.3  36.1  36.5  34.4  38.2

datastep: columns decreased from 10 to 6

     VAR     BY MEDIAN       MEANSTD          Q1Q3        MINMAX
1  DIABP A_BASE   78.5  77.2 (10.65)   70.0 - 83.0   54.0 - 96.0
2  PULSE A_BASE   72.0  72.8 (10.05)   66.0 - 76.0  60.0 - 103.0
3   RESP A_BASE   16.0   16.5 (2.50)   16.0 - 18.0   12.0 - 20.0
4  SYSBP A_BASE  125.5 128.2 (16.71) 117.0 - 140.0  98.0 - 161.0
5   TEMP A_BASE   36.4   36.5 (0.42)   36.2 - 36.9   35.9 - 37.4
6  DIABP  A_TRT   78.0   77.1 (8.12)   72.0 - 82.0   50.0 - 98.0
7  PULSE  A_TRT   74.0  74.6 (10.22)   67.0 - 80.0  54.0 - 102.0
8   RESP  A_TRT   16.0   15.8 (3.44)   16.0 - 18.0    8.0 - 24.0
9  SYSBP  A_TRT  126.0 130.4 (17.63) 118.0 - 140.0  95.0 - 184.0
10  TEMP  A_TRT   36.5   36.5 (0.29)   36.2 - 36.6   35.8 - 37.3
11 DIABP O_BASE   78.0   77.5 (8.14)   70.0 - 82.0   61.0 - 95.0
12 PULSE O_BASE   72.0   73.6 (9.71)   67.0 - 80.0  52.0 - 100.0
13  RESP O_BASE   16.0   16.0 (3.15)   15.0 - 18.0    8.0 - 22.0
14 SYSBP O_BASE  123.0 126.7 (15.47) 116.0 - 138.0 100.0 - 164.0
15  TEMP O_BASE   36.4   36.4 (0.54)   36.2 - 36.6   35.3 - 39.8
16 DIABP  O_TRT   78.0   76.9 (9.21)   70.0 - 84.0  50.0 - 104.0
17 PULSE  O_TRT   72.0   74.0 (9.86)   66.0 - 80.0  50.0 - 109.0
18  RESP  O_TRT   16.0   15.4 (3.43)   12.0 - 18.0    8.0 - 24.0
19 SYSBP  O_TRT  124.0 125.9 (15.17) 115.0 - 135.0  82.0 - 180.0
20  TEMP  O_TRT   36.3   36.3 (0.39)   36.1 - 36.5   34.4 - 38.2

proc_transpose: input data set 20 rows and 6 columns
                by: VAR
                var: MEANSTD MEDIAN Q1Q3 MINMAX
                id: BY
                name: LABEL
                output dataset 20 rows and 6 columns

     VAR   LABEL        A_BASE         A_TRT        O_BASE         O_TRT
1  DIABP MEANSTD  77.2 (10.65)   77.1 (8.12)   77.5 (8.14)   76.9 (9.21)
2  DIABP  MEDIAN          78.5          78.0          78.0          78.0
3  DIABP    Q1Q3   70.0 - 83.0   72.0 - 82.0   70.0 - 82.0   70.0 - 84.0
4  DIABP  MINMAX   54.0 - 96.0   50.0 - 98.0   61.0 - 95.0  50.0 - 104.0
5  PULSE MEANSTD  72.8 (10.05)  74.6 (10.22)   73.6 (9.71)   74.0 (9.86)
6  PULSE  MEDIAN            72            74            72            72
7  PULSE    Q1Q3   66.0 - 76.0   67.0 - 80.0   67.0 - 80.0   66.0 - 80.0
8  PULSE  MINMAX  60.0 - 103.0  54.0 - 102.0  52.0 - 100.0  50.0 - 109.0
9   RESP MEANSTD   16.5 (2.50)   15.8 (3.44)   16.0 (3.15)   15.4 (3.43)
10  RESP  MEDIAN            16            16            16            16
11  RESP    Q1Q3   16.0 - 18.0   16.0 - 18.0   15.0 - 18.0   12.0 - 18.0
12  RESP  MINMAX   12.0 - 20.0    8.0 - 24.0    8.0 - 22.0    8.0 - 24.0
13 SYSBP MEANSTD 128.2 (16.71) 130.4 (17.63) 126.7 (15.47) 125.9 (15.17)
14 SYSBP  MEDIAN         125.5         126.0         123.0         124.0
15 SYSBP    Q1Q3 117.0 - 140.0 118.0 - 140.0 116.0 - 138.0 115.0 - 135.0
16 SYSBP  MINMAX  98.0 - 161.0  95.0 - 184.0 100.0 - 164.0  82.0 - 180.0
17  TEMP MEANSTD   36.5 (0.42)   36.5 (0.29)   36.4 (0.54)   36.3 (0.39)
18  TEMP  MEDIAN          36.4          36.5          36.4          36.3
19  TEMP    Q1Q3   36.2 - 36.9   36.2 - 36.6   36.2 - 36.6   36.1 - 36.5
20  TEMP  MINMAX   35.9 - 37.4   35.8 - 37.3   35.3 - 39.8   34.4 - 38.2

Prepare factor for sorting

Final sort

proc_sort: input data set 20 rows and 6 columns
           by: VAR
           keep: VAR LABEL A_BASE A_TRT O_BASE O_TRT
           order: a
           output data set 20 rows and 6 columns

     VAR   LABEL        A_BASE         A_TRT        O_BASE         O_TRT
5  PULSE MEANSTD  72.8 (10.05)  74.6 (10.22)   73.6 (9.71)   74.0 (9.86)
6  PULSE  MEDIAN            72            74            72            72
7  PULSE    Q1Q3   66.0 - 76.0   67.0 - 80.0   67.0 - 80.0   66.0 - 80.0
8  PULSE  MINMAX  60.0 - 103.0  54.0 - 102.0  52.0 - 100.0  50.0 - 109.0
17  TEMP MEANSTD   36.5 (0.42)   36.5 (0.29)   36.4 (0.54)   36.3 (0.39)
18  TEMP  MEDIAN          36.4          36.5          36.4          36.3
19  TEMP    Q1Q3   36.2 - 36.9   36.2 - 36.6   36.2 - 36.6   36.1 - 36.5
20  TEMP  MINMAX   35.9 - 37.4   35.8 - 37.3   35.3 - 39.8   34.4 - 38.2
9   RESP MEANSTD   16.5 (2.50)   15.8 (3.44)   16.0 (3.15)   15.4 (3.43)
10  RESP  MEDIAN            16            16            16            16
11  RESP    Q1Q3   16.0 - 18.0   16.0 - 18.0   15.0 - 18.0   12.0 - 18.0
12  RESP  MINMAX   12.0 - 20.0    8.0 - 24.0    8.0 - 22.0    8.0 - 24.0
13 SYSBP MEANSTD 128.2 (16.71) 130.4 (17.63) 126.7 (15.47) 125.9 (15.17)
14 SYSBP  MEDIAN         125.5         126.0         123.0         124.0
15 SYSBP    Q1Q3 117.0 - 140.0 118.0 - 140.0 116.0 - 138.0 115.0 - 135.0
16 SYSBP  MINMAX  98.0 - 161.0  95.0 - 184.0 100.0 - 164.0  82.0 - 180.0
1  DIABP MEANSTD  77.2 (10.65)   77.1 (8.12)   77.5 (8.14)   76.9 (9.21)
2  DIABP  MEDIAN          78.5          78.0          78.0          78.0
3  DIABP    Q1Q3   70.0 - 83.0   72.0 - 82.0   70.0 - 82.0   70.0 - 84.0
4  DIABP  MINMAX   54.0 - 96.0   50.0 - 98.0   61.0 - 95.0  50.0 - 104.0

=========================================================================
Create Report
=========================================================================

# A report specification: 1 pages
- file_path: 'C:\Users\dbosa\AppData\Local\Temp\RtmpiipZo8/./output/example2.rtf'
- output_type: RTF
- units: inches
- orientation: landscape
- margins: top 0.5 bottom 0.5 left 1 right 1
- line size/count: 9/38
- page_header: left=Sponsor: Company right=Study: ABC
- title 1: 'Table 4.0'
- title 2: 'Selected Vital Signs'
- page_footer: left=2023-11-17 13:03:53.809731 center=CONFIDENTIAL right=Page [pg] of [tpg]
- content: 
# A table specification:
- data: data.frame 'final' 20 rows 6 cols
- show_cols: all
- use_attributes: all
- spanning_header: from='A_BASE' to='A_TRT' 'Placebo' level=1 
- spanning_header: from='O_BASE' to='O_TRT' 'Treated' level=1 
- stub: VAR LABEL width=2.5 align='left' 
- define: VAR 'Vital Sign' dedupe='TRUE' 
- define: LABEL 
- define: A_BASE 'Baseline' 
- define: A_TRT 'After Treatment' 
- define: O_BASE 'Baseline' 
- define: O_TRT 'After Treatment' 

=========================================================================
Clean Up
=========================================================================

=========================================================================
Log End Time: 2023-11-17 13:03:54.012811
Log Elapsed Time: 0 00:00:06
=========================================================================

Output

And here is the output:

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.