1 Introduction

This package clinUtils contains functionalities to facilitate the analysis of clinical datasets in R.

library(clinUtils)

# packages required for the examples in the vignette
library(ggplot2)
library(pander)
library(htmltools)
library(plyr)

Please note that the interactive outputs (table/visualization) in this vignette are only included if Pandoc is available (pre-requisite for R Markdown).

2 Data pre-processing

2.1 Data import

The haven R package enables to load SAS datasets in sas7bdat and xpt formats.

The function loadDataADaMSDTM is a wrapper to import multiple SAS datasets in sas7bdat or xpt format at once. It returns a list of dataset (once by domain). The variable labels are combined across datasets and available in a dedicated attribute.

pathExampleDatasets <- list.files(
    path = system.file("extdata", "cdiscpilot01", "SDTM", package = "clinUtils"), 
    pattern = "*.xpt", 
    full.names = TRUE
)

data <- loadDataADaMSDTM(files = pathExampleDatasets)
# A list is returned, each separated file is accessible via data$[fileName]
pander(head(data$DM, 2))
Table continues below
STUDYID DOMAIN USUBJID SUBJID RFSTDTC RFENDTC
CDISCPILOT01 DM 01-701-1148 1148 2013-08-23 2014-02-20
CDISCPILOT01 DM 01-701-1192 1192 2012-07-22 2013-01-20
Table continues below
RFXSTDTC RFXENDTC RFICDTC RFPENDTC DTHDTC DTHFL SITEID
2013-08-23 2014-02-20 2014-02-20T15:07 701
2012-07-22 2013-01-20 2013-01-20T15:47 701
Table continues below
AGE AGEU SEX RACE ETHNIC ARMCD
57 YEARS M WHITE NOT HISPANIC OR LATINO Xan_Hi
80 YEARS F WHITE NOT HISPANIC OR LATINO Xan_Lo
Table continues below
ARM ACTARMCD ACTARM COUNTRY DMDTC
Xanomeline High Dose Xan_Hi Xanomeline High Dose USA 2013-08-14
Xanomeline Low Dose Xan_Lo Xanomeline Low Dose USA 2012-07-08
DMDY DATASET
-9 DM
-14 DM
pander(head(data$LB, 2))
Table continues below
STUDYID DOMAIN USUBJID LBSEQ LBTESTCD LBTEST LBCAT
CDISCPILOT01 LB 01-701-1148 1 ALB Albumin CHEMISTRY
CDISCPILOT01 LB 01-701-1148 38 ALB Albumin CHEMISTRY
Table continues below
LBORRES LBORRESU LBORNRLO LBORNRHI LBSTRESC LBSTRESN LBSTRESU
4.1 g/dL 3.3 4.9 41 41 g/L
3.9 g/dL 3.3 4.9 39 39 g/L
Table continues below
LBSTNRLO LBSTNRHI LBNRIND LBBLFL VISITNUM VISIT VISITDY
33 49 NORMAL Y 1 SCREENING 1 -7
33 49 NORMAL 4 WEEK 2 14
LBDTC LBDY DATASET
2013-08-14T13:04 -9 LB
2013-09-05T15:43 14 LB
pander(head(data$AE, 2))
Table continues below
STUDYID DOMAIN USUBJID AESEQ AESPID
CDISCPILOT01 AE 01-701-1148 10 E27
CDISCPILOT01 AE 01-701-1148 1 E20
Table continues below
AETERM AELLT AELLTCD
ACTINIC KERATOSIS ACTINIC KERATOSIS NA
APPLICATION SITE ERYTHEMA APPLICATION SITE REDNESS NA
Table continues below
AEDECOD AEPTCD AEHLT AEHLTCD AEHLGT AEHLGTCD
ACTINIC KERATOSIS NA HLT_0609 NA HLGT_0490 NA
APPLICATION SITE ERYTHEMA NA HLT_0617 NA HLGT_0152 NA
Table continues below
AEBODSYS AEBDSYCD AESOC
SKIN AND SUBCUTANEOUS TISSUE DISORDERS NA SKIN AND SUBCUTANEOUS TISSUE DISORDERS
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS NA GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS
Table continues below
AESOCCD AESEV AESER AEACN AEREL AEOUT
NA MILD N NONE NOT RECOVERED/NOT RESOLVED
NA MILD N PROBABLE NOT RECOVERED/NOT RESOLVED
Table continues below
AESCAN AESCONG AESDISAB AESDTH AESHOSP AESLIFE AESOD AEDTC
N N N N N N N 2014-02-20
N N N N N N N 2013-09-05
AESTDTC AEENDTC AESTDY AEENDY DATASET
2014-02-12 174 NA AE
2013-08-25 3 NA AE
# Access labels for all variables
labelVars <- attr(data, "labelVars")
head(labelVars)
##                               STUDYID                                DOMAIN 
##                    "Study Identifier"                 "Domain Abbreviation" 
##                               USUBJID                                 AESEQ 
##           "Unique Subject Identifier"                     "Sequence Number" 
##                                AESPID                                AETERM 
##          "Sponsor-Defined Identifier" "Reported Term for the Adverse Event"
# Access label for a particular variable: 
labelVars["USUBJID"]
##                     USUBJID 
## "Unique Subject Identifier"

2.2 Example datasets

To demonstrate the functionalities of this package, a subset of the datasets from the CDISC Pilot 01 study is available in the package as dataset.

2.2.1 ADaM

# load data
data(dataADaMCDISCP01)
dataADaM <- dataADaMCDISCP01
names(dataADaM)
## [1] "ADAE"     "ADCM"     "ADLBC"    "ADPP"     "ADQSADAS" "ADQSCIBC" "ADQSNPIX"
## [8] "ADSL"     "ADVS"
pander(head(dataADaM$ADSL, 2))
Table continues below
STUDYID USUBJID SUBJID SITEID SITEGR1 ARM
CDISCPILOT01 01-701-1148 1148 701 701 Xanomeline High Dose
CDISCPILOT01 01-701-1192 1192 701 701 Xanomeline Low Dose
Table continues below
TRT01P TRT01PN TRT01A TRT01AN TRTSDT
Xanomeline High Dose 81 Xanomeline High Dose 81 2013-08-23
Xanomeline Low Dose 54 Xanomeline Low Dose 54 2012-07-22
Table continues below
TRTEDT TRTDUR AVGDD CUMDOSE AGE AGEGR1 AGEGR1N AGEU RACE
2014-02-20 182 77.1 14040 57 <65 1 YEARS WHITE
2013-01-20 183 54 9882 80 65-80 2 YEARS WHITE
Table continues below
RACEN SEX ETHNIC SAFFL ITTFL EFFFL COMP8FL
1 M NOT HISPANIC OR LATINO Y Y Y Y
1 F NOT HISPANIC OR LATINO Y Y Y Y
Table continues below
COMP16FL COMP24FL DISCONFL DSRAEFL DTHFL BMIBL BMIBLGR1 HEIGHTBL
Y Y 28.3 25-<30 175.3
Y Y 27.8 25-<30 151.1
Table continues below
WEIGHTBL EDUCLVL DISONSDT DURDIS DURDSGR1 VISIT1DT RFSTDTC
87.1 15 2010-12-12 32.1 >=12 2013-08-14 2013-08-23
63.5 12 2009-03-15 39.8 >=12 2012-07-08 2012-07-22
RFENDTC VISNUMEN RFENDT DCDECOD DCREASCD MMSETOT DATASET
2014-02-20 12 2014-02-20 COMPLETED Completed 21 ADSL
2013-01-20 12 2013-01-20 COMPLETED Completed 23 ADSL
pander(head(dataADaM$ADLBC, 2))
Table continues below
STUDYID SUBJID USUBJID TRTP TRTPN
CDISCPILOT01 1148 01-701-1148 Xanomeline High Dose 81
CDISCPILOT01 1148 01-701-1148 Xanomeline High Dose 81
Table continues below
TRTA TRTAN TRTSDT TRTEDT AGE AGEGR1
Xanomeline High Dose 81 2013-08-23 2014-02-20 57 <65
Xanomeline High Dose 81 2013-08-23 2014-02-20 57 <65
Table continues below
AGEGR1N RACE RACEN SEX COMP24FL DSRAEFL SAFFL AVISIT
1 WHITE 1 M Y Y Baseline
1 WHITE 1 M Y Y Baseline
Table continues below
AVISITN ADY ADT VISIT VISITNUM PARAM
0 -9 2013-08-14 SCREENING 1 1 Sodium (mmol/L)
0 -9 2013-08-14 SCREENING 1 1 Potassium (mmol/L)
Table continues below
PARAMCD PARAMN PARCAT1 AVAL BASE CHG A1LO A1HI R2A1LO R2A1HI
SODIUM 18 CHEM 139 139 NA 132 147 1.053 0.9456
K 19 CHEM 4 4 NA 3.4 5.4 1.176 0.7407
Table continues below
BR2A1LO BR2A1HI ANL01FL ALBTRVAL ANRIND BNRIND ABLFL AENTMTFL
1.053 0.9456 81.5 N N Y
1.176 0.7407 4.1 N N Y
LBSEQ LBNRIND LBSTRESN DATASET
26 NORMAL 139 ADLBC
19 NORMAL 4 ADLBC
pander(head(dataADaM$ADAE, 2))
Table continues below
STUDYID SITEID USUBJID TRTA TRTAN AGE
CDISCPILOT01 701 01-701-1148 Xanomeline High Dose 81 57
CDISCPILOT01 701 01-701-1148 Xanomeline High Dose 81 57
Table continues below
AGEGR1 AGEGR1N RACE RACEN SEX SAFFL TRTSDT TRTEDT
<65 1 WHITE 1 M Y 2013-08-23 2014-02-20
<65 1 WHITE 1 M Y 2013-08-23 2014-02-20
Table continues below
ASTDT ASTDTF ASTDY AENDT AENDY ADURN ADURU
2013-08-25 3 NA NA NA
2013-08-25 3 NA NA NA
Table continues below
AETERM AELLT AELLTCD
APPLICATION SITE ERYTHEMA APPLICATION SITE REDNESS NA
APPLICATION SITE PRURITUS APPLICATION SITE ITCHING NA
Table continues below
AEDECOD AEPTCD AEHLT AEHLTCD AEHLGT AEHLGTCD
APPLICATION SITE ERYTHEMA NA HLT_0617 NA HLGT_0152 NA
APPLICATION SITE PRURITUS NA HLT_0317 NA HLGT_0338 NA
Table continues below
AEBODSYS AESOC AESOCCD
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS NA
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS NA
Table continues below
AESEV AESER AESCAN AESCONG AESDISAB AESDTH AESHOSP AESLIFE
MILD N N N N N N N
MILD N N N N N N N
Table continues below
AESOD AEREL AEACN AEOUT AESEQ TRTEMFL
N PROBABLE NOT RECOVERED/NOT RESOLVED 1 Y
N PROBABLE NOT RECOVERED/NOT RESOLVED 2 Y
Table continues below
AOCCFL AOCCSFL AOCCPFL AOCC02FL AOCC03FL AOCC04FL
Y Y Y
Y
CQ01NAM AOCC01FL DATASET
DERMATOLOGIC EVENTS Y ADAE
DERMATOLOGIC EVENTS ADAE
# and variable labels
labelVarsADaM <- attr(dataADaM, "labelVars")
head(labelVarsADaM)
##                     STUDYID                      SITEID 
##          "Study Identifier"     "Study Site Identifier" 
##                     USUBJID                        TRTA 
## "Unique Subject Identifier"          "Actual Treatment" 
##                       TRTAN                         AGE 
##      "Actual Treatment (N)"                       "Age"

2.2.2 SDTM

# load data
data(dataSDTMCDISCP01)
dataSDTM <- dataSDTMCDISCP01
names(dataSDTM)
##  [1] "AE"     "CM"     "DM"     "DS"     "EX"     "LB"     "MH"     "QS"    
##  [9] "SUPPDM" "SV"     "VS"
pander(head(dataSDTM$DM, 2))
Table continues below
STUDYID DOMAIN USUBJID SUBJID RFSTDTC RFENDTC
CDISCPILOT01 DM 01-701-1148 1148 2013-08-23 2014-02-20
CDISCPILOT01 DM 01-701-1192 1192 2012-07-22 2013-01-20
Table continues below
RFXSTDTC RFXENDTC RFICDTC RFPENDTC DTHDTC DTHFL SITEID
2013-08-23 2014-02-20 2014-02-20T15:07 701
2012-07-22 2013-01-20 2013-01-20T15:47 701
Table continues below
AGE AGEU SEX RACE ETHNIC ARMCD
57 YEARS M WHITE NOT HISPANIC OR LATINO Xan_Hi
80 YEARS F WHITE NOT HISPANIC OR LATINO Xan_Lo
Table continues below
ARM ACTARMCD ACTARM COUNTRY DMDTC
Xanomeline High Dose Xan_Hi Xanomeline High Dose USA 2013-08-14
Xanomeline Low Dose Xan_Lo Xanomeline Low Dose USA 2012-07-08
DMDY DATASET
-9 DM
-14 DM
pander(head(dataSDTM$LB, 2))
Table continues below
STUDYID DOMAIN USUBJID LBSEQ LBTESTCD LBTEST LBCAT
CDISCPILOT01 LB 01-701-1148 1 ALB Albumin CHEMISTRY
CDISCPILOT01 LB 01-701-1148 38 ALB Albumin CHEMISTRY
Table continues below
LBORRES LBORRESU LBORNRLO LBORNRHI LBSTRESC LBSTRESN LBSTRESU
4.1 g/dL 3.3 4.9 41 41 g/L
3.9 g/dL 3.3 4.9 39 39 g/L
Table continues below
LBSTNRLO LBSTNRHI LBNRIND LBBLFL VISITNUM VISIT VISITDY
33 49 NORMAL Y 1 SCREENING 1 -7
33 49 NORMAL 4 WEEK 2 14
LBDTC LBDY DATASET
2013-08-14T13:04 -9 LB
2013-09-05T15:43 14 LB
pander(head(dataSDTM$AE, 2))
Table continues below
STUDYID DOMAIN USUBJID AESEQ AESPID
CDISCPILOT01 AE 01-701-1148 10 E27
CDISCPILOT01 AE 01-701-1148 1 E20
Table continues below
AETERM AELLT AELLTCD
ACTINIC KERATOSIS ACTINIC KERATOSIS NA
APPLICATION SITE ERYTHEMA APPLICATION SITE REDNESS NA
Table continues below
AEDECOD AEPTCD AEHLT AEHLTCD AEHLGT AEHLGTCD
ACTINIC KERATOSIS NA HLT_0609 NA HLGT_0490 NA
APPLICATION SITE ERYTHEMA NA HLT_0617 NA HLGT_0152 NA
Table continues below
AEBODSYS AEBDSYCD AESOC
SKIN AND SUBCUTANEOUS TISSUE DISORDERS NA SKIN AND SUBCUTANEOUS TISSUE DISORDERS
GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS NA GENERAL DISORDERS AND ADMINISTRATION SITE CONDITIONS
Table continues below
AESOCCD AESEV AESER AEACN AEREL AEOUT
NA MILD N NONE NOT RECOVERED/NOT RESOLVED
NA MILD N PROBABLE NOT RECOVERED/NOT RESOLVED
Table continues below
AESCAN AESCONG AESDISAB AESDTH AESHOSP AESLIFE AESOD AEDTC
N N N N N N N 2014-02-20
N N N N N N N 2013-09-05
AESTDTC AEENDTC AESTDY AEENDY DATASET
2014-02-12 174 NA AE
2013-08-25 3 NA AE
# and variable labels
labelVarsSDTM <- attr(dataSDTM, "labelVars")
head(labelVarsSDTM)
##                               STUDYID                                DOMAIN 
##                    "Study Identifier"                 "Domain Abbreviation" 
##                               USUBJID                                 AESEQ 
##           "Unique Subject Identifier"                     "Sequence Number" 
##                                AESPID                                AETERM 
##          "Sponsor-Defined Identifier" "Reported Term for the Adverse Event"

2.3 Variable labels

Typical data stored in SAS contains the label for each variable available in the dataset.

The function getLabelVar extracts the label for the specified variable(s), ensuring that the variable code is used if no label is specified.

# variable label is extracted from 'labelVars'
getLabelVar(var = "AEDECOD", labelVars = labelVars)
##                   AEDECOD 
## "Dictionary-Derived Term"

This function also supports extraction of variable labels from the ‘label’ attribute of the column, as in the tibble as returned by the read_sas/read_xpt functions from the haven package.

2.4 Get parameter label from its parameter code

In typical basic CDISC dataset (a.k.a BDS: Basic Data Structure), as laboratory, vital signs datasets, variables are available to store parameter and parameter code (PARAM/PARAMCD in ADaM).

The function getLabelParamcd get the label from specific parameter(s) code.

Variables with parameter name and code are based by default on standard ADaM CDISC parameter variables (PARAM/PARAMCD).

# For ADaM dataset
getLabelParamcd(paramcd = "CHOL", data = dataADaM$ADLB)
##                   CHOL 
## "Cholesterol (mmol/L)"
getLabelParamcd(paramcd = "BILI", data = dataADaM$ADLB)
##                 BILI 
## "Bilirubin (umol/L)"
# For SDTM dataset
getLabelParamcd(paramcd = "CHOL", data = dataSDTM$LB, paramcdVar = "LBTESTCD", paramVar = "LBTEST")
##          CHOL 
## "Cholesterol"
getLabelParamcd(paramcd = "BILI", data = dataSDTM$LB, paramcdVar = "LBTESTCD", paramVar = "LBTEST")
##        BILI 
## "Bilirubin"

3 Visualizations

3.1 Palette for CDISC variables

Palette for typical CDISC-variable(s) are available in the package.

3.1.1 Normal reference range indicators

Meaningful colors and symbols for a Normal Reference Range Indicator CDISC variable (-NRIND) are extracted via the colorPaletteNRIND and shapePaletteNRIND respectively:

print(colorPaletteNRIND)
##      LOW   NORMAL     HIGH ABNORMAL  UNKNOWN       NA 
## "orange" "green4" "orange"    "red"   "grey"   "grey"
print(shapePaletteNRIND)
##      LOW   NORMAL     HIGH ABNORMAL  UNKNOWN       NA 
##       25       21       24       18        3        3
plot(
    x = seq_along(colorPaletteNRIND),
    col = colorPaletteNRIND, 
    bg = colorPaletteNRIND, 
    pch = shapePaletteNRIND
)
text(
    x = seq_along(colorPaletteNRIND),
    labels = names(colorPaletteNRIND), pos = 3
)
title("Palette for CDISC normal reference range indicator")

The getPaletteCDISC function extracts such palette for a specified variable.

This retains only the categories available in the variable, and ensures that extra symbols are extracted in case non standard categories are available in the data.

dataPlot <- subset(dataSDTM$LB, LBTEST == "Leukocytes")

colorPalette <- getPaletteCDISC(x = dataPlot$LBNRIND, var = "NRIND", type = "color")
print(colorPalette)
##      LOW   NORMAL     HIGH 
## "orange" "green4" "orange"
shapePalette <- getPaletteCDISC(x = dataPlot$LBNRIND, var = "NRIND", type = "shape")
print(shapePalette)
##    LOW NORMAL   HIGH 
##     25     21     24
# visualize profile over time
gg <- ggplot(data = dataPlot) +
    geom_point(aes(x = LBDY, y = LBSTRESN, 
            color = LBNRIND, fill = LBNRIND, shape = LBNRIND)) +
    ggtitle("Evolution of Leukocytes actual value over time")
print(gg)

# use 'standard' symbols/colors
# ('limits' is only required if the categories are not already ordered in LBNRIND)
gg + 
    scale_color_manual(values = colorPalette, limits = names(colorPalette)) +
    scale_fill_manual(values = colorPalette, limits = names(colorPalette)) +
    scale_shape_manual(values = shapePalette, limits = names(colorPalette))

3.2 Get default palettes

Default palettes for visualizations are included in the package.

Palettes can be extracted based on a variable, or number of elements.

These packages are included for consistency across the entire suite of R packages.

dataPlot <- subset(dataADaM$ADLB, PARAMCD == "CHOL")

# extract palettes
colorPalette <- getColorPalette(x = dataPlot$USUBJID)
shapePalette <- getShapePalette(x = dataPlot$USUBJID)
linetypePalette <- getLinetypePalette(x = dataPlot$USUBJID)

# create the plot
ggplot(data = dataPlot, aes(x = ADY, y = CHG, color = USUBJID)) +
    geom_point(aes(shape = USUBJID)) +
    geom_line(aes(linetype = USUBJID, group = USUBJID)) +
    scale_color_manual(values = colorPalette) +
    scale_shape_manual(values = shapePalette) +
    scale_linetype_manual(values = linetypePalette) +
    labs(x = "Relative day", y = "Change from baseline",
        title = "Profile plot of cholesterol change from baseline") 
## Warning: Removed 7 rows containing missing values or values outside the scale range
## (`geom_point()`).
## Warning: Removed 7 rows containing missing values or values outside the scale range
## (`geom_line()`).

Custom palettes can be specified via the palette parameter.

4 Tables

4.1 Rounding

In R, numbers are by default rounded to the even digit for rounding off a 5.

Numbers can be rounded based on the ‘rounding up’ strategy for rounding off a 5 with roundHalfUp & roundHalfUpTextFormat. This is useful when statistics created with the SAS software should be reproduced in R.

# round up
roundHalfUp(c(0.45, 0.55), 1)
## [1] 0.5 0.6
# versus R default:
round(c(0.45, 0.55), 1)
## [1] 0.4 0.6

4.2 Display data in an interactive table

The getClinDT function is an utility function, based on the the DT package, with sensitive default settings and extra common functionalities of interest for data in clinical trials, as listing or summary tables of descriptive statistics.

There are built-in functionalities to expand row variable(s) to display patient-specific information or include bar visualization.

dataTEAE <- subset(dataADaM$ADAE, SAFFL == "Y" & TRTEMFL == "Y")

# set column names to labels
labelVarsTEAE <- getLabelVar(
    var = colnames(dataTEAE), 
    labelVars = labelVarsADaM
)
colnamesTEAE <- setNames(names(labelVarsTEAE), labelVarsTEAE)

dataTEAE <- dataTEAE[order(dataTEAE$AESOC), ]
getClinDT(
    dataTEAE, 
    colnames = colnamesTEAE, 
    rowGroupVar = c("AESOC"),
    barVar = "AGE",
    barRange = c(0, 100),
    caption = "Listing of treatment-emergent adverse events on the safety analysis set"
)

4.3 Comparison of tables

In clinical trials, datasets are typically delivered in successive batches, depending on the patient recruitment and the different milestones of the study.

The changes between successive data deliveries can be compared with the compareTables function.

