---
title: "Example 11: Subject Listing"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Example 11: Subject Listing}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
Here is an example of a subject listing using the **sassy** system of
functions. The example shows demographics for each patient and vital
signs by visit.
## Program
Note the following about this example:
* The example makes extensive use of the `datastep` function from the **libr** package.
* A label row has been created that spans the width of the page, and contains
a selection of demographic attributes of each subject.
* Titles have been placed in the document header using the `header = TRUE` parameter.
* Footnotes have been placed in the document footer using the `footer = TRUE` parameter.
* The `supsc` and `symbol` functions from the **common** package have been used
to create superscripts and symbols in the titles, footnotes, and body of the report.
* A variable "PG" has been created to force a page break every three subjects.
* The program produces both RTF and PDF outputs from the same report object.
```{r eval=FALSE, echo=TRUE}
library(sassy)
# Prepare Log -------------------------------------------------------------
options("logr.autolog" = TRUE,
"logr.on" = TRUE,
"logr.notes" = FALSE)
# Get path to temp directory
tmp <- tempdir()
# Get sample data directory
dir <- system.file("extdata", package = "sassy")
# Open log
lf <- log_open(file.path(tmp, "example11.log"))
# Prepare formats ---------------------------------------------------------
sep("Prepare formats")
fc <- fcat(SEX = c("M" = "Male", "F" = "Female"),
AGE = "%d Years",
RACE = value(condition(x == "WHITE", "White"),
condition(x == "BLACK OR AFRICAN AMERICAN", "Black or African American"),
condition(x == "ASIAN OR PACIFIC ISLANDER", "Asian or Pacific Islander"),
condition(TRUE, "Other")),
WEIGHT = "%6.2f kg",
EAR = c("L" = "Left", "R" = "Right"),
DOSE = "%4.2fug",
ETHNIC = value(condition(x == "NOT HISPANIC OR LATINO", "Not Hispanic or Latino"),
condition(x == "HISPANIC OR LATINO", "Hispanic or Latino"),
condition(TRUE, "Unknown")),
ARMT = value(condition(x == "ARM A", "Placebo"),
condition(x == "ARM B", "Drug 50mg"),
condition(x == "ARM C", "Drug 100mg"),
condition(x == "ARM D", "Competitor"),
condition(TRUE, "Not Treated/Screen Failure")),
UNITS = value(condition(x == "BEATS/MIN", "bpm"),
condition(x == "BREATHS/MIN", "brths/min"),
condition(x == "C", symbol("degC")),
condition(x == "mmHg", "")),
VISIT = value(condition(x == "DAY 1", "Day 1"),
condition(x == "WEEK 2", "Week 2"),
condition(x == "WEEK 4", "Week 4"),
condition(x == "WEEK 6", "Week 6"),
condition(x == "WEEK 8", "Week 8"),
condition(x == "WEEK 12", "Week 12"),
condition(x == "WEEK 16", "Week 16"),
condition(TRUE, "Early Termination"))
)
# Prepare Data ------------------------------------------------------------
sep("Prepare Data")
libname(sdtm, dir, "csv")
lib_load(sdtm)
put("Format desired vital signs")
datastep(sdtm.VS,
keep = v(USUBJID, VSTESTCD, VSCOMB, VISITNUM, VISIT),
where = expression(VSTESTCD != 'HEIGHT' & VISITNUM > 0),
{
if (VSORRESU == "C")
VSCOMB <- paste0(VSORRES, fapply(VSORRESU, fc$UNITS))
else
VSCOMB <- paste(VSORRES, fapply(VSORRESU, fc$UNITS))
}) -> vso
put("Pivot vitals signs")
proc_transpose(vso, id = VSTESTCD, var = VSCOMB,
by = v(USUBJID, VISITNUM, VISIT)) |>
proc_sort(by = v(USUBJID, VISITNUM)) -> vsot
put("Assign and apply formats")
formats(sdtm.DM) <- fc
dmf <- fdata(sdtm.DM) |> put()
put("Prepare final data for reporting")
datastep(dmf, format = fc,
by = USUBJID,
retain = list(PTCNT = 0, PG = 1),
merge = vsot, merge_by = USUBJID,
{
# Combine subject info into label row
BASELINE <- paste0(USUBJID, ", Site=", SITEID,
", Age=", AGE, ", Sex=", SEX, ", Race=", RACE,
", Ethnic=", ETHNIC)
# Deal with non-recorded blood pressure
if (is.na(DIABP))
DIABP <- "-"
if (is.na(SYSBP))
SYSBP <- "-"
# Combine distolic and systolic in one column
BP <- paste0(trimws(DIABP), "/", trimws(SYSBP), " mmHg")
# Format treatment group
if (first.)
TREATMENT <- fapply(ARM, fc$ARMT)
else
TREATMENT <- ""
# Count up patients
if (first.) {
PTCNT <- PTCNT + 1
}
# Create paging variable with 3 patients per page
if (PTCNT == 4) {
PTCNT <- 1
PG <- PG + 1
}
}) -> final
# Create report -----------------------------------------------------------
sep("Create and Print Report")
tbl <- create_table(final, show_cols = "none",
width = 9, first_row_blank = FALSE,
header_bold = TRUE) |>
column_defaults(from = "VISIT", to = "BP", width = 1.25) |>
stub(v(BASELINE, TREATMENT), label = "Subject/Treatment") |>
define(BASELINE, label_row = TRUE) |>
define(TREATMENT) |>
define(VISIT, label = "Visit") |>
define(TEMP, label = "Temperature") |>
define(PULSE, label = "Pulse") |>
define(RESP, label = "Respirations") |>
define(BP, label = "Blood Pressure") |>
define(USUBJID, blank_after = TRUE, visible = FALSE) |>
define(PG, page_break = TRUE, visible = FALSE)
rpt <- create_report(file.path(tmp, "example11"), font = "Courier", font_size = 9) |>
add_content(tbl) |>
set_margins(top = 1, bottom = 1) |>
page_header("Program:" %p% Sys.path(), right = "Draft", width = 7) |>
titles( "Study: ABC", "Appendix 10.2.6.1.2.1", "Source: DM, VS",
columns = 3, header = TRUE, blank_row = "none") |>
titles("Subject Listing with Vital Signs by Visit{supsc('1')}",
"All Randomized Patients", align = "center", header = TRUE, blank_row = "below") |>
footnotes("{supsc('1')} Baseline through completion of study or early termination.",
"Values flagged with {symbol('dagger')} were excluded from the by-visit " %p%
"analysis in tables showing the qualitative test results.",
blank_row = "none", footer = TRUE) |>
page_footer("Date: " %p% toupper(fapply(Sys.time(), "%d%b%Y %H:%M:%S")),
"Archytas", "Page [pg] of [tpg]")
# Generate both RTF and PDF with same report object
res1 <- write_report(rpt, output_type = "RTF")
res2 <- write_report(rpt, output_type = "PDF")
# Uncomment to show reports
# file.show(res1$modified_path)
# file.show(res2$modified_path)
# Uncomment to show log
# file.show(lf)
# Clean Up ----------------------------------------------------------------
lib_unload(sdtm)
log_close()
```
## Output
Here is an image of the first page of the RTF report produced by the
above subject listing:
## Log
Here is the log produced by the above subject listing:
```
=========================================================================
Log Path: C:/Users/dbosa/AppData/Local/Temp/RtmpkNnsUE/log/example12.log
Program Path: C:/packages/Testing/procs/ProcsCombinedFigure.R
Working Directory: C:/packages/Testing/procs
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 ggplot2_3.4.2 patchwork_1.1.3 procs_1.0.3
reporter_1.4.1 libr_1.2.8 fmtr_1.5.9 logr_1.3.4 common_1.0.8 sassy_1.1.0
Log Start Time: 2023-09-06 21:06:40.53712
=========================================================================
=========================================================================
Prepare Data
=========================================================================
Define data library
# library 'sdtm': 7 items
- attributes: csv not loaded
- path: C:/Users/dbosa/AppData/Local/R/win-library/4.3/sassy/extdata
- items:
Name Extension Rows Cols Size LastModified
1 AE csv 150 27 88.5 Kb 2023-08-07 17:51:40
2 DM csv 87 24 45.5 Kb 2023-08-07 17:51:40
3 DS csv 174 9 34.1 Kb 2023-08-07 17:51:40
4 EX csv 84 11 26.4 Kb 2023-08-07 17:51:40
5 IE csv 2 14 13.4 Kb 2023-08-07 17:51:40
6 SV csv 685 10 70.3 Kb 2023-08-07 17:51:40
7 VS csv 3358 17 467.4 Kb 2023-08-07 17:51:40
Load data into workspace
lib_load: library 'sdtm' loaded
Prepare format
# A user-defined format: 4 conditions
Name Type Expression Label Order
1 obj U x >= 18 & x <= 24 18 to 24 NA
2 obj U x >= 25 & x <= 44 25 to 44 NA
3 obj U x >= 45 & x <= 64 45 to 64 NA
4 obj U x >= 65 >= 65 NA
Prepare data
datastep: columns decreased from 24 to 5
# A tibble: 85 × 5
USUBJID SEX AGE ARM AGECAT
1 ABC-01-049 M 39 ARM D 25 to 44
2 ABC-01-050 M 47 ARM B 45 to 64
3 ABC-01-051 M 34 ARM A 25 to 44
4 ABC-01-052 F 45 ARM C 45 to 64
5 ABC-01-053 F 26 ARM B 25 to 44
6 ABC-01-054 M 44 ARM D 25 to 44
7 ABC-01-055 F 47 ARM C 45 to 64
8 ABC-01-056 M 31 ARM A 25 to 44
9 ABC-01-113 M 74 ARM D >= 65
10 ABC-01-114 F 72 ARM B >= 65
# ℹ 75 more rows
# ℹ Use `print(n = ...)` to see more rows
Convert agecat to factor it will sort correctly
Split by ARM
=========================================================================
Create Plots
=========================================================================
Create plot for ARM A
Create plot for ARM B
Create plot for ARM C
Create plot for ARM D
Combine 4 plots into 1 using patchwork
=========================================================================
Create and print report
=========================================================================
# A report specification: 1 pages
- file_path: 'C:\Users\dbosa\AppData\Local\Temp\RtmpkNnsUE/output/example12.rtf'
- output_type: RTF
- units: inches
- orientation: landscape
- margins: top 1 bottom 1 left 1 right 1
- line size/count: 9/36
- page_header: left=Sponsor: Company right=Study: ABC
- footnote 1: 'Program: DM_Figure.R'
- page_footer: left=Date Produced: 06Sep23 21:06 center= right=Page [pg] of [tpg]
- content:
# A plot specification:
- height: 4.5
- width: 7
- title 1: 'Figure 3.2'
- title 2: 'Distribution of Subjects by Treatment Group'
lib_sync: synchronized data in library 'sdtm'
lib_unload: library 'sdtm' unloaded
=========================================================================
Log End Time: 2023-09-06 21:06:43.938549
Log Elapsed Time: 0 00:00:03
=========================================================================
```
Next: [Example 12: Combined Figure](sassy-pfigure.html)