---
title: EXT01
subtitle: Study Drug Exposure Table
---
------------------------------------------------------------------------
{{< include ../../_utils/envir_hook.qmd >}}
```{r setup, echo = FALSE, warning = FALSE, message = FALSE}
library(tern)
library(dplyr)
library(tidyr)
adsl <- random.cdisc.data::cadsl
adex <- random.cdisc.data::cadex
# Ensure character variables are converted to factors and empty strings and NAs are explicit missing levels.
adsl <- df_explicit_na(adsl)
adex <- df_explicit_na(adex)
adex <- adex %>%
filter(PARCAT1 == "OVERALL") %>%
select(STUDYID, USUBJID, ACTARM, PARAMCD, PARAM, AVAL, PARCAT2) %>%
mutate(
PARAMCD = as.character(PARAMCD),
AVALC = ""
) %>%
droplevels()
# Add new param tdurd for treatment duration.
set.seed(99)
tdurd_adsl <- adsl %>%
select(STUDYID, USUBJID, ACTARM) %>%
mutate(
PARAMCD = "TDURD",
PARAM = "Overall duration (days)",
AVAL = sample(1:150, size = nrow(adsl), replace = TRUE),
AVALC = case_when(
0 <= AVAL & AVAL <= 30 ~ "0 - 30",
31 <= AVAL & AVAL <= 60 ~ "31 - 60",
61 <= AVAL & AVAL <= 90 ~ "61 - 90",
TRUE ~ ">= 91"
)
)
tdurd <- adex %>%
filter(PARAMCD == "TNDOSE") %>%
select(STUDYID, USUBJID, PARCAT2) %>%
left_join(tdurd_adsl, by = c("STUDYID", "USUBJID"))
# Add new param tndosmis for missed doses.
tndosmis_adsl <- adsl %>%
select(STUDYID, USUBJID, ACTARM) %>%
mutate(
PARAMCD = "TNDOSMIS",
PARAM = "Total number of missed doses during study",
AVAL = sample(0:20, size = nrow(adsl), replace = TRUE),
AVALC = ""
)
tndosmis <- adex %>%
filter(PARAMCD == "TNDOSE") %>%
select(STUDYID, USUBJID, PARCAT2) %>%
left_join(tndosmis_adsl, by = c("STUDYID", "USUBJID"))
adex <- dplyr::bind_rows(adex, tdurd, tndosmis) %>%
mutate(PARAM = factor(
PARAM,
levels = c(
"Overall duration (days)", "Total dose administered", "Total number of doses administered",
"Total number of missed doses during study"
)
))
```
```{r include = FALSE}
webr_code_labels <- c("setup")
```
{{< include ../../_utils/webr_no_include.qmd >}}
## Output
:::::: panel-tabset
## Standard Table
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
```{r variant1, test = list(result_v1 = "result")}
# When summary table contains only categorical or only numeric parameters
split_fun <- drop_split_levels
lyt <- basic_table(show_colcounts = TRUE) %>%
split_cols_by("ACTARM") %>%
split_rows_by("PARCAT2", split_label = "\nParameter Category (Drug A/Drug B)", label_pos = "topleft") %>%
split_rows_by("PARAM", split_fun = split_fun) %>%
analyze_vars(vars = "AVAL")
result <- build_table(lyt = lyt, df = adex, alt_counts_df = adsl)
result
```
```{r include = FALSE}
webr_code_labels <- c("variant1")
```
{{< include ../../_utils/webr.qmd >}}
:::
## Table with Optional Analyses
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
```{r variant2, test = list(result_v2 = "result")}
# When summary table contains both categorical and numeric parameters,
# developer needs to do pre-processing to transform dataset to wide format.
adex_avalc_wide <- adex %>%
filter(PARAMCD == "TDURD") %>%
select(STUDYID, USUBJID, PARAMCD, AVALC, PARCAT2) %>%
tidyr::pivot_wider(
id_cols = c(STUDYID, USUBJID, PARCAT2),
names_from = PARAMCD,
values_from = AVALC
) %>%
mutate(
TDURDC = factor(TDURD, levels = c("0 - 30", "31 - 60", "61 - 90", ">= 91"))
) %>%
select(-TDURD)
anl <- adex %>%
select(STUDYID, USUBJID, ACTARM, PARAMCD, AVAL, PARCAT2) %>%
tidyr::pivot_wider(
id_cols = c(STUDYID, USUBJID, ACTARM, PARCAT2),
names_from = PARAMCD,
values_from = AVAL
) %>%
left_join(adex_avalc_wide, by = c("STUDYID", "USUBJID", "PARCAT2")) %>%
var_relabel(
TDOSE = "Total dose administered",
TNDOSE = "Total number of doses administered",
TDURD = "Overall duration (days)",
TNDOSMIS = "Total number of missed doses during study",
TDURDC = "Overall duration (days)"
)
lyt <- basic_table(show_colcounts = TRUE) %>%
split_cols_by("ACTARM") %>%
split_rows_by("PARCAT2", split_label = "\nParameter Category (Drug A/Drug B)", label_pos = "topleft") %>%
analyze_vars(
vars = c("TDURD", "TDURDC", "TDOSE", "TNDOSE"),
var_labels = var_labels(anl)[c("TDURD", "TDURDC", "TDOSE", "TNDOSE")]
)
result <- build_table(lyt = lyt, df = anl, alt_counts_df = adsl)
result
```
```{r include = FALSE}
webr_code_labels <- c("variant2")
```
{{< include ../../_utils/webr.qmd >}}
:::
## Table with User-Specified <br/> Categories for Missed Doses
::: {.panel-tabset .nav-justified group="webr"}
## {{< fa regular file-lines sm fw >}} Preview
```{r variant3, test = list(result_v3 = "result")}
# When summary table contains both categorical and numeric parameters,
# developer needs to do pre-processing to transform dataset to wide format.
adex_avalc_wide <- adex %>%
filter(PARAMCD == "TDURD") %>%
select(STUDYID, USUBJID, PARAMCD, AVALC, PARCAT2) %>%
tidyr::pivot_wider(
id_cols = c(STUDYID, USUBJID, PARCAT2),
names_from = PARAMCD,
values_from = AVALC
) %>%
mutate(
TDURDC = factor(TDURD, levels = c("0 - 30", "31 - 60", "61 - 90", ">= 91"))
) %>%
select(-TDURD)
anl <- adex %>%
select(STUDYID, USUBJID, ACTARM, PARAMCD, AVAL, PARCAT2) %>%
tidyr::pivot_wider(
id_cols = c(STUDYID, USUBJID, ACTARM, PARCAT2),
names_from = PARAMCD,
values_from = AVAL
) %>%
left_join(adex_avalc_wide, by = c("STUDYID", "USUBJID", "PARCAT2")) %>%
var_relabel(
TDOSE = "Total dose administered",
TNDOSE = "Total number of doses administered",
TDURD = "Overall duration (days)",
TNDOSMIS = "Total number of missed doses during study",
TDURDC = "Overall duration (days)"
)
lyt <- basic_table(show_colcounts = TRUE) %>%
split_cols_by("ACTARM") %>%
split_rows_by("PARCAT2", split_label = "\nParameter Category (Drug A/Drug B)", label_pos = "topleft") %>%
analyze_vars(
vars = c("TDURD", "TDURDC", "TDOSE", "TNDOSE"),
var_labels = var_labels(anl)[c("TDURD", "TDURDC", "TDOSE", "TNDOSE")]
) %>%
count_missed_doses(
"TNDOSMIS",
thresholds = c(1, 5, 10, 15),
var_labels = "Missed Doses"
)
result <- build_table(lyt = lyt, df = anl, alt_counts_df = adsl)
result
```
```{r include = FALSE}
webr_code_labels <- c("variant3")
```
{{< include ../../_utils/webr.qmd >}}
:::
## Data Setup
```{r setup}
#| code-fold: show
```
::::::
{{< include ../../_utils/save_results.qmd >}}
## `teal` App
::: {.panel-tabset .nav-justified}
## {{< fa regular file-lines fa-sm fa-fw >}} Preview
```{r teal, opts.label = c("skip_if_testing", "app")}
library(teal.modules.clinical)
## Data reproducible code
data <- teal_data()
data <- within(data, {
library(dplyr)
ADSL <- random.cdisc.data::cadsl
ADEX <- random.cdisc.data::cadex
adex_labels <- unname(col_labels(ADEX))
ADEX <- ADEX %>%
filter(PARCAT1 == "OVERALL") %>%
mutate(
AVALCAT1 = case_when(
PARAMCD == "TDOSE" & AVAL < 5000 ~ "LOW",
PARAMCD == "TDOSE" & AVAL >= 5000 ~ "HIGH",
PARAMCD == "TNDOSE" & AVAL < 10 ~ "< 10",
PARAMCD == "TNDOSE" & AVAL >= 10 ~ ">= 10"
)
)
col_labels(ADEX) <- c(adex_labels, "")
})
datanames <- c("ADSL", "ADEX")
names(data) <- datanames
join_keys(data) <- default_cdisc_join_keys[datanames]
## Reusable Configuration For Modules
ADEX <- data[["ADEX"]]
## Setup App
app <- init(
data = data,
modules = modules(
tm_t_summary_by(
label = "Exposure Table",
dataname = "ADEX",
arm_var = choices_selected(
choices = variable_choices(ADEX, c("ARM", "ARMCD")),
selected = "ARM"
),
by_vars = choices_selected(
choices = variable_choices(ADEX, c("PARCAT2", "PARAM")),
selected = c("PARCAT2", "PARAM")
),
summarize_vars = choices_selected(
choices = variable_choices(ADEX, c("AVAL", "AVALCAT1")),
selected = c("AVAL", "AVALCAT1")
),
paramcd = choices_selected(
choices = value_choices(ADEX, "PARAMCD", "PARAM"),
selected = c("TDOSE", "TNDOSE")
),
denominator = choices_selected(
choices = c("n", "N", "omit"),
selected = "N"
)
)
), # Set initial filter state as single study drug to produce smaller table
filter = teal_slices(
teal_slice("ADEX", "PARCAT2", selected = "Drug A"),
teal_slice("ADEX", "AVAL", selected = NULL)
)
)
shinyApp(app$ui, app$server)
```
{{< include ../../_utils/shinylive.qmd >}}
:::
{{< include ../../repro.qmd >}}