pharmaverse examples
  1. ADaM
  2. ADTTE
  • Introduction

  • SDTM
    • SDTM Examples
  • ADaM
    • ADSL
    • ADPC
    • ADPPK
    • ADRS
    • ADTTE
    • ADVS
    • ADAE
  • TLG
    • Demographic Table
    • Adverse Events
    • Pharmacokinetic
  • Interactive
    • teal applications
  • Logs
    • The Difference Between logr, logrx, and whirl
  • eSubmission
    • eSubmission

  • Session Info
  • Pharmaverse Home
  1. ADaM
  2. ADTTE

ADTTE

Introduction

This article provides a step-by-step explanation for creating an ADaM ADTTE (Time-to-Event) dataset with common oncology endpoint parameters using key pharmaverse packages along with tidyverse components. ADTTE datasets often involve calculating time-to-event variables for endpoints such as Overall Survival (OS) and Progression-Free Survival (PFS).

For the purpose of this example, we will use the ADSL and ADRS_ONCO datasets from {pharmaverseadam}.

Load Required Packages

First, we will load the necessary packages:

library(admiral)
library(admiralonco)
library(dplyr)
library(lubridate)
library(metacore)
library(metatools)
library(xportr)
library(pharmaverseadam)

Load Specifications and Source Data

We will load our specification file into a {metacore} object to trace the dataset variables and attributes. Then, we will read the source data.

# Load metacore specifications
metacore <- spec_to_metacore("./metadata/onco_spec.xlsx") %>%
  select_dataset("ADTTE")

# Load source datasets
adsl <- pharmaverseadam::adsl
adrs <- pharmaverseadam::adrs_onco

adrs <- adrs_onco

Define Event and Censoring Sources

We define event and censoring sources using the admiral::event_source() and admiral::censor_source() functions. This forms the basis for calculating time-to-event endpoints. Find other {admiral} functions and related variables by searching admiraldiscovery.

# Define event and censoring sources
death_event <- event_source(
  dataset_name = "adrs",
  filter = PARAMCD == "DEATH" & AVALC == "Y" & ANL01FL == "Y",
  date = ADT,
  set_values_to = exprs(
    EVNTDESC = "Death",
    SRCDOM = "ADRS",
    SRCVAR = "ADT"
  )
)

pd_event <- event_source(
  dataset_name = "adrs",
  filter = PARAMCD == "PD" & ANL01FL == "Y",
  date = ADT,
  set_values_to = exprs(
    EVNTDESC = "Progressive Disease",
    SRCDOM = "ADRS",
    SRCVAR = "ADT"
  )
)

lastalive_censor <- censor_source(
  dataset_name = "adsl",
  date = LSTALVDT,
  set_values_to = exprs(
    EVNTDESC = "Last Known Alive",
    CNSDTDSC = "Last Known Alive Date",
    SRCDOM = "ADSL",
    SRCVAR = "LSTALVDT"
  )
)

lasta_censor <- censor_source(
  dataset_name = "adrs",
  filter = PARAMCD == "LSTA" & ANL01FL == "Y",
  date = ADT,
  set_values_to = exprs(
    EVNTDESC = "Progression Free Alive",
    CNSDTDSC = "Last Tumor Assessment",
    SRCDOM = "ADRS",
    SRCVAR = "ADT"
  )
)

rand_censor <- censor_source(
  dataset_name = "adsl",
  date = RANDDT,
  set_values_to = exprs(
    EVNTDESC = "Randomization Date",
    CNSDTDSC = "Randomization Date",
    SRCDOM = "ADSL",
    SRCVAR = "RANDDT"
  )
)

Derive Time-to-Event Parameters

The admiral::derive_param_tte() function is used to derive parameters such as OS (Overall Survival) and PFS (Progression-Free Survival).

# Derive Overall Survival (OS)
adtte <- derive_param_tte(
  dataset_adsl = adsl,
  start_date = RANDDT,
  event_conditions = list(death_event),
  censor_conditions = list(lastalive_censor, rand_censor),
  source_datasets = list(adsl = adsl, adrs = adrs),
  set_values_to = exprs(PARAMCD = "OS", PARAM = "Overall Survival")
)

# Derive Progression-Free Survival (PFS)
adtte_pfs <- adtte %>%
  derive_param_tte(
    dataset_adsl = adsl,
    start_date = RANDDT,
    event_conditions = list(pd_event, death_event),
    censor_conditions = list(lasta_censor, rand_censor),
    source_datasets = list(adsl = adsl, adrs = adrs),
    set_values_to = exprs(PARAMCD = "PFS", PARAM = "Progression-Free Survival")
  )

