Introduction to the patientProfilesVis package
Author: Laure Cougnaud
Date: 2025-09-04

# Introduction to the `patientProfilesVis` package

#### Laure Cougnaud

#### September 04, 2025

# 1 Introduction

This package `patientProfilesVis` enables to create subject profile reports of patients/subjects in a clinical trial.

Such visualization can be used to obtain a global view of the subject metadata information, combined with its treatment exposure and concomitant medications, in relation with the adverse events occurring during the trial, and any measurements conducted during a clinical trial (e.g. laboratory, vital signs or ECG).

        library(patientProfilesVis)
        library(pander)

## 1.1 Input data

### 1.1.1 Data format

The input dataset for the creation of patient profiles should be a data.frame, typically CDISC ‘Study Data Tabulation Model’ (a.k.a SDTM) or ‘Analysis Data Model’ (a.k.a. ADaM) datasets.

The package also support tibble datasets as imported by the `read_sas`/`read_xpt` functions from the `haven`.

Alternatively, datasets can be imported at once with the `loadDataADaMSDTM` function from the `clinUtils` package.

Furthermore, the input dataset should contain a variable containing subject identifier. This variable is set to `USUBJID` by default, but can be overwritten via the `subjectVar` parameter.

### 1.1.2 Example SDTM dataset

The package is demonstrated with a subset of the SDTM datasets from the CDISC Pilot 01 dataset, available in the `clinUtils` package.

    library(clinUtils)

    # import example data:
    data(dataSDTMCDISCP01)
    # formatted as a list of data.frame (one per domain)
    dataSDTM <- dataSDTMCDISCP01
    names(dataSDTM)

    ##  [1] "AE"     "CM"     "DM"     "DS"     "EX"     "LB"     "MH"     "QS"
    ##  [9] "SUPPDM" "SV"     "VS"

    # and corresponding 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"

### 1.1.3 Example ADaM dataset

A subset of the ADaM datasets from the CDISC Pilot 01 dataset, available in the `clinUtils` package, is also imported for the example in section ADaM dataset.

    # import example data:
    data(dataADaMCDISCP01)
    # formatted as a list of data.frame (one per domain)
    dataADaM <- dataADaMCDISCP01
    names(dataADaM)

    ## [1] "ADAE"     "ADCM"     "ADLBC"    "ADPP"     "ADQSADAS" "ADQSCIBC" "ADQSNPIX"
    ## [8] "ADSL"     "ADVS"

    # and corresponding 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"

    # example subjects for the vignette:
    subjectAE <- "01-718-1427"
    subjectMH <- "01-718-1371"
    subjectCM <- "01-701-1148"
    subjectLB <- "01-704-1445"

# 2 Creation of the plot modules

## 2.1 General

Different types of visualization (a.k.a ‘modules’) are available via dedicated R function. Each function creates a separate visualization for each subject available in the dataset.

Four plot types/modules are currently available in the package:

- ‘text’ module: patient specific information formatted as text, available via the `subjectProfileTextPlot` function
- ‘interval’ module: representation of event with a start and end time, available via the `subjectProfileIntervalPlot` function
- ‘event’ module: representation of event occurring at a single time, available via the `subjectProfileEventPlot` function
- ‘line’ module: representation of the evolution of a continuous parameter across time via the `subjectProfileLinePlot` function

Each of this function returns a nested list of plots (`ggplot` object).

Each element of the list contains the plots for a specific subject. The subject profile plot for a specific subject/module is possibly split into multiple plots to fit in the final report (`formatReport` parameter).

## 2.2 Text module

The ‘text’ module enables to specify meta-information for each subject. There are two ways to specify such information, either by specifying a set of variables/columns of the data (`paramValueVar` only), or by a variable/column containing the parameter name (`paramNameVar`) and variable(s)/column(s) containing the parameter value (`paramValueVar`).

### 2.2.1 Wide format

        # annotate subject demographics meta-data
        # by specifying a set of variables to include
        dmPlots <- subjectProfileTextPlot(
            data = dataSDTM$DM,
            paramValueVar = c("SEX|AGE", "RACE|COUNTRY", "ARM"),
            labelVars = labelVarsSDTM
        )

Demographic information with the ‘subjectProfileTextPlot’ function for patient: 01-701-1148

### 2.2.2 Long format

#### 2.2.2.1 General

It is possible to specify multiple variable to represent in the plot for a certain variable name.

        # annotate subject medical history
        # by specifying a combination of parameter value/name
        mhPlots <- subjectProfileTextPlot(
            data = dataSDTM$MH,
            paramNameVar = c("MHDECOD"),
            paramValueVar = c("MHSTDTC", "MHSEV"),
            paramGroupVar = "MHCAT",
            title = "Medical History: status",
            labelVars = labelVarsSDTM
        )

Medical history with the ‘subjectProfileTextPlot’ function for patient: 01-718-1371

### 2.2.3 Table format (listing)

Information is displayed as a listing, by setting the `table` parameter to TRUE.

        aeListingPlots <- subjectProfileTextPlot(
            data = dataSDTM$AE,
            paramValueVar = c(
                "AEBODSYS", "AESOC", "AEHLT",
                "AELLT", "AEDECOD", "AESTDTC",
                "AEENDTC", "AESER", "AEACN"
            ),
            paramGroupVar = "AESTDTC",
            labelVars = labelVarsSDTM,
            table = TRUE
        )

Adverse event listing with the ‘subjectProfileTextPlot’ function for patient: 01-718-1427

By default, the widths of the columns of the table are optimized based on the column content, but custom widths can be specified via the `colWidth` parameter.

For example, the column for the system organ class is enlarged.

        aeListingPlots <- subjectProfileTextPlot(
            data = dataSDTM$AE,
            paramValueVar = c(
                "AEBODSYS", "AESOC", "AEHLT",
                "AELLT", "AEDECOD", "AESTDTC",
                "AEENDTC", "AESER", "AEACN"
            ),
            paramGroupVar = "AESTDTC",
            labelVars = labelVarsSDTM,
            table = TRUE,
            colWidth = c(
                0.2, 0.2, 0.05,
                0.1, 0.1, 0.05,
                0.05, 0.05, 0.05
            )
        )

Adverse event listing with the ‘subjectProfileTextPlot’ function for patient: 01-701-1148

#### 2.2.3.1 Customization for multiple variables