# Build example dataset with treatment-emergent adverse events
# of multiple batches

varsListing <- c("USUBJID", "AESOC", "AEDECOD", "ASTDT", "AESEV", "AEOUT")
dataTEAEListing <- dataTEAE[, varsListing]

# simulate removal of observations in new batch
dataTEAENew <- dataTEAE[-sample.int(n = nrow(dataTEAEListing), size = 3), ]

# simulate addition of observations in new batch
dataTEAEOld <- dataTEAE[-sample.int(n = nrow(dataTEAEListing), size = 3), ]

# simulate change of observations       
dataTEAEOld[seq_len(2), "AESEV"] <- "SEVERE"

refVars <- c("USUBJID", "AESOC", "AEDECOD", "ASTDT")
tableComparison <- compareTables(
    newData = dataTEAENew, 
    oldData = dataTEAEOld, 
    referenceVars = refVars,
    changeableVars = setdiff(colnames(dataTEAEListing), refVars),
    # parameters passed to datatable
    colnames = setNames(names(labelVarsADaM), labelVarsADaM)
)

The new, old datasets with change information, or the difference between datasets are extracted. See documentation of outputType parameter for further details.

The table below highlight the differences between the datasets in an interactive table.

tableComparison$`table-comparison-interactive`

5 Reporting

5.1 Include list of objects in a Rmarkdown document

Dedicated functions: knitPrintListPlots and knitPrintListObjects are available to include a list of plots/objects in a Rmarkdown document, enabling to specify any (knitr) chunk options and title header for each object.

This function inserts each object in a separated code chunk, such as independent option (as figure dimensions) can be specified for each object.

Please note that this function should be used within a chunk having the option: results = 'asis'.

5.1.1 Static visualizations (ggplot2)

For example, by default in knitr the options to specify figure dimensions should be the same for all plots generated from the same chunk (fig.height/fig.width).

Plots can be included with different specified dimension with: knitPrintListPlots.

dataLB <- subset(dataSDTM$LB, 
    LBTESTCD %in% c("ALB", "ALT", "CHOL", "HCT", "KETONES", "PH")
)
dataLB$ACTARM <- dataSDTM$DM$ACTARM[match(dataLB$USUBJID, dataSDTM$DM$USUBJID)]

# create plots:
listPlotsLB <- plyr::dlply(dataLB, "LBCAT", function(data)
      ggplot(data = data) +
          geom_histogram(aes(fill = LBNRIND, x = ACTARM), stat = "count", position = "dodge") +
          facet_wrap(~LBTEST) +
          theme(axis.text.x = element_text(angle = -45, hjust = 0))
)
# n2mfrow: extract default dimensions for a specified number of plots
figDim <- plyr::dlply(dataLB, "LBCAT", function(data) 
      n2mfrow(length(unique(data$LBTESTCD)))
)
knitPrintListPlots(
    plotsList = listPlotsLB, 
    generalLabel = "lab-hist-static",
    type = "ggplot2",
    # set caption for each figure
    fig.cap = paste("Barplot of", tolower(names(listPlotsLB)), "measurements"),
    # specify different dimensions
    fig.width = sapply(figDim, "[[", 1) * 2 + 1, # 3 in for each plot + 1 in for the legend
    fig.height = sapply(figDim, "[[", 2) * 2 + 2, # 3 in for each plot + 2 for x-axis labels
    # include title before each visualization
    titles = simpleCap(tolower(names(listPlotsLB))),
    titleLevel = 4
)

5.1.1.1 Chemistry

Barplot of chemistry measurements

Barplot of chemistry measurements

5.1.1.2 Hematology

Barplot of hematology measurements

Barplot of hematology measurements

5.1.1.3 Urinalysis

Barplot of urinalysis measurements

Barplot of urinalysis measurements

5.1.2 Interactive visualizations (plotly)

A list of interactive figures is created with the plotly package:

library(plotly)
listPlotsInteractiveLB <- sapply(listPlotsLB, function(ggplot)
      ggplotly(ggplot) %>% partial_bundle()
    , simplify = FALSE)

5.1.2.1 htmltools::tagList

A list of interactive figures can be included within a Rmarkdown document with the tagList function of the htmltools package.

tagListArgs <- mapply(list,
    # section header
    lapply(names(listPlotsInteractiveLB), htmltools::h4),
    # interactive plots
    listPlotsInteractiveLB,
    SIMPLIFY = FALSE
)
tagListArgs <- unlist(tagListArgs, recursive = FALSE)
do.call(htmltools::tagList, tagListArgs)

CHEMISTRY

HEMATOLOGY

URINALYSIS

5.1.2.2 Inclusion in a separated chunk

