--- 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)