In case multiple variable are used as `paramValueVar` and they should be concatenated with a specific format, a function can be specified via the parameter: `paramValueVar`.

        # annotate subject medical history
        # by specifying a combination of parameter value/name
        paramValueVarFct <- function(data)
            with(data, paste0(
                ifelse(MHSEV != "", paste("severity:", MHSEV, ""), ""),
                "(start = ", ifelse(MHSTDTC != "", MHSTDTC, "undefined"), ")"
            ))
        mhPlotsMultipleVars <- subjectProfileTextPlot(
            data = dataSDTM$MH,
            paramNameVar = "MHDECOD",
            paramValueVar = paramValueVarFct,
            title = "Medical History: status with dates",
            labelVars = labelVarsSDTM
        )

Medical history with the ‘subjectProfileTextPlot’ function for patient: 01-718-1371

#### 2.2.3.2 With grouping

        # annotate subject medical history
        # by specifying a combination of parameter value/name
        mhPlotsGroup <- subjectProfileTextPlot(
            data = dataSDTM$MH,
            paramNameVar = "MHDECOD",
            paramValueVar = c("MHDECOD", "MHSTDTC"),
            paramGroupVar = "MHCAT",
            title = "Medical History: grouped by category",
            labelVars = labelVarsSDTM
        )

Medical history with the ‘subjectProfileTextPlot’ function for patient: 01-718-1371

## 2.3 Interval/Range module

Event with a fixed start/end time are displayed as time interval via the ‘interval’ module.

### 2.3.1 Adverse events

This module is used to represent the start/end date of the adverse events.

Please check section Missing starting/end time for further information on how records with missing start/end date are represented.

        dataAE <- dataSDTM$AE

        # sort severities
        dataAE[, "AESEV"] <- factor(dataAE[, "AESEV"], levels = c("MILD", "MODERATE", "SEVERE"))

        aePlots <- subjectProfileIntervalPlot(
            data = dataAE,
            paramVar = "AETERM",
            timeStartVar = "AESTDY",
            timeEndVar = "AEENDY",
            colorVar = "AESEV",
            labelVars = labelVarsSDTM,
            title = "Adverse events"
        )

    ## 3 record(s) with missing Study Day of Start of Adverse Event and 19 record(s) with missing Study Day of End of Adverse Event are imputed with minimal imputation.

    ## Warning: Removed 1 row containing missing values or values outside the scale range
    ## (`geom_point()`).

Adverse events with the ‘subjectProfileIntervalPlot’ function for patient: 01-718-1427

### 2.3.2 Exposure

The exposure of the patients to certain treatment(s) is also represented in this time interval visualization

        exPlots <- subjectProfileIntervalPlot(
            data = dataSDTM$EX,
            paramVar = c("EXTRT", "EXDOSE", "EXDOSU"),
            timeStartVar = "EXSTDY",
            timeEndVar = "EXENDY",
            colorVar = "EXDOSFRM",
            labelVars = labelVarsSDTM,
            title = "Treatment exposure"
        )

Exposure interval with the ‘subjectProfileIntervalPlot’ function for patient: 01-701-1148

### 2.3.3 Concomitant medications

        cmPlots <- subjectProfileIntervalPlot(
            data = dataSDTM$CM,
            paramVar = c(
                "CMTRT",
                "CMDOSE", "CMDOSU", "CMROUTE",
                "CMDOSFRQ"
            ),
            timeStartVar = "CMSTDY",
            timeEndVar = "CMENDY",
            paramGroupVar = "CMCLAS",
            colorVar = "CMCLAS",
            labelVars = labelVarsSDTM,
            title = "Concomitant medications"
        )

    ## 171 record(s) with missing Study Day of Start of Medication and 208 record(s) with missing Study Day of End of Medication are imputed with minimal imputation.

    ## Warning: Removed 26 rows containing missing values or values outside the scale range
    ## (`geom_segment()`).

    ## Warning: Removed 31 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

    ## Warning: Removed 26 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

Concomitant medications with the ‘subjectProfileIntervalPlot’ function for patient: 01-701-1148

### 2.3.4 Missing starting/end time

The interval visualization requires specified start/end time for each record.

However, it is frequent that the start or the end time of an event/record is missing in clinical data, especially if the data is being collected.

Different types of missing values can occur during a clinical study:

- partial dates, e.g. a concomitant medication that occurs 2012, but for which the relative date is not encoded
- on-going event at data collection, e.g. adverse event
- ‘true’ missing: actual date not reported

It might be important to still display these records in the visualization, so different types of imputation for missing start/end date for the interval visualization are available in the package.

Please have a look at the section ‘Details’ of the documentation of the `subjectProfileIntervalPlot` function for the most up-to-date information on this imputation.

#### 2.3.4.1 Default imputation

By default, minimal imputation is used (specified via the parameter `timeImpType`). Specific symbols are used to represent missing starting/end time.

Records with:

- missing start and end times are only displayed with their labels in the y-axis
- missing start only: record are displayed at the specified end with an left-directed arrow
- missing end only: record are displayed at the specified start with an right-directed arrow

        aePlots <- subjectProfileIntervalPlot(
            data = dataAE,
            paramVar = "AETERM",
            timeStartVar = "AESTDY",
            timeEndVar = "AEENDY",
            colorVar = "AESEV",
            labelVars = labelVarsSDTM,
            title = "Adverse events"
        )

    ## 3 record(s) with missing Study Day of Start of Adverse Event and 19 record(s) with missing Study Day of End of Adverse Event are imputed with minimal imputation.

    ## Warning: Removed 1 row containing missing values or values outside the scale range
    ## (`geom_point()`).

Adverse events with the ‘subjectProfileIntervalPlot’ function for patient: 01-718-1427

#### 2.3.4.2 Imputation based on an external dataset

To set the values represented for records with missing start/end dates, the time limits can be extracted from a specified dataset containing the start/end date for each subject via the `timeLimData`/`timeLimStartVar`/`timeLimEndVar` parameters.

This option is used below to impute missing starting/end time with the first/last visit for each subject based on the ‘Subject Visit’ dataset.

