---
title: LTG01
subtitle: Lattice Plot of Laboratory Tests by Treatment Group Over Time
---
------------------------------------------------------------------------
{{< include ../../_utils/envir_hook.qmd >}}
Lattice plots are natively handled by R, the examples below rely mostly on the package `ggplot2`.
```{r setup, echo = FALSE, warning = FALSE, message = FALSE}
library(tern)
library(teal.modules.clinical)
library(ggplot2)
library(dplyr)
library(nestcolor)
# Datasets
adsl <- random.cdisc.data::cadsl %>% slice(1:8)
adlb <- random.cdisc.data::cadlb %>% filter(USUBJID %in% adsl$USUBJID)
# Pre-processing
adlb$AVISIT_txt <- adlb$AVISIT
adlb$AVISIT <- as.numeric(adlb$AVISIT)
adlb$ARM_N <- adlb$ARM
levels(adlb$ARM_N) <- with(
data = adlb,
paste0(
levels(ARM_N), " (N = ",
tapply(SUBJID, ARM_N, function(x) length(unique(x))), ")"
)
)
# Plot utils
npch <- 1:25
npatients <- length(unique(adlb$SUBJID))
pch <- c(
rep(npch, times = npatients %/% length(npch)),
npch[1:(npatients %% length(npch))]
)
```
```{r include = FALSE}
webr_code_labels <- c("setup")
```
{{< include ../../_utils/webr_no_include.qmd >}}
## Output
:::::::::: panel-tabset
## Plot of Liver Function Tests
#### Basic Plot
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
```{r plot1, test = list(plot_v1 = "plot")}
# General mapping and "lattice" ("facet" in ggplot2 nomenclature).
g1 <- {
ggplot(
data = adlb,
mapping = aes(x = AVISIT, y = AVAL, colour = SUBJID, shape = SUBJID)
) +
facet_grid(LBTESTCD ~ ARM, scales = "free_y") +
scale_shape_manual(values = pch)
}
# Add points and lines.
g1 <- g1 + geom_point()
g1 <- g1 + geom_line()
plot <- g1
plot
```
```{r include = FALSE}
webr_code_labels <- c("plot1")
```
{{< include ../../_utils/webr.qmd >}}
:::
#### Modifying Facets
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
The units describing rows of panes and the number of patients under each arm is specified by modifying `facet_grid()`:
```{r plot2, test = list(plot_v2 = "plot")}
# Include the units and the sample size N.
g2 <- g1 + facet_grid(
paste0(LBTESTCD, "\n(", AVALU, ")") ~ ARM_N,
scales = "free_y"
)
plot <- g2
plot
```
```{r include = FALSE}
webr_code_labels <- c("plot2")
```
{{< include ../../_utils/webr.qmd >}}
:::
#### Modifying X-Axis
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
The graphic elements are modified through usual `ggplot2` functions. For instance, the x-axis could be improved as follows:
```{r plot3, test = list(plot_v3 = "g3")}
g3 <- g2 + theme(
axis.text.x = element_text(angle = 45, hjust = 1),
axis.title = element_blank()
) + scale_x_continuous(breaks = adlb$AVISIT, labels = adlb$AVISIT_txt)
plot <- g3
plot
```
```{r include = FALSE}
webr_code_labels <- c("plot3")
```
{{< include ../../_utils/webr.qmd >}}
:::
## Plot of Liver Function Tests <br/> Including Mean, Median, and 95% CIs
The functions `stat_mean_ci` and `stat_median_ci` from the `tern` package allow the addition of mean and/or median confidence intervals. The example below suggests a larger dataset, where the individual subject legend may not be relevant but the mean or the median are of special interest.
#### Pre-Processing
```{r pre-processing}
#| code-fold: show
# Datasets
adsl <- random.cdisc.data::cadsl %>% slice(1:40)
adlb <- random.cdisc.data::cadlb %>% filter(USUBJID %in% adsl$USUBJID)
# Pre-processing
adlb$AVISIT_txt <- adlb$AVISIT
adlb$AVISIT <- as.numeric(adlb$AVISIT)
adlb$ARM_N <- adlb$ARM
levels(adlb$ARM_N) <- with(
data = adlb,
paste0(
levels(ARM_N), " (N = ",
tapply(SUBJID, ARM_N, function(x) length(unique(x))), ")"
)
)
# Plot utils
npch <- 1:25
npatients <- length(unique(adlb$SUBJID))
pch <- c(
rep(npch, times = npatients %/% length(npch)),
npch[1:(npatients %% length(npch))]
)
```
```{r include = FALSE}
webr_code_labels <- c("pre-processing")
```
{{< include ../../_utils/webr_no_include.qmd >}}
#### Basic Plot
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
```{r plot4, test = list(plot_v4 = "plot")}
# General mapping and "lattice" ("facet" in ggplot2 nomenclature)
g4 <- {
ggplot(
data = adlb,
mapping = aes(x = AVISIT, y = AVAL, colour = SUBJID, shape = SUBJID)
) +
facet_grid(LBTESTCD ~ ARM_N, scales = "free_y") +
scale_shape_manual(values = pch) +
scale_color_manual(values = rep(getOption("ggplot2.discrete.colour"), 2))
}
# Add points and lines.
# Note that with so many patients, legend might not be useful and transparency
# is advisable.
g4 <- g4 + geom_point(alpha = .3)
g4 <- g4 + geom_line(alpha = .3)
g4 <- g4 + guides(colour = "none", shape = "none")
g4 <- g4 + theme(
axis.text.x = element_text(angle = 45, hjust = 1),
axis.title = element_blank()
)
g4 <- g4 + scale_x_continuous(breaks = adlb$AVISIT, labels = adlb$AVISIT_txt)
plot <- g4
plot
```
```{r include = FALSE}
webr_code_labels <- c("plot4")
```
{{< include ../../_utils/webr.qmd >}}
:::
#### Adding Mean
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
```{r plot51, test = list(plot_v51 = "plot")}
# Add the mean along with the 95% CI at every visit.
g51 <- g4 + stat_summary(
fun = mean, linewidth = 1, geom = "line",
aes(group = 1, linetype = "Mean +/- 95% CI")
)
g51 <- g51 + stat_summary(
fun.data = tern::stat_mean_ci, geom = "errorbar",
aes(group = 1, linetype = "Mean +/- 95% CI")
)
plot <- g51 + guides(linetype = guide_legend(title = NULL))
plot
```
```{r include = FALSE}
webr_code_labels <- c("plot51")
```
{{< include ../../_utils/webr.qmd >}}
:::
#### Adding Median
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
```{r plot52, test = list(plot_v52 = "plot")}
# Instead of a mean, the median could be more relevant.
g52 <- g51 + stat_summary(
fun = median, linewidth = 1, geom = "line",
aes(group = 1, linetype = "Median +/- 95% CI")
)
g52 <- g52 + stat_summary(
fun.data = tern::stat_median_ci, geom = "errorbar",
aes(group = 1, linetype = "Median +/- 95% CI")
)
plot <- g52 + guides(linetype = guide_legend(title = "Aggregate"))
plot
```
```{r include = FALSE}
webr_code_labels <- c("plot52")
```
{{< include ../../_utils/webr.qmd >}}
:::
#### Changing Confidence Level
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
```{r plot53, test = list(plot_v53 = "plot")}
# Change the confidence level of interval for the median.
# Note: check `?stat_mean_ci()` and `?stat_median_ci()` for further fine tuning.
g53 <- g4 + stat_summary(
fun = median, linewidth = 1, geom = "line",
aes(group = 1, linetype = "Median +/- 80% CI")
)
g53 <- g53 + stat_summary(
fun.data = function(x) tern::stat_median_ci(x, conf_level = 0.8),
geom = "errorbar", aes(group = 1, linetype = "Median +/- 80% CI")
)
plot <- g53 + guides(linetype = guide_legend(title = NULL))
plot
```
```{r include = FALSE}
webr_code_labels <- c("plot53")
```
{{< include ../../_utils/webr.qmd >}}
:::
## Data Setup
```{r setup}
#| code-fold: show
```
::::::::::
{{< include ../../_utils/save_results.qmd >}}
{{< include ../../repro.qmd >}}