---
title: "Introduction to the `patientProfilesVis` package"
author: "Laure Cougnaud"
date: "`r format(Sys.Date(), '%B %d, %Y')`"
output: 
  rmarkdown::html_document:
    toc: true
    toc_float: true
    toc_depth: 5
    number_sections: true
vignette: >
  %\VignetteIndexEntry{Introduction to the patientProfilesVis package}
  %\VignetteEngine{knitr::rmarkdown}
  \usepackage[utf8]{inputenc}
---

# Introduction

```{r options, echo = FALSE}
	
	library(knitr)
	opts_chunk$set(
		error = FALSE, 
		fig.width = 14, fig.height = 7,
		dev = "png",
		out.width = "100%",
		fig.path = "./figures_vignette/",
		fig.align = 'center'
	)
	# include warnings where they occur
	options(warn = 1)
	
	heightLineIn  <- 0.2
	
```

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


```{r loadPackages, message = FALSE}

	library(patientProfilesVis)
	library(pander)

```

## Input data

### 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`](https://CRAN.R-project.org/package=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.

### 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.

```{r loadData-SDTM}	
	
library(clinUtils)

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

# and corresponding labels
labelVarsSDTM <- attr(dataSDTM, "labelVars")
head(labelVarsSDTM)	
	
```

### 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].

```{r loadData-ADaM}	
	
# import example data:
data(dataADaMCDISCP01)
# formatted as a list of data.frame (one per domain)
dataADaM <- dataADaMCDISCP01
names(dataADaM)

# and corresponding labels
labelVarsADaM <- attr(dataADaM, "labelVars")
head(labelVarsADaM)

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

# Creation of the plot modules

## 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).
  
## 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`).

### Wide format

```{r text-wideFormat}

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

```{r text-wideFormat-include, echo = FALSE, fig.height = attributes(dmPlots[[1]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Demographic information with the 'subjectProfileTextPlot' function for patient:", names(dmPlots)[1])}

	print(dmPlots[[1]][[1]])

```

### Long format

#### General

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

```{r text-longFormat-noGrouping}	

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

```{r text-longFormat-noGrouping-include, echo = FALSE, fig.height = attributes(mhPlots[[subjectMH]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Medical history with the 'subjectProfileTextPlot' function for patient:", subjectMH)}

	print(mhPlots[[subjectMH]][[1]])

```

### Table format (listing)

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

```{r text-tableFormat}

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

```{r text-tableFormat-include, echo = FALSE, fig.height = attributes(aeListingPlots[[subjectAE]][[1]])$metaData$nLines*heightLineIn, fig.width = 14, fig.cap = paste("Adverse event listing with the 'subjectProfileTextPlot' function for patient:", subjectAE)}

	print(aeListingPlots[[subjectAE]][[1]])

```

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.

```{r text-tableFormat-customWidth}

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

```{r text-tableFormat-customWidth-include, echo = FALSE, fig.width = 14, fig.height = attributes(aeListingPlots[[1]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Adverse event listing with the 'subjectProfileTextPlot' function for patient:", names(aeListingPlots)[1])}

	print(aeListingPlots[[subjectAE]][[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`.

```{r text-longFormat-multipleVariables}	

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

```{r text-longFormat-multipleVariables-include, echo = FALSE, fig.height = attributes(mhPlotsMultipleVars[[subjectMH]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Medical history with the 'subjectProfileTextPlot' function for patient:", subjectMH)}

	print(mhPlotsMultipleVars[[subjectMH]][[1]])

```

#### With grouping

```{r text-longFormat-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
	)
	
```

```{r text-longFormat-grouping-include, echo = FALSE, fig.height = attributes(mhPlotsGroup[[subjectMH]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Medical history with the 'subjectProfileTextPlot' function for patient:", subjectMH)}

	print(mhPlotsGroup[[subjectMH]][[1]])

```

## Interval/Range module

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

### Adverse events

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

Please **check section [Missing starting/end time](#intervalMissingStartEnd) for further information 
on how records with
missing start/end date are represented**.

```{r interval-ae}

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

```{r interval-ae-include, echo = FALSE, fig.height = attributes(aePlots[[subjectAE]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Adverse events with the 'subjectProfileIntervalPlot' function for patient:", subjectAE)}

	print(aePlots[[subjectAE]][[1]])

```

### Exposure

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

```{r interval-ex}

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

```

```{r interval-ex-include, echo = FALSE, fig.height = attributes(exPlots[[1]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Exposure interval with the 'subjectProfileIntervalPlot' function for patient:", names(exPlots)[1])}

	print(exPlots[[1]][[1]])

```

### Concomitant medications

```{r interval-cm}

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

```

```{r interval-cm-include, echo = FALSE, fig.height = attributes(cmPlots[[subjectCM]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Concomitant medications with the 'subjectProfileIntervalPlot' function for patient:", subjectCM)}

	print(cmPlots[[subjectCM]][[1]])

```

### Missing starting/end time {#intervalMissingStartEnd}

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**.

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

```{r interval-ae-default, message = TRUE}

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

```{r interval-ae-default-include, echo = FALSE, fig.height = attributes(aePlots[[subjectAE]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Adverse events with the 'subjectProfileIntervalPlot' function for patient:", subjectAE)}

	print(aePlots[[subjectAE]][[1]])

```

#### 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.

```{r formatSVData}

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


```

```{r interval-ae-timeLimData, message = TRUE}
	
	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", 
	)
	
```

```{r interval-ae-timeLimData-include, echo = FALSE, fig.height = attributes(aePlotsTimLimFromSV[[subjectAE]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste0("Adverse events with the 'subjectProfileIntervalPlot' function for patient:", subjectAE, ". Missing start/end date are extracted from the subject-level dataset.")}

	print(aePlotsTimLimFromSV[[subjectAE]][[1]])

```

```{r interval-ae-timeLimData-svData}
	svSubjectAE <- subset(dataSV, USUBJID == subjectAE)[, c("VISIT", "SVSTDY", "SVENDY")]
	pander(svSubjectAE)
```

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.

```{r interval-cm-restrictedTimeLimits}

	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
	)

```

```{r interval-cm-restrictedTimeLimits-include, echo = FALSE, fig.height = attributes(cmPlotsTimeSV[[subjectCM]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Concomitant medications with the 'subjectProfileIntervalPlot' function for patient:", subjectCM, "with time limits restricted to subject visits")}

	print(cmPlotsTimeSV[[subjectCM]][[1]])

```


#### 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](https://ggplot2.tidyverse.org/reference/scale_shape.html)
doesn't contain the left and right triangle symbols; these are specified
in Unicode format in hexadecimal (see [List of unicode symbols](https://en.wikipedia.org/wiki/List_of_Unicode_characters)).

```{r interval-ae-customMissingPartialDates}

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

```

```{r interval-ae-customMissingPartialDates-include, echo = FALSE, fig.height = attributes(aePlotsShape[[subjectAE]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Adverse events with the 'subjectProfileIntervalPlot' function for patient:", subjectAE, "with custom shape specification")}

	print(aePlotsShape[[subjectAE]][[1]])

```

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

```{r interval-cm-restrictedTimeLimits2}

	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
	)

```

```{r interval-cm-restrictedTimeLimits2-include, echo = FALSE, fig.height = attributes(cmPlotsTimeSpec[[subjectCM]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Concomitant medications with the 'subjectProfileIntervalPlot' function for patient:", subjectCM, "with time limits restricted to: (", toString(timeLim), ")")}

	print(cmPlotsTimeSpec[[subjectCM]][[1]])

```

### Non-alignment across subjects {#subjectIntervalTimeAlign}

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.

```{r interval-cm-timeAlign-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
	)

```

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

```{r interval-cm-timeAlign-FALSE-include-1, echo = FALSE, fig.height = attributes(cmPlotsNotAligned[[subjectCM]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Adverse events with the 'subjectProfileIntervalPlot' function for patient:", subjectCM, "with custom shape specification")}

	print(cmPlotsNotAligned[[subjectCM]][[1]])


```

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

## Event module

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

```{r formatLBData}

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

```

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

```

```{r event-include, echo = FALSE, fig.height = attributes(lbPlots[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with the 'subjectProfileEventPlot' function for patient:", subjectLB)}

	print(lbPlots[[subjectLB]][[1]])

```

### 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.

```{r event-color}

	# 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"
	)
	
```

```{r event-color-include, echo = FALSE, fig.height = attributes(lbPlotsColorShape[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with reference range with the 'subjectProfileEventPlot' function for patient:", subjectLB)}

	print(lbPlotsColorShape[[subjectLB]][[1]])

```

## Line module

### General

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

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

```{r line}

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

```{r line-include, echo = FALSE, fig.height = attributes(lbLinePlots[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with the 'subjectProfileLinePlot' function for patient:", subjectLB)}

	print(lbLinePlots[[subjectLB]][[1]])

```

### 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.

```{r line-colorShape}

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

```{r line-colorShape-include, echo = FALSE, fig.height = attributes(lbLinePlotsColorShape[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with reference range with the 'subjectProfileLinePlot' function for patient:", subjectLB)}

	print(lbLinePlotsColorShape[[subjectLB]][[1]])

```

### Reference range

#### 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`:

```{r line-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
	)
	
```

```{r line-paramValueRangeVar-value-include, echo = FALSE, fig.height = attributes(lbLineRefRangePlots[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with the 'subjectProfileLinePlot' function with a reference range for patient:", subjectLB)}

	print(lbLineRefRangePlots[[subjectLB]][[1]])

```

#### 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'.

```{r line-yLimFrom-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
	)
	
```

```{r line-yLimFrom-value-include, echo = FALSE, fig.height = attributes(lbLineYLimFromValuePlots[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with the 'subjectProfileLinePlot' function for patient:", subjectLB)}

	print(lbLineYLimFromValuePlots[[subjectLB]][[1]])

```

# 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.

## 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:

```{r event-subset}

	# 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")
	
```

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

```{r event-subset-2}

	# 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")
	
```

# Specify colors/shapes

## 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`).

## 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.

```{r lab-SDTM-categories-default}
			
	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
	)
	
```	

```{r lab-SDTM-categories-default-include, echo = FALSE, fig.height = attributes(lbPlotsColor[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with the 'subjectProfileEventPlot' function with color/shape ordered alphabetically for patient:", subjectLB)}

print(lbPlotsColor[[subjectLB]][[1]])

```

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: 

```{r lab-SDTM-categories-sorted}
	
	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
	)
	
```

```{r lab-SDTM-categories-sorted-include, echo = FALSE, fig.height = attributes(lbPlotsColor[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with the 'subjectProfileEventPlot' function with color/shape ordered as specified for patient:", subjectLB)}

print(lbPlotsColor[[subjectLB]][[1]])

```

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

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

```{r lab-ADaM-categories-sorted-numeric}	
	
	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
	)

```

```{r lab-SDTM-categories-sorted-numeric, echo = FALSE, fig.height = attributes(lbPlotsColor[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with the 'subjectProfileEventPlot' function with color/shape ordered based on the corresponding numeric variable for patient:", subjectLB)}

print(lbPlotsColor[[subjectLB]][[1]])

```

## Palettes

### 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.

```{r palettes-default-get}

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

```

```{r palettes-default-example}

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

```

```{r palettes-default-example-include, echo = FALSE, fig.height = attributes(lbPlots[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with reference range with the 'subjectProfileLinePlot' function with default colors/shapes for patient:", subjectLB)}

print(lbPlots[[subjectLB]][[1]])

```

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

```{r palettes-customGeneral-set}

# 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.

```{r palettes-customGeneral-example}

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

```

```{r palettes-customGeneral-example-include, echo = FALSE, fig.height = attributes(lbPlots[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with reference range with the 'subjectProfileLinePlot' function with default colors/shapes for patient:", subjectLB)}

	print(lbPlots[[subjectLB]][[1]])

```

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

```{r palettes-default-reset}

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

```

### Palette for standard CDISC variables

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

```{r palettes}

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

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

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

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

```


```{r palettes-include, echo = FALSE, fig.height = attributes(lbPlots[[subjectLB]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Laboratory data with the 'subjectProfileEventPlot' function with generic color/shape palettes for patient:", subjectLB)}

print(lbPlots[[subjectLB]][[1]])

```

# 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'.

```{r interval-cm-example}

	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
	)
	
	subjectCMTimeTrans <- "01-701-1192"

```

```{r interval-cm-example-include, echo = FALSE, fig.height = attributes(cmPlots[[subjectCMTimeTrans]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Concomitant medications with the 'subjectProfileIntervalPlot' function for patient:", subjectCMTimeTrans)}

	print(cmPlots[[subjectCMTimeTrans]][[1]])

```

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

```{r interval-cm-timeTransformation}

	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
	)

```

```{r interval-cm-timeTransformation-include, echo = FALSE, fig.height = attributes(cmPlotsTimeTrans[[subjectCMTimeTrans]][[1]])$metaData$nLines*heightLineIn, fig.cap = paste("Concomitant medications with the 'subjectProfileIntervalPlot' function with asinh negative transformation of the time axis for patient:", subjectCMTimeTrans)}

	print(cmPlotsTimeTrans[[subjectCMTimeTrans]][[1]])

```

# 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!

## Example report

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

### SDTM dataset

```{r createReport-SDTM, eval = FALSE}

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

```

### ADaM dataset

```{r createReport-ADaM, eval = FALSE}

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

```

## Reference lines

### 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:

```{r createReport-referenceLines-list, eval = FALSE}

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

```

### Reference lines from subject visits

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

```{r createReport-referenceLines-data, eval = FALSE}

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

```

## Bookmarks

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

```{r createReport-bookmarks, eval = FALSE}

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

```

## Time alignment {#createSubjectProfileReportTimeAlign}

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](#subjectIntervalTimeAlign)).

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

```{r createReport-example}

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

```

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

```{r createReport-timeAlign, out.width = "100%", out.height = "700px", eval = FALSE}

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

### 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").

```{r createReport-timeAlign-domain, out.width = "100%", out.height = "700px", eval = FALSE}

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

### Visualizations not aligned across domains

The visualizations are not aligned across domain (`timeAlign` set to: 'none') neither subjects (`timeAlignPerSubject`  is "none").

```{r createReport-timeAlign-none, out.width = "100%", out.height = "700px", eval = FALSE}

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

### Visualizations aligned per subject

The visualizations are aligned (`timeAlign` set to: 'all') per subject (`timeAlignPerSubject`  is "all").

```{r createReport-timeAlign-perSubject, out.width = "100%", out.height = "700px", eval = FALSE}

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

# 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()`.

# Appendix

## Session information

```{r includeSessionInfo, echo = FALSE}

	pander(sessionInfo())

```