As the start and end of the subject visit dates are not available as relative day in the example data, these are first computed based on the subject reference start date/time available in the demography dataset.

    dataSV <- dataSDTM$SV
    dataSV$RFSTDTC <- dataSDTM$DM[match(dataSV$USUBJID, dataSDTM$DM$USUBJID), "RFSTDTC"]
    dataSV$SVSTDY <- with(dataSV, as.numeric(as.Date(SVSTDTC)-as.Date(RFSTDTC)+1))
    dataSV$SVENDY <- with(dataSV, as.numeric(as.Date(SVENDTC)-as.Date(RFSTDTC)+1))

        aePlotsTimLimFromSV <- subjectProfileIntervalPlot(
            data = dataAE,
            paramVar = "AETERM",
            timeStartVar = "AESTDY",
            timeEndVar = "AEENDY",
            colorVar = "AESEV",
            labelVars = labelVarsSDTM,
            title = "Adverse events",
            timeLimData = dataSV,
            timeLimStartVar = "SVSTDY", timeLimStartLab = "First subject visit",
            timeLimEndVar = "SVENDY", timeLimEndLab = "Last subject visit",
        )

    ## 3 record(s) with missing Study Day of Start of Adverse Event and 19 record(s) with missing Study Day of End of Adverse Event are imputed with First subject visit/Last subject visit  or minimal imputation.

Adverse events with the ‘subjectProfileIntervalPlot’ function for patient:01-718-1427. Missing start/end date are extracted from the subject-level dataset.

        svSubjectAE <- subset(dataSV, USUBJID == subjectAE)[, c("VISIT", "SVSTDY", "SVENDY")]
        pander(svSubjectAE)

| VISIT | SVSTDY | SVENDY
--- | --- | --- | ---
82 | SCREENING 1 | -3 | -3
83 | SCREENING 2 | -1 | -1
84 | BASELINE | 1 | 1
85 | AMBUL ECG PLACEMENT | 14 | 14
86 | WEEK 2 | 15 | 15
87 | WEEK 4 | 32 | 32
88 | AMBUL ECG REMOVAL | 34 | 34
89 | WEEK 6 | 43 | 43
90 | WEEK 8 | 64 | 64
91 | UNSCHEDULED 8.2 | 64 | 64
92 | RETRIEVAL | 169 | 169

This is also used to restrict the time limits of the plots.

As the modules will be combined with the same time limits, it might be advisable to restrict the time limits for this module via the `timeLimData`, `timeLimStartVar` and `timeLimEndVar` parameter.
In this example the time limits are restricted to the minimum/maximum time range of the subject visits.

        cmPlotsTimeSV <- subjectProfileIntervalPlot(
            data = dataSDTM$CM,
            paramVar = c(
                "CMTRT",
                "CMDOSE", "CMDOSU", "CMROUTE",
                "CMDOSFRQ"
            ),
            timeStartVar = "CMSTDY",
            timeEndVar = "CMENDY",
            paramGroupVar = "CMCLAS",
            colorVar = "CMCLAS",
            labelVars = labelVarsSDTM,
            title = "Concomitant medications",
            timeLimData = dataSV,
            timeLimStartVar = "SVSTDY",
            timeLimEndVar = "SVENDY",
            timeAlign = FALSE
        )

    ## 171 record(s) with missing Study Day of Start of Medication and 208 record(s) with missing Study Day of End of Medication are imputed with SVSTDY/SVENDY  or minimal imputation.

Concomitant medications with the ‘subjectProfileIntervalPlot’ function for patient: 01-701-1148 with time limits restricted to subject visits

#### 2.3.4.3 Custom specification for missing and partial dates

Missing start/end dates, partial dates or custom date status can be specified by creating two extra variables in the input data containing the status of the start/end time (`timeStartShapeVar`/`timeEndShapeVar`).

This status is represented as different symbols in the plot.

Please note that because the default `ggplot2` symbol palette doesn’t contain the left and right triangle symbols; these are specified in Unicode format in hexadecimal (see List of unicode symbols).

        # add status for dates:
        dataAE$AESTDYST <- with(dataAE,
            ifelse(is.na(AESTDY) & !is.na(AESTDY), "Missing start", "")
        )

        shapePalette <- c(
            `Missing start`= "\u25C4", # left-pointing arrow
            'NOT RECOVERED/NOT RESOLVED' = "\u25BA", # right-pointing arrow
            'RECOVERED/RESOLVED' = "\u25A0", # small square
            'FATAL' = "\u2666", # diamond
            UNKNOWN = "+"
        )

        aePlotsShape <- subjectProfileIntervalPlot(
            data = dataAE,
            paramVar = "AETERM",
            timeStartVar = "AESTDY", timeEndVar = "AEENDY",
            timeStartShapeVar = "AESTDYST", timeEndShapeVar = "AEOUT",
            shapePalette = shapePalette,
            shapeLab = "Study date status",
            colorVar = "AESEV",
            labelVars = labelVarsSDTM,
            title = "Adverse events"
        )

    ## 3 record(s) with missing Study Day of Start of Adverse Event and 19 record(s) with missing Study Day of End of Adverse Event are imputed with minimal imputation.

    ## Empty records in the: 'AESTDYST' variable are converted to NA.

    ## Warning: Removed 16 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

Adverse events with the ‘subjectProfileIntervalPlot’ function for patient: 01-718-1427 with custom shape specification

### 2.3.5 Specification of time limits

To restrict the time range in the visualization, the time limits can be set via the `timeLim` parameter.

The visualization are restricted to the timr range from baseline to the last visit (Week 26).

        timeLim <- c(0, 182)
        cmPlotsTimeSpec <- subjectProfileIntervalPlot(
            data = dataSDTM$CM,
            paramVar = c(
                "CMTRT",
                "CMDOSE", "CMDOSU", "CMROUTE",
                "CMDOSFRQ"
            ),
            timeStartVar = "CMSTDY",
            timeEndVar = "CMENDY",
            paramGroupVar = "CMCLAS",
            colorVar = "CMCLAS",
            labelVars = labelVarsSDTM,
            title = "Concomitant medications",
            timeLim = timeLim
        )

    ## 171 record(s) with missing Study Day of Start of Medication and 208 record(s) with missing Study Day of End of Medication are imputed with minimal imputation.

    ## Warning: Removed 26 rows containing missing values or values outside the scale range
    ## (`geom_segment()`).

    ## Warning: Removed 31 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

    ## Warning: Removed 26 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

Concomitant medications with the ‘subjectProfileIntervalPlot’ function for patient: 01-701-1148 with time limits restricted to: ( 0, 182 )

### 2.3.6 Non-alignment across subjects

By default, the visualizations created with the `subjectProfileIntervalPlot` are aligned in the time-axis across subjects.

To obtain visualization which don’t align, the parameter: `timeAlign` is set to FALSE.

        cmPlotsNotAligned <- subjectProfileIntervalPlot(
            data = dataSDTM$CM,
            paramVar = c(
                "CMTRT",
                "CMDOSE", "CMDOSU", "CMROUTE",
                "CMDOSFRQ"
            ),
            timeStartVar = "CMSTDY",
            timeEndVar = "CMENDY",
            paramGroupVar = "CMCLAS",
            colorVar = "CMCLAS",
            labelVars = labelVarsSDTM,
            title = "Concomitant medications",
            timeAlign = FALSE
        )

    ## 171 record(s) with missing Study Day of Start of Medication and 208 record(s) with missing Study Day of End of Medication are imputed with minimal imputation.

In this case, each visualization contains specific time-limits.

    ## Warning: Removed 26 rows containing missing values or values outside the scale range
    ## (`geom_segment()`).

    ## Warning: Removed 31 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

    ## Warning: Removed 26 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

Adverse events with the ‘subjectProfileIntervalPlot’ function for patient: 01-701-1148 with custom shape specification

When building the report, the same parameter should be used (see section Report creation).

## 2.4 Event module

### 2.4.1 General

The ‘event’ module enables to represent event data.

This is used to represent the presence/absence of a certain laboratory measurement (and corresponding time).

    # consider a subset of the laboratory data for example:
    lbTests <- c("CHOL", "PHOS", "ANISO", "MCHC", "PLAT", "KETONES")
    dataLB <- subset(dataSDTM$LB, LBTESTCD %in% lbTests)
    # sort the categories (empty values '', if any, becomes NA)
    dataLB$LBNRIND <- factor(dataLB$LBNRIND, levels = c("LOW", "NORMAL", "HIGH", "ABNORMAL"))

        # create plot
        lbPlots <- subjectProfileEventPlot(
            data = dataLB,
            paramVar = c("LBCAT", "LBTEST"),
            paramGroupVar = "LBCAT",
            timeVar = "LBDY",
            labelVars = labelVarsSDTM,
            title = "Laboratory test measurements"
        )

Laboratory data with the ‘subjectProfileEventPlot’ function for patient: 01-704-1445

### 2.4.2 Color/symbol

The laboratory events are colored based on the category of the laboratory parameter, with the `colorVar` parameter.

The reference range indicator is used to set different symbols via the `shapeVar`. Symbols specific of this categorization are used via the `shapePalette` parameter: bottom/top arrow for low/high measurements, dot for measurements in normal range and star for abnormal measurements.

        # create plot
        lbPlotsColorShape <- subjectProfileEventPlot(
            data = dataLB,
            paramVar = "LBTEST",
            paramGroupVar = "LBCAT",
            timeVar = "LBDY",
            colorVar = "LBCAT",
            labelVars = labelVarsSDTM,
            shapeVar = "LBNRIND",
            shapePalette = c(
                'LOW' = 25, 'NORMAL' = 19, 'HIGH' = 24,
                'ABNORMAL' = 11
            ),
            title = "Laboratory test measurements: reference range indicator"
        )

Laboratory data with reference range with the ‘subjectProfileEventPlot’ function for patient: 01-704-1445

## 2.5 Line module

### 2.5.1 General

The ‘line’ module enables to represent value of a variable across time.

This is used to represent the evolution of the lab parameters.

        # create plot
        lbLinePlots <- subjectProfileLinePlot(
            data = dataLB,
            paramNameVar = "LBTEST",
            paramValueVar = "LBSTRESN",
            paramGroupVar = "LBCAT",
            timeVar = "LBDY",
            title = "Laboratory test measurements: actual value",
            labelVars = labelVarsSDTM
        )

Laboratory data with the ‘subjectProfileLinePlot’ function for patient: 01-704-1445

### 2.5.2 Color/symbols of each observation

The color and the shape of the points can be specified via the `colorVar` and `shapeVar` parameters, similarly as for the `subjectProfileEventPlot` function. The reference range measurement is represented via these parameters.

        # create plot
        lbLinePlotsColorShape <- subjectProfileLinePlot(
            data = dataLB,
            paramNameVar = "LBTEST",
            paramValueVar = "LBSTRESN",
            colorVar = "LBCAT",
            shapeVar = "LBNRIND",
            shapePalette = c(
                'LOW' = 25, 'NORMAL' = 19, 'HIGH' = 24,
                'ABNORMAL' = 11
            ),
            paramGroupVar = "LBCAT",
            timeVar = "LBDY",
            title = "Laboratory test measurements: actual value",
            labelVars = labelVarsSDTM
        )

Laboratory data with reference range with the ‘subjectProfileLinePlot’ function for patient: 01-704-1445

### 2.5.3 Reference range

#### 2.5.3.1 Display reference range indicators

A reference range for each parameter can be visualized if the variables containing the low and upper limit of the range are specified via `paramValueRangeVar`:

        # create plot
        lbLineRefRangePlots <- subjectProfileLinePlot(
            data = dataLB,
            paramNameVar = "LBTEST",
            paramValueVar = "LBSTRESN",
            paramGroupVar = "LBCAT",
            paramValueRangeVar = c("LBSTNRLO", "LBSTNRHI"),
            shapeVar = "LBNRIND",
            shapePalette = c(
                'LOW' = 25, 'NORMAL' = 19, 'HIGH' = 24,
                'ABNORMAL' = 11
            ),
            timeVar = "LBDY",
            title = "Laboratory test measurements: actual value",
            labelVars = labelVarsSDTM
        )

Laboratory data with the ‘subjectProfileLinePlot’ function with a reference range for patient: 01-704-1445

#### 2.5.3.2 Range of the y-axis based on the observations or the reference range

By default, for each parameter, the range of the y-axis is extended to the reference range in case the range of the associated observations is smaller than the specified reference range.

If the range of the y-axis should only contain the range of the actual measurements, (so shouldn’t be extended to cover the reference range), the `yLimFrom` parameter should be set on: ‘value’.

        # create plot
        lbLineYLimFromValuePlots <- subjectProfileLinePlot(
            data = dataLB,
            paramNameVar = "LBTEST",
            paramValueVar = "LBSTRESN",
            paramGroupVar = "LBCAT",
            paramValueRangeVar = c("LBSTNRLO", "LBSTNRHI"),
            shapeVar = "LBNRIND",
            shapePalette = c(
                'LOW' = 25, 'NORMAL' = 19, 'HIGH' = 24,
                'ABNORMAL' = 11
            ),
            yLimFrom = "value",
            timeVar = "LBDY",
            title = "Laboratory test measurements: actual value",
            labelVars = labelVarsSDTM
        )

Laboratory data with the ‘subjectProfileLinePlot’ function for patient: 01-704-1445

# 3 Subset of interest

A subset of interest can be specified via:

- a dataset of interest
- a variable/values of interest (possibly from a different dataset in hand)
- a set of subjects of interest

These parameters are also available for all other module types.

## 3.1 Subset based on extra variable

If only a subset of parameters are of interest `subsetVar` and `subsetValue` can be used.

By default, the subset is extracted from the current `data`, but can also be extracted from a different dataset specified via `subsetData`.

The patient laboratory profile is only created for the patients with severe adverse events:

        # create plot
        lbPlotsSubset <- subjectProfileEventPlot(
            data = dataLB,
            paramVar = "LBTEST",
            # select subjects of interest:
            subsetData = dataSDTM$AE,
            subsetVar = "AESEV", subsetValue = "SEVERE",
            timeVar = "LBDY",
            colorVar = "LBNRIND",
            shapeVar = "LBNRIND",
            shapePalette = c(
                'LOW' = 25, 'NORMAL' = 19, 'HIGH' = 24,
                'ABNORMAL' = 11
            ),
            title = "Hematology test measurements",
            labelVars = labelVarsSDTM
        )
        cat("Only the", length(lbPlotsSubset), "patients with severe adverse events:", toString(names(lbPlotsSubset)), "are considered.\n")

    ## Only the 5 patients with severe adverse events: 01-701-1211, 01-704-1445, 01-710-1083, 01-718-1371, 01-718-1427 are considered.

## 3.2 Set of subjects of interest

A set of subjects of interest from the input `data` can be specified via the `subjectSubset` parameter (by default extracted from the `subjectVar` parameter):

        # create plot
        lbPlotsSubjectSubset <- subjectProfileEventPlot(
            data = dataLB,
            paramVar = "LBTEST",
            subsetVar = "LBCAT", subsetValue = "HEMATOLOGY",
            subjectSubset = subjectLB,
            timeVar = "LBDY",
            colorVar = "LBNRIND",
            shapeVar = "LBNRIND",
            shapePalette = c(
                'LOW' = 25, 'NORMAL' = 19, 'HIGH' = 24,
                'ABNORMAL' = 11
            ),
            title = "Laboratory test measurements for subject of interest",
            labelVars = labelVarsSDTM
        )
        cat("Only the patient:", toString(names(lbPlotsSubjectSubset)), "is considered.\n")

    ## Only the patient: 01-704-1445 is considered.

# 4 Specify colors/shapes

## 4.1 Missing values

Missing values in the specified color/shape variables are always displayed in the legend and associated palette.

If the variable is specified as character (by default when the dataset is loaded into R), the variable is converted to a factor and empty values (’’, if any) in the variable are converted to missing (NA).

If the variable is specified as factor, the missing values are included in the levels of the factor (via `exclude = NULL` in `factor`).

## 4.2 Order of the categories

By default, if a character vector is specified, the categories are sorted in alphabetical order when the variable is converted to a factor in R.

        dataLB <- subset(dataSDTM$LB, LBTESTCD %in% lbTests)

        # LBRIND is a character: elements sorted in alphabetical order
        lbPlotsColor <- subjectProfileEventPlot(
            data = dataLB,
            paramVar = "LBTEST",
            paramGroupVar = "LBCAT",
            timeVar = "LBDY",
            colorVar = "LBNRIND",
            title = "Laboratory test measurements: actual value",
            labelVars = labelVarsSDTM
        )

Laboratory data with the ‘subjectProfileEventPlot’ function with color/shape ordered alphabetically for patient: 01-704-1445

To specify the elements of the variable in a specific order (e.g. ordered categories), the variable should be converted to a factor with its levels sorted in the order of interest (as by default in `ggplot2`).

For example, the reference ranges for the laboratory measurements are sorted from low to high in the legend:

        dataLB <- subset(dataSDTM$LB, LBTESTCD %in% lbTests)
        # sort LBRIND
        dataLB$LBNRIND <- with(dataLB,
            factor(LBNRIND, levels = c("LOW", "NORMAL", "HIGH", "ABNORMAL"))
        )

        # create plot
        lbPlotsColor <- subjectProfileEventPlot(
            data = dataLB,
            paramVar = "LBTEST",
            paramGroupVar = "LBCAT",
            timeVar = "LBDY",
            colorVar = "LBNRIND",
            title = "Laboratory test measurements: actual value",
            labelVars = labelVarsSDTM
        )

Laboratory data with the ‘subjectProfileEventPlot’ function with color/shape ordered as specified for patient: 01-704-1445

Sometimes, the variable are also available their numeric form in the CDISC datasets.

In this case, corresponding numeric variable can be used for sorting:

        dataLB <- subset(dataSDTM$LB, LBTESTCD %in% lbTests)

        # for the demo, creates numeric variable associated to reference range
        # (often already available)
        dataLB$LBNRINDN <- c(LOW = 1, NORMAL = 2, HIGH = 3, ABNORMAL = 10)[dataLB$LBNRIND]

        dataLB$LBNRIND <- with(dataLB, reorder(LBNRIND, LBNRINDN))

        lbPlotsColor <- subjectProfileEventPlot(
            data = dataLB,
            paramVar = "LBTEST",
            paramGroupVar = "LBCAT",
            timeVar = "LBDY",
            colorVar = "LBNRIND", shapeVar = "LBNRIND",
            title = "Laboratory test measurements: actual value",
            labelVars = labelVarsSDTM
        )

Laboratory data with the ‘subjectProfileEventPlot’ function with color/shape ordered based on the corresponding numeric variable for patient: 01-704-1445

## 4.3 Palettes

### 4.3.1 Set palette for the entire session

Palette for the colors and shapes associated with specific variables can be set for all patient profile visualizations at once by setting the `patientProfilesVis.colors` and `patientProfilesVis.shapes` options at the start of the R session.

The default palette for colors is the `viridis` colorblind palette and a custom palette for shapes has been created in the package.

    # display default palettes
    colorsDefault <- getOption("patientProfilesVis.colors")
    str(colorsDefault)

    ## function (n, alpha = 1, begin = 0, end = 1, direction = 1, option = "D")

    shapesDefault <- getOption("patientProfilesVis.shapes")
    shapesDefault

    ##  [1] "circle filled"        "square filled"        "diamond filled"
    ##  [4] "triangle filled"      "triangle down filled" "square open"
    ##  [7] "circle open"          "triangle open"        "plus"
    ## [10] "cross"                "diamond open"         "triangle down open"
    ## [13] "square cross"         "asterisk"             "diamond plus"
    ## [16] "circle plus"          "star"                 "square plus"
    ## [19] "circle cross"         "square triangle"      "square"
    ## [22] "triangle"             "diamond"              "circle"

    # create plot
    lbPlots <- subjectProfileEventPlot(
        data = dataLB,
        paramVar = "LBTEST",
        paramGroupVar = "LBCAT",
        timeVar = "LBDY",
        colorVar = "LBNRIND",
        shapeVar = "LBNRIND",
        title = "Laboratory test measurements: actual value",
        labelVars = labelVarsSDTM
    )

Laboratory data with reference range with the ‘subjectProfileLinePlot’ function with default colors/shapes for patient: 01-704-1445

The palettes can be set for all patient profile visualization, e.g. at the start of the R session, with:

    # change palettes for the entire R session
    options(patientProfilesVis.colors = c("gold", "pink", "cyan"))
    options(patientProfilesVis.shapes = c("cross", "diamond", "circle", "square"))

In case the palette contains less elements than available in the data, these are replicated.

    # create plot
    lbPlots <- subjectProfileEventPlot(
        data = dataLB,
        paramVar = "LBTEST",
        paramGroupVar = "LBCAT",
        timeVar = "LBDY",
        colorVar = "LBNRIND",
        shapeVar = "LBNRIND",
        title = "Laboratory test measurements: actual value",
        labelVars = labelVarsSDTM
    )

Laboratory data with reference range with the ‘subjectProfileLinePlot’ function with default colors/shapes for patient: 01-704-1445

Palettes are reset to the default patient profiles palettes at the start of a new R session, or by setting:

    # change palettes for the entire R session
    options(patientProfilesVis.colors = colorsDefault)
    options(patientProfilesVis.shapes = shapesDefault)

### 4.3.2 Palette for standard CDISC variables

Custom palettes for standard reference indicator variable are available in the `clinUtils` package, via the function `getPaletteCDISC`.

    # sort LBNRIND
    dataLB$LBNRIND <- with(dataLB,
        factor(LBNRIND, levels = c("LOW", "NORMAL", "HIGH", "ABNORMAL"))
    )

    colorPaletteLBNRIND <- getPaletteCDISC(dataLB$LBNRIND, var = "NRIND", type = "color")
    print(colorPaletteLBNRIND)

    ##      LOW   NORMAL     HIGH ABNORMAL
    ## "orange" "green4" "orange"    "red"

    shapePaletteLBNRIND <- getPaletteCDISC(dataLB$LBNRIND, var = "NRIND", type = "shape")
    print(shapePaletteLBNRIND)

    ##      LOW   NORMAL     HIGH ABNORMAL
    ##       25       21       24       18

    # create plot
    lbPlots <- subjectProfileEventPlot(
        data = dataLB,
        paramVar = "LBTEST",
        paramGroupVar = "LBCAT",
        timeVar = "LBDY",
        colorVar = "LBNRIND", colorPalette = colorPaletteLBNRIND,
        shapeVar = "LBNRIND", shapePalette = shapePaletteLBNRIND,
        title = "Laboratory test measurements: actual value",
        labelVars = labelVarsSDTM
    )

Laboratory data with the ‘subjectProfileEventPlot’ function with generic color/shape palettes for patient: 01-704-1445

# 5 Time transformation

For certain module, it might be of interest to transform the time axis to e.g. ‘zoom’ in one part of the the study timeframe. The `timeTrans` parameter is used to specify a custom transformation of the time-axis.

The `getTimeTrans` provides convenient transformations:

- ‘asinh’: hyperbolic arc-sine transformation, to zoom in small absolute time values (around 0).
  Negative and positive values are represented in a log-like fashion.
- ‘asinh-neg’: hyperbolic arc-sine transformation only for negative relative time. The positive time frame is represented in a linear scale and negative times are represented in a log-like fashion.

This is typically of interest for domains including events occurring/recorded long before the start of the study (e.g. concomitant medications).

For example, the following subject has a concomitant medication starting long before the start of the study. This results into the positive part of the time axis being ‘squeezed’.

        cmPlots <- subjectProfileIntervalPlot(
            data = dataSDTM$CM,
            paramVar = c(
                "CMTRT",
                "CMDOSE", "CMDOSU", "CMROUTE",
                "CMDOSFRQ"
            ),
            timeStartVar = "CMSTDY",
            timeEndVar = "CMENDY",
            paramGroupVar = "CMCLAS",
            colorVar = "CMCLAS",
            title = "Concomitant medications",
            labelVars = labelVarsSDTM
        )

    ## 171 record(s) with missing Study Day of Start of Medication and 208 record(s) with missing Study Day of End of Medication are imputed with minimal imputation.

        subjectCMTimeTrans <- "01-701-1192"

    ## Warning: Removed 13 rows containing missing values or values outside the scale range
    ## (`geom_segment()`).

    ## Warning: Removed 32 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

    ## Warning: Removed 13 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

Concomitant medications with the ‘subjectProfileIntervalPlot’ function for patient: 01-701-1192

A hyperbolic arc-sine transformation is applied on the time axis, only for the negative times, to focus mainly on the medications taken after the start of the treatment exposure (after time 0).

        timeTrans <- getTimeTrans("asinh-neg")

        cmPlotsTimeTrans <- subjectProfileIntervalPlot(
            data = dataSDTM$CM,
            paramVar = c(
                "CMTRT",
                "CMDOSE", "CMDOSU", "CMROUTE",
                "CMDOSFRQ"
            ),
            timeStartVar = "CMSTDY",
            timeEndVar = "CMENDY",
            paramGroupVar = "CMCLAS",
            colorVar = "CMCLAS",
            timeTrans = timeTrans,
            title = "Concomitant medications",
            labelVars = labelVarsSDTM
        )

    ## 171 record(s) with missing Study Day of Start of Medication and 208 record(s) with missing Study Day of End of Medication are imputed with minimal imputation.

    ## Warning: Removed 13 rows containing missing values or values outside the scale range
    ## (`geom_segment()`).

    ## Warning: Removed 32 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

    ## Warning: Removed 13 rows containing missing values or values outside the scale range
    ## (`geom_point()`).

Concomitant medications with the ‘subjectProfileIntervalPlot’ function with asinh negative transformation of the time axis for patient: 01-701-1192

# 6 Creation of subject report

A report, combining all subject profile visualizations is created via the function `createSubjectProfileReport`.

The function:

- combines the subject profile plots of each patient across modules (via the `subjectProfileCombine` function)
- creates a pdf report containing the resulting plots (one page per subject)

Please note that the example report(s) in the section are not created by default in the vignette, for time constraints.

Feel free to run yourself the code, and check the resulting pdf report!

