Here is another example of a complete program that demonstrates several of the key functions in the libr package.
library(tidyverse)
library(sassy)
library(common)
options("logr.autolog" = TRUE,
"logr.notes" = FALSE)
# Get temp location for log and report output
<- tempdir()
tmp
# Open log
<- log_open(file.path(tmp, "example1.log"))
lf
# Prepare Data ------------------------------------------------------------
sep("Prepare Data")
# Get path to sample data
<- system.file("extdata", package = "libr")
pkg
# Create libname for csv data
libname(sdtm, pkg, "csv", quiet = TRUE)
# Load data into workspace
lib_load(sdtm)
put("Join and prepare data")
<- sdtm.DM %>%
prep left_join(sdtm.VS, by = c("USUBJID" = "USUBJID")) %>%
select(USUBJID, VSTESTCD, VISIT, VISITNUM, VSSTRESN, ARM, VSBLFL) %>%
filter(VSTESTCD %in% c("PULSE", "RESP", "TEMP", "DIABP", "SYSBP"),
!(VISIT == "SCREENING" & VSBLFL != "Y")) %>%
arrange(USUBJID, VSTESTCD, VISITNUM) %>%
group_by(USUBJID, VSTESTCD) %>%
datastep(retain = list(BSTRESN = 0), {
# Combine treatment groups
# And distingish baseline time points
if (ARM == "ARM A") {
if (VSBLFL %eq% "Y") {
<- "A_BASE"
GRP else {
} <- "A_TRT"
GRP
}else {
} if (VSBLFL %eq% "Y") {
<- "O_BASE"
GRP else {
} <- "O_TRT"
GRP
}
}
# Populate baseline value
if (first.)
= VSSTRESN
BSTRESN
%>%
}) ungroup() %>%
put()
put("Get population counts")
<- prep %>% select(USUBJID, GRP) %>% filter(GRP == "A_BASE") %>%
pop_A distinct() %>% count() %>% deframe() %>% put()
<- prep %>% select(USUBJID, GRP) %>% filter(GRP == "O_BASE") %>%
pop_O distinct() %>% count() %>% deframe() %>% put()
put("Prepare final data frame")
<- prep %>%
final select(VSTESTCD, GRP, VSSTRESN, BSTRESN) %>%
group_by(VSTESTCD, GRP) %>%
summarize(Mean = fmt_mean_sd(VSSTRESN),
Median = fmt_median(VSSTRESN),
Quantiles = fmt_quantile_range(VSSTRESN),
Range = fmt_range(VSSTRESN)) %>%
ungroup() %>%
pivot_longer(cols = c(Mean, Median, Quantiles, Range),
names_to = "stats",
values_to = "values") %>%
pivot_wider(names_from = GRP,
values_from = values) %>%
put()
# Create Formats ----------------------------------------------------------
sep("Create formats")
# Vital sign lookup format
<- c(PULSE = "Pulse",
vs_fmt TEMP = "Temperature °C",
RESP = "Respirations/min",
SYSBP = "Systolic Blood Pressure",
DIABP = "Diastolic Blood Pressure") %>%
put()
# Statistics user-defined format
<- value(condition(x == "Mean", "Mean (SD)"),
stat_fmt condition(x == "Quantiles", "Q1 - Q3")) %>%
put()
# Create Report -----------------------------------------------------------
sep("Create Report")
# Apply sort
<- final %>%
final mutate(VSTESTCD = factor(VSTESTCD, levels = names(vs_fmt))) %>%
arrange(VSTESTCD)
# Define table object
<- create_table(final) %>%
tbl 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(VSTESTCD, stats), width = 2.5) %>%
define(VSTESTCD, "Vital Sign", format = vs_fmt,
blank_after = TRUE, dedupe = TRUE, label_row = TRUE) %>%
define(stats, 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
<- create_report(file.path(tmp, "./output/example1.rtf"), output_type = "RTF",
rpt 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
<- write_report(rpt)
res
# Clean Up ----------------------------------------------------------------
sep("Clean Up")
# Unload data from workspace
lib_unload(sdtm)
# Close log
log_close()
# View log
writeLines(readLines(lf, encoding = "UTF-8"))
# View report
# file.show(res$file_path)
Here is the log from the above program:
=========================================================================
Log Path: C:/Users/dbosa/AppData/Local/Temp/RtmpwLpEIV/log/example2.log
Program Path: C:\packages\Testing\libr_example2.R
Working Directory: C:/packages/Testing
User Name: dbosa
R Version: 4.1.2 (2021-11-01)
Machine: SOCRATES x86-64
Operating System: Windows 10 x64 build 19041
Base Packages: stats graphics grDevices utils datasets methods base
Other Packages: tidylog_1.0.2 reporter_1.2.6 libr_1.2.1 fmtr_1.5.4 logr_1.2.7
sassy_1.0.5 forcats_0.5.1 stringr_1.4.0 dplyr_1.0.7 purrr_0.3.4
readr_2.0.2 tidyr_1.1.4 tibble_3.1.5 ggplot2_3.3.5 tidyverse_1.3.1
Log Start Time: 2021-11-20 23:15:59
=========================================================================
=========================================================================
Prepare Data
=========================================================================
# library 'sdtm': 8 items
- attributes: csv not loaded
- path: C:/Users/dbosa/Documents/R/win-library/4.1/libr/extdata
- items:
Name Extension Rows Cols Size LastModified
1 AE csv 150 27 88.3 Kb 2021-10-08 15:02:15
2 DA csv 3587 18 528.1 Kb 2021-10-08 15:02:15
3 DM csv 87 24 45.4 Kb 2021-10-08 15:02:15
4 DS csv 174 9 33.9 Kb 2021-10-08 15:02:15
5 EX csv 84 11 26.2 Kb 2021-10-08 15:02:15
6 IE csv 2 14 13.2 Kb 2021-10-08 15:02:15
7 SV csv 685 10 70.2 Kb 2021-10-08 15:02:15
8 VS csv 3358 17 467.3 Kb 2021-10-08 15:02:15
lib_load: library 'sdtm' loaded
Join and prepare data
left_join: added 18 columns (STUDYID.x, DOMAIN.x, STUDYID.y, DOMAIN.y, VSSEQ, <U+0085>)
> rows only in x 0
> rows only in y ( 0)
> matched rows 3,358 (includes duplicates)
> =======
> rows total 3,358
select: dropped 33 variables (STUDYID.x, DOMAIN.x, SUBJID, RFSTDTC, RFENDTC, <U+0085>)
filter: removed 590 rows (18%), 2,768 rows remaining
group_by: 2 grouping variables (USUBJID, VSTESTCD)
datastep: columns increased from 7 to 9
ungroup: no grouping variables
# A tibble: 2,768 x 9
USUBJID VSTESTCD VISIT VISITNUM VSSTRESN ARM VSBLFL BSTRESN GRP
<chr> <chr> <chr> <dbl> <dbl> <chr> <chr> <dbl> <chr>
1 ABC-01-049 DIABP DAY 1 1 76 ARM D Y 76 O_BASE
2 ABC-01-049 DIABP WEEK 2 2 66 ARM D <NA> 76 O_TRT
3 ABC-01-049 DIABP WEEK 4 4 84 ARM D <NA> 76 O_TRT
4 ABC-01-049 DIABP WEEK 6 6 68 ARM D <NA> 76 O_TRT
5 ABC-01-049 DIABP WEEK 8 8 80 ARM D <NA> 76 O_TRT
6 ABC-01-049 DIABP WEEK 12 12 70 ARM D <NA> 76 O_TRT
7 ABC-01-049 DIABP WEEK 16 16 70 ARM D <NA> 76 O_TRT
8 ABC-01-049 PULSE DAY 1 1 84 ARM D Y 84 O_BASE
9 ABC-01-049 PULSE WEEK 2 2 84 ARM D <NA> 84 O_TRT
10 ABC-01-049 PULSE WEEK 4 4 76 ARM D <NA> 84 O_TRT
# ... with 2,758 more rows
Get population counts
select: dropped 7 variables (VSTESTCD, VISIT, VISITNUM, VSSTRESN, ARM, <U+0085>)
filter: removed 2,669 rows (96%), 99 rows remaining
distinct: removed 79 rows (80%), 20 rows remaining
count: now one row and one column, ungrouped
[1] 20
select: dropped 7 variables (VSTESTCD, VISIT, VISITNUM, VSSTRESN, ARM, <U+0085>)
filter: removed 2,435 rows (88%), 333 rows remaining
distinct: removed 266 rows (80%), 67 rows remaining
count: now one row and one column, ungrouped
[1] 67
Prepare final data frame
select: dropped 5 variables (USUBJID, VISIT, VISITNUM, ARM, VSBLFL)
group_by: 2 grouping variables (VSTESTCD, GRP)
summarize: now 20 rows and 6 columns, one group variable remaining (VSTESTCD)
ungroup: no grouping variables
pivot_longer: reorganized (Mean, Median, Quantiles, Range) into (stats, values) [was 20x6, now 80x4]
pivot_wider: reorganized (GRP, values) into (A_BASE, A_TRT, O_BASE, O_TRT) [was 80x4, now 20x6]
# A tibble: 20 x 6
VSTESTCD stats A_BASE A_TRT O_BASE O_TRT
<chr> <chr> <chr> <chr> <chr> <chr>
1 DIABP Mean 77.2 (10.7) 77.1 (8.1) 77.5 (8.1) 76.9 (9.2)
2 DIABP Median 78.5 78.0 78.0 78.0
3 DIABP Quantiles 70.0 - 82.5 72.0 - 82.0 70.2 - 82.0 70.0 - 83.8
4 DIABP Range 54 - 96 50 - 98 61 - 95 50 - 104
5 PULSE Mean 72.8 (10.1) 74.6 (10.2) 73.6 (9.7) 74.0 (9.9)
6 PULSE Median 72.0 74.0 72.0 72.0
7 PULSE Quantiles 66.0 - 76.0 67.0 - 80.0 67.5 - 79.5 66.0 - 80.0
8 PULSE Range 60 - 103 54 - 102 52 - 100 50 - 109
9 RESP Mean 16.5 (2.5) 15.8 (3.4) 16.0 (3.1) 15.4 (3.4)
10 RESP Median 16.0 16.0 16.0 16.0
11 RESP Quantiles 16.0 - 18.0 16.0 - 18.0 15.5 - 18.0 12.0 - 18.0
12 RESP Range 12 - 20 8 - 24 8 - 22 8 - 24
13 SYSBP Mean 128.2 (16.7) 130.4 (17.6) 126.7 (15.5) 125.9 (15.2)
14 SYSBP Median 125.5 126.0 123.0 124.0
15 SYSBP Quantiles 117.5 - 140.0 118.0 - 140.0 116.0 - 138.0 115.2 - 135~
16 SYSBP Range 98 - 161 95 - 184 100 - 164 82 - 180
17 TEMP Mean 36.5 (0.4) 36.5 (0.3) 36.4 (0.5) 36.3 (0.4)
18 TEMP Median 36.4 36.5 36.4 36.3
19 TEMP Quantiles 36.2 - 36.9 36.2 - 36.6 36.2 - 36.6 36.1 - 36.5
20 TEMP Range 35.9 - 37.4 35.8 - 37.3 35.3 - 39.8 34.4 - 38.2
=========================================================================
Create formats
=========================================================================
Pulse
Temperature <U+00B0>C
Respirations/min
Systolic Blood Pressure
Diastolic Blood Pressure
# A user-defined format: 2 conditions
Name Type Expression Label Order
1 obj U x == "Mean" Mean (SD) NA
2 obj U x == "Quantiles" Q1 - Q3 NA
=========================================================================
Create Report
=========================================================================
mutate: converted 'VSTESTCD' from character to factor (0 new NA)
# A report specification: 1 pages
- file_path: 'C:\Users\dbosa\AppData\Local\Temp\RtmpwLpEIV/./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=2021-11-20 23:16:06 center=CONFIDENTIAL right=Page [pg] of [tpg]
- content:
# A table specification:
- data: tibble '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: VSTESTCD stats width=2.5 align='left'
- define: VSTESTCD 'Vital Sign' dedupe='TRUE'
- define: stats
- define: A_BASE 'Baseline'
- define: A_TRT 'After Treatment'
- define: O_BASE 'Baseline'
- define: O_TRT 'After Treatment'
=========================================================================
Clean Up
=========================================================================
lib_sync: synchronized data in library 'sdtm'
lib_unload: library 'sdtm' unloaded
=========================================================================
Log End Time: 2021-11-20 23:16:08
Log Elapsed Time: 0 00:00:09
=========================================================================
And here is the output: