clinUtils packageThis 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).
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))
| 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 |
| 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 |
| 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 |
| 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))
| 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 |
| 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 |
| 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))
| STUDYID | DOMAIN | USUBJID | AESEQ | AESPID |
|---|---|---|---|---|
| CDISCPILOT01 | AE | 01-701-1148 | 10 | E27 |
| CDISCPILOT01 | AE | 01-701-1148 | 1 | E20 |
| AETERM | AELLT | AELLTCD |
|---|---|---|
| ACTINIC KERATOSIS | ACTINIC KERATOSIS | NA |
| APPLICATION SITE ERYTHEMA | APPLICATION SITE REDNESS | NA |
| 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 |
| 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 |
| AESOCCD | AESEV | AESER | AEACN | AEREL | AEOUT |
|---|---|---|---|---|---|
| NA | MILD | N | NONE | NOT RECOVERED/NOT RESOLVED | |
| NA | MILD | N | PROBABLE | NOT RECOVERED/NOT RESOLVED |
| 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"
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.
# load data
data(dataADaMCDISCP01)
dataADaM <- dataADaMCDISCP01
names(dataADaM)
## [1] "ADAE" "ADCM" "ADLBC" "ADPP" "ADQSADAS" "ADQSCIBC" "ADSL"
## [8] "ADVS"
pander(head(dataADaM$ADSL, 2))
| 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 |
| 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 |
| 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 |
| 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 |
| COMP16FL | COMP24FL | DISCONFL | DSRAEFL | DTHFL | BMIBL | BMIBLGR1 | HEIGHTBL |
|---|---|---|---|---|---|---|---|
| Y | Y | 28.3 | 25-<30 | 175.3 | |||
| Y | Y | 27.8 | 25-<30 | 151.1 |
| 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))
| STUDYID | SUBJID | USUBJID | TRTP | TRTPN |
|---|---|---|---|---|
| CDISCPILOT01 | 1148 | 01-701-1148 | Xanomeline High Dose | 81 |
| CDISCPILOT01 | 1148 | 01-701-1148 | Xanomeline High Dose | 81 |
| 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 |
| AGEGR1N | RACE | RACEN | SEX | COMP24FL | DSRAEFL | SAFFL | AVISIT |
|---|---|---|---|---|---|---|---|
| 1 | WHITE | 1 | M | Y | Y | Baseline | |
| 1 | WHITE | 1 | M | Y | Y | Baseline |
| 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) |
| 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 |
| 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))
| 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 |
| 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 |
| ASTDT | ASTDTF | ASTDY | AENDT | AENDY | ADURN | ADURU |
|---|---|---|---|---|---|---|
| 2013-08-25 | 3 | NA | NA | NA | ||
| 2013-08-25 | 3 | NA | NA | NA |
| AETERM | AELLT | AELLTCD |
|---|---|---|
| APPLICATION SITE ERYTHEMA | APPLICATION SITE REDNESS | NA |
| APPLICATION SITE PRURITUS | APPLICATION SITE ITCHING | NA |
| 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 |
| 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 |
| AESEV | AESER | AESCAN | AESCONG | AESDISAB | AESDTH | AESHOSP | AESLIFE |
|---|---|---|---|---|---|---|---|
| MILD | N | N | N | N | N | N | N |
| MILD | N | N | N | N | N | N | N |
| AESOD | AEREL | AEACN | AEOUT | AESEQ | TRTEMFL |
|---|---|---|---|---|---|
| N | PROBABLE | NOT RECOVERED/NOT RESOLVED | 1 | Y | |
| N | PROBABLE | NOT RECOVERED/NOT RESOLVED | 2 | Y |
| 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"
# load data
data(dataSDTMCDISCP01)
dataSDTM <- dataSDTMCDISCP01
names(dataSDTM)
## [1] "AE" "CM" "DM" "EX" "LB" "MH" "SV" "VS"
pander(head(dataSDTM$DM, 2))
| 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 |
| 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 |
| 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 |
| 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))
| 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 |
| 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 |
| 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))
| STUDYID | DOMAIN | USUBJID | AESEQ | AESPID |
|---|---|---|---|---|
| CDISCPILOT01 | AE | 01-701-1148 | 10 | E27 |
| CDISCPILOT01 | AE | 01-701-1148 | 1 | E20 |
| AETERM | AELLT | AELLTCD |
|---|---|---|
| ACTINIC KERATOSIS | ACTINIC KERATOSIS | NA |
| APPLICATION SITE ERYTHEMA | APPLICATION SITE REDNESS | NA |
| 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 |
| 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 |
| AESOCCD | AESEV | AESER | AEACN | AEREL | AEOUT |
|---|---|---|---|---|---|
| NA | MILD | N | NONE | NOT RECOVERED/NOT RESOLVED | |
| NA | MILD | N | PROBABLE | NOT RECOVERED/NOT RESOLVED |
| 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"
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.
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"
Palette for typical CDISC-variable(s) are available in the package.
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))
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 (geom_point).
## Warning: Removed 7 row(s) containing missing values (geom_path).
Custom palettes can be specified via the palette parameter.
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
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"
)
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`
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'.
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
)
Barplot of chemistry measurements
Barplot of hematology measurements
Barplot of urinalysis measurements
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)
htmltools::tagListA 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)
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
)
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
)
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 |
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 |
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.
R version 4.1.1 (2021-08-10)
Platform: x86_64-pc-linux-gnu (64-bit)
locale: LC_CTYPE=en_US.UTF-8, LC_NUMERIC=C, LC_TIME=en_GB.UTF-8, LC_COLLATE=en_US.UTF-8, LC_MONETARY=en_GB.UTF-8, LC_MESSAGES=en_US.UTF-8, LC_PAPER=en_GB.UTF-8, LC_NAME=C, LC_ADDRESS=C, LC_TELEPHONE=C, LC_MEASUREMENT=en_GB.UTF-8 and LC_IDENTIFICATION=C
attached base packages: stats, graphics, grDevices, utils, datasets, methods and base
other attached packages: flextable(v.0.6.8), plotly(v.4.9.4.1), plyr(v.1.8.6), htmltools(v.0.5.2), pander(v.0.6.4), ggplot2(v.3.3.5), clinUtils(v.0.1.0) and knitr(v.1.34)
loaded via a namespace (and not attached): tidyselect(v.1.1.1), xfun(v.0.26), purrr(v.0.3.4), haven(v.2.4.3), colorspace(v.2.0-2), vctrs(v.0.3.8), generics(v.0.1.0), viridisLite(v.0.4.0), base64enc(v.0.1-3), yaml(v.2.2.1), utf8(v.1.2.2), rlang(v.0.4.11), jquerylib(v.0.1.4), pillar(v.1.6.2), glue(v.1.4.2), withr(v.2.4.2), gdtools(v.0.2.3), uuid(v.0.1-4), lifecycle(v.1.0.0), stringr(v.1.4.0), munsell(v.0.5.0), gtable(v.0.3.0), zip(v.2.2.0), htmlwidgets(v.1.5.4), evaluate(v.0.14), labeling(v.0.4.2), forcats(v.0.5.1), tzdb(v.0.1.2), fastmap(v.1.1.0), crosstalk(v.1.1.1), curl(v.4.3.2), fansi(v.0.5.0), highr(v.0.9), Rcpp(v.1.0.7), readr(v.2.0.1), scales(v.1.1.1), DT(v.0.19), jsonlite(v.1.7.2), systemfonts(v.1.0.2), farver(v.2.1.0), hms(v.1.1.0), digest(v.0.6.27), stringi(v.1.7.4), dplyr(v.1.0.7), grid(v.4.1.1), tools(v.4.1.1), magrittr(v.2.0.1), lazyeval(v.0.2.2), tibble(v.3.1.4), crayon(v.1.4.1), tidyr(v.1.1.3), pkgconfig(v.2.0.3), ellipsis(v.0.3.2), xml2(v.1.3.2), data.table(v.1.14.0), officer(v.0.4.0), rmarkdown(v.2.11), httr(v.1.4.2), R6(v.2.5.1) and compiler(v.4.1.1)