## 6.1 Example report

Example code to create patient profiles for SDTM or ADaM datasets is described below.

### 6.1.1 SDTM dataset

    # demography
    dmPlots <- subjectProfileTextPlot(
        data = dataSDTM$DM,
        paramValueVar = c("SEX|AGE", "RACE|COUNTRY", "ARM"),
        labelVars = labelVarsSDTM
    )

    # medical history
    mhPlots <- subjectProfileTextPlot(
        data = dataSDTM$MH,
        paramNameVar = c("MHDECOD"),
        paramValueVar = c("MHCAT", "MHTERM", "MHSTDTC"),
        title = "Medical History: status",
        labelVars = labelVarsSDTM
    )

    # concomitant medications
    cmPlots <- subjectProfileIntervalPlot(
        data = dataSDTM$CM,
        paramVar = c(
            "CMTRT",
            "CMDOSE", "CMDOSU", "CMROUTE",
            "CMDOSFRQ"
        ),
        timeStartVar = "CMSTDY",
        timeEndVar = "CMENDY",
        paramGroupVar = "CMCLAS",
        colorVar = "CMCLAS",
        timeTrans = timeTrans,
        title = "Concomitant medications",
        labelVars = labelVarsSDTM
    )

    # treatment exposure
    exPlots <- subjectProfileIntervalPlot(
        data = dataSDTM$EX,
        paramVar = c("EXTRT", "EXDOSE", "EXDOSU"),
        timeStartVar = "EXSTDY",
        timeEndVar = "EXENDY",
        colorVar = "EXDOSFRM",
        labelVars = labelVarsSDTM,
        title = "Treatment exposure"
    )

    # adverse events:
    dataAE <- dataSDTM$AE
    # sort severities
    dataAE[, "AESEV"] <- factor(dataAE[, "AESEV"], levels = c("MILD", "MODERATE", "SEVERE"))
    aePlots <- subjectProfileIntervalPlot(
        data = dataAE,
        paramVar = "AETERM",
        timeStartVar = "AESTDY",
        timeEndVar = "AEENDY",
        colorVar = "AESEV",
        labelVars = labelVarsSDTM,
        title = "Adverse events"
    )

    # laboratory parameter
    lbLinePlots <- subjectProfileLinePlot(
        data = dataSDTM$LB,
        paramNameVar = "LBTEST",
        paramValueVar = "LBSTRESN",
        paramValueRangeVar = c("LBSTNRLO", "LBSTNRHI"),
        paramGroupVar = "LBCAT",
        timeVar = "LBDY",
        title = "Laboratory test measurements: actual value",
        labelVars = labelVarsSDTM
    )

    # create report
    pathReport <- "subjectProfile_SDTM.pdf"
    createSubjectProfileReport(
        listPlots = list(
            dmPlots,
            mhPlots,
            cmPlots,
            exPlots,
            aePlots,
            lbLinePlots
        ),
        outputFile = pathReport
    )

### 6.1.2 ADaM dataset

    # demography
    adslPlots <- subjectProfileTextPlot(
        data = dataADaM$ADSL,
        paramValueVar = c("SEX|AGE", "RACE", "TRT01P"),
        labelVars = labelVarsADaM
    )

    # adverse events:
    dataADAE <- dataADaM$ADAE
    # sort severities
    dataADAE[, "AESEV"] <- factor(dataAE[, "AESEV"], levels = c("MILD", "MODERATE", "SEVERE"))
    adaePlots <- subjectProfileIntervalPlot(
        data = dataADAE,
        paramVar = "AEDECOD",
        timeStartVar = "ASTDY",
        timeEndVar = "AENDY",
        colorVar = "AESEV",
        labelVars = labelVarsADaM,
        timeTrans = getTimeTrans("asinh-neg"),
        title = "Adverse events"
    )

    # laboratory parameter
    adlbcPlots <- subjectProfileLinePlot(
        data = dataADaM$ADLBC,
        paramNameVar = "PARAM",
        paramValueVar = "AVAL",
        paramValueRangeVar = c("A1LO", "A1HI"),
        paramGroupVar = "PARCAT1",
        timeVar = "ADY",
        title = "Laboratory test measurements: actual value",
        labelVars = labelVarsADaM
    )

    # create report
    pathReport <- "subjectProfile_ADaM.pdf"
    createSubjectProfileReport(
        listPlots = list(
            adslPlots,
            adaePlots,
            adlbcPlots
        ),
        outputFile = pathReport
    )

## 6.2 Reference lines

### 6.2.1 Specify custom reference lines

Reference lines can be displayed as vertical lines spanning all visualizations.

Custom reference lines to indicated the two screening visits and the baseline are displayed for a example subject:

    # reference lines input parameter
    refLinesParam <- list(
        list(
            time = -7,
            label = "Screening 1",
            color = "purple"
        ),
        list(
            time = -7,
            label = "Screening 2",
            color = "purple"
        ),
        list(
            time = 1,
            label = "Baseline",
            color = "darkblue"
        )
    )

    # create report
    pathReport <- "subjectProfile_SDTM_referenceLines_custom.pdf"
    createSubjectProfileReport(
        listPlots = list(
            dmPlots,
            mhPlots,
            cmPlots,
            exPlots,
            aePlots,
            lbLinePlots
        ),
        refLines = refLinesParam,
        outputFile = pathReport
    )

### 6.2.2 Reference lines from subject visits

In the following example: the reference lines are extracted from the subject visits: `SV` dataset.

    # create report
    pathReport <- "subjectProfile_SDTM_referenceLines_subjectVisit.pdf"

    # only retain screening, baseline and planned visits
    dataSV <- subset(dataSDTM$SV, grepl("SCREENING|WEEK|BASELINE", VISIT))

    createSubjectProfileReport(
        listPlots = list(
            dmPlots,
            mhPlots,
            cmPlots,
            exPlots,
            aePlots,
            lbLinePlots
        ),
        # reference line(s)
        refLinesData = dataSV,
        refLinesTimeVar = "VISITDY",
        refLinesLabelVar = "VISIT",
        outputFile = pathReport
    )

## 6.3 Bookmarks