The function knitPrintListPlots with the type set to ‘plotly’ enables to include additionally e.g. a caption or a title.

knitPrintListPlots(
    plotsList = listPlotsInteractiveLB, 
    generalLabel = "lab-hist-interactive",
    type = "plotly",
    # include title before each visualization
    titles = simpleCap(tolower(names(listPlotsInteractiveLB))),
    titleLevel = 5
)
5.1.2.2.1 Chemistry
5.1.2.2.2 Hematology
5.1.2.2.3 Urinalysis

5.1.3 Tables (flextable)

The flextable package enables to create highly customizable tables for Word/PowerPoint format (among others).

The function knitPrintListObjects enables to include a list of flextable objects within a single chunk.

Please note that the following chunk option should be used: results = 'asis'.

library(flextable)
listFtLB <- plyr::dlply(dataLB, "LBCAT", function(dataParcat){
      flextable::flextable(data = head(dataParcat))
    })

knitPrintListObjects(
    xList = listFtLB, 
    generalLabel = "lab-listing-ft",
    titles = simpleCap(tolower(names(listFtLB))),
    # different alignment for each table
    ft.align = c("center", "right", "left"),
    titleLevel = 4
)

5.1.3.1 Chemistry

STUDYID

DOMAIN

USUBJID

LBSEQ

LBTESTCD

LBTEST

LBCAT

LBORRES

LBORRESU

LBORNRLO

LBORNRHI

LBSTRESC

LBSTRESN

LBSTRESU

LBSTNRLO

LBSTNRHI

LBNRIND

LBBLFL

VISITNUM

VISIT

VISITDY

LBDTC

LBDY

DATASET

ACTARM

CDISCPILOT01

LB

01-701-1148

1

ALB

Albumin

CHEMISTRY

4.1

g/dL

3.3

4.9

41

41

g/L

33

49

NORMAL

Y

1

SCREENING 1

-7

2013-08-14T13:04

-9

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

38

ALB

Albumin

CHEMISTRY

3.9

g/dL

3.3

4.9

39

39

g/L

33

49

NORMAL

4

WEEK 2

14

2013-09-05T15:43

14

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

73

ALB

Albumin

CHEMISTRY

3.8

g/dL

3.3

4.9

38

38

g/L

33

49

NORMAL

5

WEEK 4

28

2013-09-19T14:30

28

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

103

ALB

Albumin

CHEMISTRY

4.1

g/dL

3.3

4.9

41

41

g/L

33

49

NORMAL

7

WEEK 6

42

2013-10-03T12:17

42

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

133

ALB

Albumin

CHEMISTRY

3.8

g/dL

3.3

4.9

38

38

g/L

33

49

NORMAL

8

WEEK 8

56

2013-10-18T15:46

57

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

163

ALB

Albumin

CHEMISTRY

3.8

g/dL

3.3

4.9

38

38

g/L

33

49

NORMAL

9

WEEK 12

84

2013-11-17T10:59

87

LB

Xanomeline High Dose

5.1.3.2 Hematology

STUDYID

DOMAIN

USUBJID

LBSEQ

LBTESTCD

LBTEST

LBCAT

LBORRES

LBORRESU

LBORNRLO

LBORNRHI

LBSTRESC

LBSTRESN

LBSTRESU

LBSTNRLO

LBSTNRHI

LBNRIND

LBBLFL

VISITNUM

VISIT

VISITDY

LBDTC

LBDY

DATASET

ACTARM

CDISCPILOT01

LB

01-701-1148

17

HCT

Hematocrit

HEMATOLOGY

49.0

%

39

54

0.49

0.49

1

0.39

0.54

NORMAL

Y

1

SCREENING 1

-7

2013-08-14T13:04

-9

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

54

HCT

Hematocrit

HEMATOLOGY

43.0

%

39

54

0.43

0.43

1

0.39

0.54

NORMAL

4

WEEK 2

14

2013-09-05T15:43

14

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

88

HCT

Hematocrit

HEMATOLOGY

44.0

%

39

54

0.44

0.44

1

0.39

0.54

NORMAL

5

WEEK 4

28

2013-09-19T14:30

28

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

118

HCT

Hematocrit

HEMATOLOGY

44.0

%

39

54

0.44

0.44

1

0.39

0.54

NORMAL

7

WEEK 6

42

2013-10-03T12:17

42

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

148

HCT

Hematocrit

HEMATOLOGY

44.0

%

39

54

0.44

0.44

1

0.39

0.54

NORMAL

8

WEEK 8

56

2013-10-18T15:46

57

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

179

HCT

Hematocrit

HEMATOLOGY

45.0

%

39

54

0.45

0.45

1

0.39

0.54

NORMAL