Sample of Data

Derive Analysis Value (AVAL)

The analysis value (AVAL) can be derived by calling the admiral::derive_vars_duration() function.

# Derive analysis value
adtte_aval <- adtte_pfs %>%
  derive_vars_duration(
    new_var = AVAL,
    start_date = STARTDT,
    end_date = ADT
  )

Sample of Data

Derive Analysis Sequence Number (ASEQ)

We derive the sequence number for each record to uniquely identify them using the admiral::derive_var_obs_number() function.

# Derive analysis sequence number
adtte_aseq <- adtte_aval %>%
  derive_var_obs_number(
    by_vars = exprs(STUDYID, USUBJID),
    order = exprs(PARAMCD),
    check_type = "error"
  )

Add ADSL Variables

Additional variables from the ADSL dataset are merged into the ADTTE dataset using the admiral::derive_vars_merged() function to enrich it.

# Add ADSL variables
adtte_adsl <- adtte_aseq %>%
  derive_vars_merged(
    dataset_add = adsl,
    by_vars = exprs(STUDYID, USUBJID)
  )

Apply Metadata and eSub Checks

We use {metatools} and {xportr} to perform checks, apply metadata such as types, lengths, labels, and write the dataset to an XPT file.

# Apply metadata and perform checks
adtte_adsl_checked <- adtte_adsl %>%
  add_variables(metacore) %>%
  drop_unspec_vars(metacore) %>%
  check_variables(metacore) %>%
  check_ct_data(metacore) %>%
  order_cols(metacore) %>%
  sort_by_key(metacore)

# Apply apply labels, formats, and export the dataset to an XPT file.
adtte_final <- adtte_adsl_checked %>%
  xportr_type(metacore, domain = "ADTTE") %>%
  xportr_length(metacore) %>%
  xportr_label(metacore) %>%
  xportr_df_label(metacore)

# Write dataset to XPT file (optional)
dir <- tempdir()
xportr_write(adtte_final, file.path(dir, "adtte.xpt"))
ADRS
ADVS
Source Code
---
title: "ADTTE"
order: 5
---

```{r setup script, include=FALSE, purl=FALSE}
invisible_hook_purl <- function(before, options, ...) {
  knitr::hook_purl(before, options, ...)
  NULL
}
knitr::knit_hooks$set(purl = invisible_hook_purl)
source("functions/print_df.R")
```

# Introduction

This article provides a step-by-step explanation for creating an ADaM `ADTTE` (Time-to-Event) dataset with common oncology endpoint parameters using key pharmaverse packages along with tidyverse components. `ADTTE` datasets often involve calculating time-to-event variables for endpoints such as Overall Survival (OS) and Progression-Free Survival (PFS).

For the purpose of this example, we will use the `ADSL` and `ADRS_ONCO` datasets from `{pharmaverseadam}`.

# Load Required Packages

First, we will load the necessary packages:

```{r message=FALSE, warning=FALSE}
library(admiral)
library(admiralonco)
library(dplyr)
library(lubridate)
library(metacore)
library(metatools)
library(xportr)
library(pharmaverseadam)
```

# Load Specifications and Source Data

We will load our specification file into a `{metacore}` object to trace the dataset variables and attributes. Then, we will read the source data.

```{r read-specs}
#| warning: false

# Load metacore specifications
metacore <- spec_to_metacore("./metadata/onco_spec.xlsx") %>%
  select_dataset("ADTTE")

# Load source datasets
adsl <- pharmaverseadam::adsl
adrs <- pharmaverseadam::adrs_onco

adrs <- adrs_onco
```

# Define Event and Censoring Sources