A simple index by sex and arm of each subject is created via the bookmark parameter.

    # create report
    pathReport <- "subjectProfile_SDTM_bookmarks.pdf"

    dataDM <- dataSDTM$DM
    # sort arm categories
    dataDM$ARM <- factor(dataDM$ARM,
        levels = c("Placebo", "Xanomeline Low Dose", "Xanomeline High Dose"))

    createSubjectProfileReport(
        listPlots = list(
            dmPlots,
            mhPlots,
            cmPlots,
            exPlots,
            aePlots,
            lbLinePlots
        ),
        subset = c("01-718-1427", "01-704-1445", "01-701-1211"),
        # bookmark(s)
        bookmarkData = dataDM,
        bookmarkVar = c("SEX", "ARM"),
        # sort subjects in the report based on:
        subjectSortData = dataDM,
        subjectSortVar = "ARM",
        outputFile = pathReport
    )

## 6.4 Time alignment

In order that the different visualizations are not aligned in the time axis, the modules to be aligned can be specified to the `timeAlign` parameter.

This can be of interest when combining a visualization displaying concomitant medications with historical data with a high time range and visualization of events occuring only during the study timeframe; or for modules with different time units.

Please note that the corresponding interval module(s) should also be created with the parameter: `timeAlign = FALSE` in the function `subjectProfileIntervalPlot` call (see section Interval module).

Please find an example below of subject profiles displaying the adverse events occurring from baseline associated with the laboratory measurements before and after baseline.

        # create the list of visualizations
        # The list is named in order that the names are used
        # to reference the module for the alignment parameters
        listPlots <- list(AE = aePlots, LB = lbLinePlots)
        subsetPatients <- c(subjectAE, subjectLB)

### 6.4.1 Visualizations aligned across domains and subjects

By default, the visualizations are aligned across domains (`timeAlign` is ‘all’) and subjects (`timeAlignPerSubject` is “none”).

Please note that because all domains are aligned, the adverse event domain is extended to also contain the times for laboratory measurements (and not only from baseline on as specified during the creation of the AE visualizations).

        pathReport <- "subjectProfile_timeAlign-all_timeAlignPerSubject-none.pdf"
        createSubjectProfileReport(
            listPlots = listPlots,
            outputFile = pathReport,
            subset = subsetPatients
        )

### 6.4.2 Visualizations aligned across subjects only for a specific domain

The visualizations are aligned only for the adverse events domain (`timeAlign` set to: ‘AE’) and across subjects (`timeAlignPerSubject` is “none”).

        pathReport <- "subjectProfile_timeAlign-AE_timeAlignPerSubject-none.pdf"
        createSubjectProfileReport(
            listPlots = listPlots,
            outputFile = pathReport,
            subset = subsetPatients,
            timeAlign = "AE"
        )

### 6.4.3 Visualizations not aligned across domains

The visualizations are not aligned across domain (`timeAlign` set to: ‘none’) neither subjects (`timeAlignPerSubject` is “none”).

        pathReport <- "subjectProfile_timeAlign-none_timeAlignPerSubject-none.pdf"
        createSubjectProfileReport(
            listPlots = listPlots,
            outputFile = pathReport,
            subset = subsetPatients,
            timeAlign = "none"
        )

### 6.4.4 Visualizations aligned per subject

The visualizations are aligned (`timeAlign` set to: ‘all’) per subject (`timeAlignPerSubject` is “all”).

        pathReport <- "subjectProfile_timeAlign-all_timeAlignPerSubject-all.pdf"
        createSubjectProfileReport(
            listPlots = listPlots,
            outputFile = pathReport,
            subset = subsetPatients,
            timeAlignPerSubject = "all"
        )

# 7 Optimization of patient profiles creation

For clinical trial with high number of patients (e.g. phase 3), the creation of the subject profile report can be time-consuming.

Please find below a few advices:

- during the development of the patient profiles for a specific study, the different modules can be created only for a subset of the subjects via the `subjectSubset` or `subsetData`/`subsetVar`/`subsetValue` parameters
- for the final creation of the patient profiles on the entire set of patients:
  - the reports can be created for the patients of highest concern first, e.g. patients with severe adverse events (via `subjectSortData`/`subjectSortVar`)
  - the reports can be exported by batch of X subjects, via the `exportBatchSize` parameter. Exporting the patient profiles by batch of 10 subjects can be a good idea for a for study with a high number of patients.
  - the report can be parallelized by specifying a number of cores > 1 to the parameter `nCores` of the `createSubjectProfileReport` function. In this case, the package `parallel` is required.
    To check the number of cores available in your system, you may use: `parallel::detectCores()`.

# 8 Appendix

## 8.1 Session information

R version 4.5.1 (2025-06-13)

Platform: x86_64-pc-linux-gnu

locale: LC_CTYPE=en_US.UTF-8, LC_NUMERIC=C, LC_TIME=en_US.UTF-8, LC_COLLATE=C, LC_MONETARY=en_US.UTF-8, LC_MESSAGES=en_US.UTF-8, LC_PAPER=en_US.UTF-8, LC_NAME=C, LC_ADDRESS=C, LC_TELEPHONE=C, LC_MEASUREMENT=en_US.UTF-8 and LC_IDENTIFICATION=C

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

other attached packages: pander(v.0.6.6), clinUtils(v.0.2.0), patientProfilesVis(v.2.0.10) and knitr(v.1.50)

loaded via a namespace (and not attached): gtable(v.0.3.6), jsonlite(v.2.0.0), compiler(v.4.5.1), Rcpp(v.1.1.0), stringr(v.1.5.1), parallel(v.4.5.1), gridExtra(v.2.3), jquerylib(v.0.1.4), scales(v.1.4.0), yaml(v.2.3.10), fastmap(v.1.2.0), ggplot2(v.3.5.2.9002), R6(v.2.6.1), plyr(v.1.8.9), labeling(v.0.4.3), htmlwidgets(v.1.6.4), forcats(v.1.0.0), tibble(v.3.3.0), bslib(v.0.9.0), pillar(v.1.11.0), RColorBrewer(v.1.1-3), rlang(v.1.1.6), DT(v.0.33), stringi(v.1.8.7), cachem(v.1.1.0), xfun(v.0.53), sass(v.0.4.10), S7(v.0.2.0), viridisLite(v.0.4.2), cli(v.3.6.5), withr(v.3.0.2), magrittr(v.2.0.3), crosstalk(v.1.2.2), digest(v.0.6.37), grid(v.4.5.1), haven(v.2.5.5), hms(v.1.1.3), cowplot(v.1.2.0), lifecycle(v.1.0.4), vctrs(v.0.6.5), evaluate(v.1.0.5), glue(v.1.8.0), data.table(v.1.17.8), farver(v.2.1.2), reshape2(v.1.4.4), rmarkdown(v.2.29), tools(v.4.5.1), pkgconfig(v.2.0.3) and htmltools(v.0.5.8.1)