9

WEEK 12

84

2013-11-17T10:59

87

LB

Xanomeline High Dose

5.1.3.3 Urinalysis

STUDYID

DOMAIN

USUBJID

LBSEQ

LBTESTCD

LBTEST

LBCAT

LBORRES

LBORRESU

LBORNRLO

LBORNRHI

LBSTRESC

LBSTRESN

LBSTRESU

LBSTNRLO

LBSTNRHI

LBNRIND

LBBLFL

VISITNUM

VISIT

VISITDY

LBDTC

LBDY

DATASET

ACTARM

CDISCPILOT01

LB

01-701-1148

20

KETONES

Ketones

URINALYSIS

0

NO UNITS

0

0

NORMAL

Y

1

SCREENING 1

-7

2013-08-14T13:04

-9

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

57

KETONES

Ketones

URINALYSIS

0

NO UNITS

0

0

NORMAL

4

WEEK 2

14

2013-09-05T15:43

14

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

182

KETONES

Ketones

URINALYSIS

0

NO UNITS

0

0

NORMAL

9

WEEK 12

84

2013-11-17T10:59

87

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

277

KETONES

Ketones

URINALYSIS

0

NO UNITS

0

0

NORMAL

12

WEEK 24

168

2014-02-08T14:40

170

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

27

PH

pH

URINALYSIS

5.0

NO UNITS

5

8

5

5

5

8

NORMAL

Y

1

SCREENING 1

-7

2013-08-14T13:04

-9

LB

Xanomeline High Dose

CDISCPILOT01

LB

01-701-1148

64

PH

pH

URINALYSIS

7.0

NO UNITS

5

8

7

7

5

8

NORMAL

4

WEEK 2

14

2013-09-05T15:43

14

LB

Xanomeline High Dose

Please note that the table alignment option is more visible in a Word output format.

6 Appendix

6.1 Session info

R version 4.4.0 (2024-04-24)

Platform: x86_64-pc-linux-gnu

locale: C

attached base packages: stats, graphics, grDevices, utils, datasets, methods and base

other attached packages: flextable(v.0.9.6), plotly(v.4.10.4), plyr(v.1.8.9), htmltools(v.0.5.8.1), pander(v.0.6.5), ggplot2(v.3.5.1), clinUtils(v.0.2.0) and knitr(v.1.46)

loaded via a namespace (and not attached): gtable(v.0.3.5), xfun(v.0.44), bslib(v.0.7.0), htmlwidgets(v.1.6.4), tzdb(v.0.4.0), vctrs(v.0.6.5), tools(v.4.4.0), crosstalk(v.1.2.1), generics(v.0.1.3), curl(v.5.2.1), tibble(v.3.2.1), fansi(v.1.0.6), highr(v.0.10), pkgconfig(v.2.0.3), data.table(v.1.15.4), uuid(v.1.2-0), lifecycle(v.1.0.4), compiler(v.4.4.0), farver(v.2.1.2), textshaping(v.0.3.7), munsell(v.0.5.1), httpuv(v.1.6.15), fontquiver(v.0.2.1), fontLiberation(v.0.1.0), sass(v.0.4.9), yaml(v.2.3.8), lazyeval(v.0.2.2), pillar(v.1.9.0), later(v.1.3.2), crayon(v.1.5.2), jquerylib(v.0.1.4), tidyr(v.1.3.1), gfonts(v.0.2.0), openssl(v.2.2.0), DT(v.0.33), cachem(v.1.1.0), mime(v.0.12), fontBitstreamVera(v.0.1.1), zip(v.2.3.1), tidyselect(v.1.2.1), digest(v.0.6.35), dplyr(v.1.1.4), purrr(v.1.0.2), labeling(v.0.4.3), forcats(v.1.0.0), fastmap(v.1.2.0), grid(v.4.4.0), colorspace(v.2.1-0), cli(v.3.6.2), magrittr(v.2.0.3), crul(v.1.4.2), utf8(v.1.2.4), readr(v.2.1.5), withr(v.3.0.0), gdtools(v.0.3.7), scales(v.1.3.0), promises(v.1.3.0), officer(v.0.6.6), rmarkdown(v.2.26), httr(v.1.4.7), ragg(v.1.3.2), askpass(v.1.2.0), hms(v.1.1.3), shiny(v.1.8.1.1), evaluate(v.0.23), haven(v.2.5.4), viridisLite(v.0.4.2), rlang(v.1.1.3), Rcpp(v.1.0.12), xtable(v.1.8-4), glue(v.1.7.0), httpcode(v.0.3.0), xml2(v.1.3.6), jsonlite(v.1.8.8), R6(v.2.5.1) and systemfonts(v.1.1.0)