We define event and censoring sources using the `admiral::event_source()` and `admiral::censor_source()` functions. This forms the basis for calculating time-to-event endpoints. Find other `{admiral}` functions and related variables by searching [admiraldiscovery](<https://pharmaverse.github.io/admiraldiscovery/articles/reactable.html>).

```{r}
# Define event and censoring sources
death_event <- event_source(
  dataset_name = "adrs",
  filter = PARAMCD == "DEATH" & AVALC == "Y" & ANL01FL == "Y",
  date = ADT,
  set_values_to = exprs(
    EVNTDESC = "Death",
    SRCDOM = "ADRS",
    SRCVAR = "ADT"
  )
)

pd_event <- event_source(
  dataset_name = "adrs",
  filter = PARAMCD == "PD" & ANL01FL == "Y",
  date = ADT,
  set_values_to = exprs(
    EVNTDESC = "Progressive Disease",
    SRCDOM = "ADRS",
    SRCVAR = "ADT"
  )
)

lastalive_censor <- censor_source(
  dataset_name = "adsl",
  date = LSTALVDT,
  set_values_to = exprs(
    EVNTDESC = "Last Known Alive",
    CNSDTDSC = "Last Known Alive Date",
    SRCDOM = "ADSL",
    SRCVAR = "LSTALVDT"
  )
)

lasta_censor <- censor_source(
  dataset_name = "adrs",
  filter = PARAMCD == "LSTA" & ANL01FL == "Y",
  date = ADT,
  set_values_to = exprs(
    EVNTDESC = "Progression Free Alive",
    CNSDTDSC = "Last Tumor Assessment",
    SRCDOM = "ADRS",
    SRCVAR = "ADT"
  )
)

rand_censor <- censor_source(
  dataset_name = "adsl",
  date = RANDDT,
  set_values_to = exprs(
    EVNTDESC = "Randomization Date",
    CNSDTDSC = "Randomization Date",
    SRCDOM = "ADSL",
    SRCVAR = "RANDDT"
  )
)
```

# Derive Time-to-Event Parameters

The `admiral::derive_param_tte()` function is used to derive parameters such as OS (Overall Survival) and PFS (Progression-Free Survival).

```{r}
# Derive Overall Survival (OS)
adtte <- derive_param_tte(
  dataset_adsl = adsl,
  start_date = RANDDT,
  event_conditions = list(death_event),
  censor_conditions = list(lastalive_censor, rand_censor),
  source_datasets = list(adsl = adsl, adrs = adrs),
  set_values_to = exprs(PARAMCD = "OS", PARAM = "Overall Survival")
)

# Derive Progression-Free Survival (PFS)
adtte_pfs <- adtte %>%
  derive_param_tte(
    dataset_adsl = adsl,
    start_date = RANDDT,
    event_conditions = list(pd_event, death_event),
    censor_conditions = list(lasta_censor, rand_censor),
    source_datasets = list(adsl = adsl, adrs = adrs),
    set_values_to = exprs(PARAMCD = "PFS", PARAM = "Progression-Free Survival")
  )
```


```{r eval=TRUE, echo=FALSE, purl=FALSE}
print_df(adtte_pfs, n = 10)
```

# Derive Analysis Value (`AVAL`)

The analysis value (`AVAL`) can be derived by calling the `admiral::derive_vars_duration()` function.

```{r}
# Derive analysis value
adtte_aval <- adtte_pfs %>%
  derive_vars_duration(
    new_var = AVAL,
    start_date = STARTDT,
    end_date = ADT
  )
```


```{r eval=TRUE, echo=FALSE, purl=FALSE}
print_df(adtte_aval, n = 10)
```

# Derive Analysis Sequence Number (`ASEQ`)

We derive the sequence number for each record to uniquely identify them using the `admiral::derive_var_obs_number()` function.

```{r}
# Derive analysis sequence number
adtte_aseq <- adtte_aval %>%
  derive_var_obs_number(
    by_vars = exprs(STUDYID, USUBJID),
    order = exprs(PARAMCD),
    check_type = "error"
  )
```

# Add ADSL Variables

Additional variables from the `ADSL` dataset are merged into the `ADTTE` dataset using the `admiral::derive_vars_merged()` function to enrich it.

```{r}
# Add ADSL variables
adtte_adsl <- adtte_aseq %>%
  derive_vars_merged(
    dataset_add = adsl,
    by_vars = exprs(STUDYID, USUBJID)
  )
```

# Apply Metadata and eSub Checks

We use `{metatools}` and `{xportr}` to perform checks, apply metadata such as types, lengths, labels, and write the dataset to an XPT file.

```{r, message=FALSE, warning=FALSE}
# Apply metadata and perform checks
adtte_adsl_checked <- adtte_adsl %>%
  add_variables(metacore) %>%
  drop_unspec_vars(metacore) %>%
  check_variables(metacore) %>%
  check_ct_data(metacore) %>%
  order_cols(metacore) %>%
  sort_by_key(metacore)

# Apply apply labels, formats, and export the dataset to an XPT file.
adtte_final <- adtte_adsl_checked %>%
  xportr_type(metacore, domain = "ADTTE") %>%
  xportr_length(metacore) %>%
  xportr_label(metacore) %>%
  xportr_df_label(metacore)

# Write dataset to XPT file (optional)
dir <- tempdir()
xportr_write(adtte_final, file.path(dir, "adtte.xpt"))
```
 
Cookie Preferences