pharmaverse examples
  1. ADaM
  2. ADRS
  • 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. ADRS

ADRS

Introduction

The Response Analysis Dataset (ADRS) is an essential part of oncology clinical trials for monitoring disease response and progression. This article describes how to create an ADRS ADaM dataset, focusing on common oncology endpoint parameters based on RECIST v1.1 criteria. The primary response values include CR (Complete Response), PR (Partial Response), SD (Stable Disease), NON-CR/NON-PD (Non-CR/Non-PD), PD (Progressive Disease), and NE (Not Evaluable). See {admiral} and {admiralonco} for more information. Find other {admiral} functions and related variables by searching admiraldiscovery

This guide uses key pharmaverse packages along with tidyverse components to demonstrate the step-by-step process, ensuring the inclusion of metadata, validation, and exporting to a compliant SAS transport file (XPT).

Load Packages

First, we load the necessary packages required for creating the ADRS dataset.

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

Load Specifications for Metacore

Load the specifications stored in an Excel file into a {metacore} object.

metacore <- spec_to_metacore("./metadata/onco_spec.xlsx") %>%
  select_dataset("ADRS")

Load Source Datasets

We load the required SDTM datasets (RS, TU) and ADaM dataset (ADSL) necessary for creating the ADRS dataset.

adsl <- pharmaverseadam::adsl
rs <- pharmaversesdtm::rs_onco_recist
tu <- pharmaversesdtm::tu_onco_recist

# Convert blanks to NA
rs <- convert_blanks_to_na(rs)
tu <- convert_blanks_to_na(tu)

Sample of Data

Merging ADSL with RS

Merge ADSL to the RS domain by selecting only the necessary variables for derivations.

adsl_vars <- exprs(RANDDT)
adrs_merged <- derive_vars_merged(
  rs,
  dataset_add = adsl,
  new_vars = adsl_vars,
  by_vars = exprs(STUDYID, USUBJID)
)

Pre-processing of Input Records

Select Overall Response Records and Set Parameter Details

Filter the RS domain to include only overall response records assessed by the investigator and set the parameter details accordingly.

adrs_ovr <- adrs_merged %>%
  filter(RSEVAL == "INVESTIGATOR" & RSTESTCD == "OVRLRESP") %>%
  mutate(
    PARAMCD = "OVR",
    PARAM = "Overall Response by Investigator",
    PARCAT1 = "Tumor Response",
    PARCAT2 = "Investigator",
    PARCAT3 = "RECIST 1.1"
  )

Date Imputation and Deriving ADT, ADTF, AVISIT

Impute missing dates and derive analysis dates and visits.

adrs_imputed <- adrs_ovr %>%
  derive_vars_dt(
    dtc = RSDTC,
    new_vars_prefix = "A",
    highest_imputation = "D",
    date_imputation = "last"
  ) %>%
  mutate(AVISIT = VISIT)

Derive AVALC and AVAL

Populate AVALC with assessed values and create the numeric version AVAL.

adrs_aval <- adrs_imputed %>%
  mutate(
    AVALC = RSSTRESC,
    AVAL = aval_resp(AVALC)
  )

Flag Worst Assessment at Each Date (ANL01FL)

Flag the worst assessment at each date, considering only valid assessments from the randomization date onward.

worst_resp <- function(arg) {
  case_when(
    arg == "NE" ~ 1,
    arg == "CR" ~ 2,
    arg == "PR" ~ 3,
    arg == "SD" ~ 4,
    arg == "NON-CR/NON-PD" ~ 5,
    arg == "PD" ~ 6,
    TRUE ~ 0
  )
}

adrs_anl01fl <- adrs_aval %>%
  restrict_derivation(
    derivation = derive_var_extreme_flag,
    args = params(
      by_vars = exprs(STUDYID, USUBJID, ADT),
      order = exprs(worst_resp(AVALC), RSSEQ),
      new_var = ANL01FL,
      mode = "last"
    ),
    filter = !is.na(AVAL) & ADT >= RANDDT
  )

Sample of Data

Deriving Parameters

Derive Progressive Disease Parameter

Use the admiral::derive_extreme_records() function to find the date of first PD.

adrs_pd <- adrs_anl01fl %>%
  derive_extreme_records(
    dataset_ref = adsl,
    dataset_add = adrs_anl01fl,
    by_vars = exprs(STUDYID, USUBJID),
    filter_add = PARAMCD == "OVR" & AVALC == "PD" & ANL01FL == "Y",
    order = exprs(ADT, RSSEQ),
    mode = "first",
    exist_flag = AVALC,
    false_value = "N",
    set_values_to = exprs(
      PARAMCD = "PD",
      PARAM = "Disease Progression by Investigator",
      PARCAT1 = "Tumor Response",
      PARCAT2 = "Investigator",
      PARCAT3 = "RECIST 1.1",
      AVAL = yn_to_numeric(AVALC),
      ANL01FL = "Y"
    )
  )

Sample of Data

Derive Death Parameter

Create a new death parameter using the death date from ADSL.

adsldth <- adsl %>%
  select(STUDYID, USUBJID, DTHDT, !!!adsl_vars)

adrs_death <- adrs_pd %>%
  derive_extreme_records(
    dataset_ref = adsldth,
    dataset_add = adsldth,
    by_vars = exprs(STUDYID, USUBJID),
    filter_add = !is.na(DTHDT),
    exist_flag = AVALC,
    false_value = "N",
    set_values_to = exprs(
      PARAMCD = "DEATH",
      PARAM = "Death",
      PARCAT1 = "Reference Event",
      AVAL = yn_to_numeric(AVALC),
      ANL01FL = "Y",
      ADT = DTHDT
    )
  ) %>%
  select(-DTHDT)

Derive Last Disease Assessment Parameter

Create a parameter for the last disease assessment.

adrs_lsta <- adrs_death %>%
  derive_extreme_records(
    dataset_ref = adsl,
    dataset_add = adrs_death,
    by_vars = exprs(STUDYID, USUBJID),
    filter_add = PARAMCD == "OVR" & ANL01FL == "Y",
    order = exprs(ADT, RSSEQ),
    mode = "last",
    set_values_to = exprs(
      PARAMCD = "LSTA",
      PARAM = "Last Disease Assessment by Investigator",
      PARCAT1 = "Tumor Response",
      PARCAT2 = "Investigator",
      PARCAT3 = "RECIST 1.1",
      ANL01FL = "Y"
    )
  )

Sample of Data

Apply Metadata and Perform Associated Checks

Apply metadata and conduct checks to ensure data quality and compliance.

adrs_checked <- adrs_lsta %>%
  add_variables(metacore) %>% # Add variables specified in the metadata
  drop_unspec_vars(metacore) %>% # Drop variables not specified in metadata
  check_variables(metacore) %>% # Check all variables specified are present and no more
  check_ct_data(metacore) %>% # Check controlled terminology
  order_cols(metacore) %>% # Order columns according to metadata
  sort_by_key(metacore) # Sort rows by sort keys

Apply Labels and Formats with xportr

Finally, apply labels, formats, and export the dataset to an XPT file.

dir <- tempdir() # Specify the directory for saving the XPT file

adrs_xpt <- adrs_checked %>%
  xportr_type(metacore, domain = "ADRS") %>% # Coerce variable types to match metadata
  xportr_length(metacore) %>% # Assign variable lengths from metadata
  xportr_label(metacore) %>% # Assign variable labels from metadata
  xportr_format(metacore) %>% # Assign variable formats from metadata
  xportr_df_label(metacore) %>% # Assign dataset labels from metadata
  xportr_write(file.path(dir, "adrs.xpt")) # Write the XPT file
── Variable type mismatches found. ──
✔ 1 variable coerced
Warning: Column `STUDYID` contains string values longer than user width 8.
Width set to 12 to accommodate.
ADPPK
ADTTE
Source Code
---
title: "ADRS"
order: 4
---

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

The Response Analysis Dataset (`ADRS`) is an essential part of oncology clinical trials for monitoring disease response and progression. This article describes how to create an `ADRS` ADaM dataset, focusing on common oncology endpoint parameters based on RECIST v1.1 criteria. The primary response values include `CR` (Complete Response), `PR` (Partial Response), `SD` (Stable Disease), `NON-CR/NON-PD` (Non-CR/Non-PD), `PD` (Progressive Disease), and `NE` (Not Evaluable). See `{admiral}` and `{admiralonco}` for more information. Find other `{admiral}` functions and related variables by searching [admiraldiscovery](<https://pharmaverse.github.io/admiraldiscovery/articles/reactable.html>)

This guide uses key pharmaverse packages along with tidyverse components to demonstrate the step-by-step process, ensuring the inclusion of metadata, validation, and exporting to a compliant SAS transport file (XPT).

# Load Packages

First, we load the necessary packages required for creating the `ADRS` dataset.

```{r setup, message=FALSE, warning=FALSE, results='hold'}
library(admiral)
library(admiralonco)
library(metacore)
library(metatools)
library(xportr)
library(pharmaversesdtm)
library(pharmaverseadam)
library(dplyr)
library(lubridate)
library(stringr)
```

# Load Specifications for Metacore

Load the specifications stored in an Excel file into a `{metacore}` object.

```{r read-specs}
#| warning: false
metacore <- spec_to_metacore("./metadata/onco_spec.xlsx") %>%
  select_dataset("ADRS")
```

# Load Source Datasets

We load the required SDTM datasets (`RS`, `TU`) and ADaM dataset (`ADSL`) necessary for creating the `ADRS` dataset.

```{r load-data}
adsl <- pharmaverseadam::adsl
rs <- pharmaversesdtm::rs_onco_recist
tu <- pharmaversesdtm::tu_onco_recist

# Convert blanks to NA
rs <- convert_blanks_to_na(rs)
tu <- convert_blanks_to_na(tu)
```

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


# Merging ADSL with RS

Merge `ADSL` to the `RS` domain by selecting only the necessary variables for derivations.

```{r merge-adsl-rs}
adsl_vars <- exprs(RANDDT)
adrs_merged <- derive_vars_merged(
  rs,
  dataset_add = adsl,
  new_vars = adsl_vars,
  by_vars = exprs(STUDYID, USUBJID)
)
```

# Pre-processing of Input Records

## Select Overall Response Records and Set Parameter Details

Filter the `RS` domain to include only overall response records assessed by the investigator and set the parameter details accordingly.

```{r set-param-details}
adrs_ovr <- adrs_merged %>%
  filter(RSEVAL == "INVESTIGATOR" & RSTESTCD == "OVRLRESP") %>%
  mutate(
    PARAMCD = "OVR",
    PARAM = "Overall Response by Investigator",
    PARCAT1 = "Tumor Response",
    PARCAT2 = "Investigator",
    PARCAT3 = "RECIST 1.1"
  )
```

## Date Imputation and Deriving `ADT`, `ADTF`, `AVISIT`

Impute missing dates and derive analysis dates and visits.

```{r impute-dates}
adrs_imputed <- adrs_ovr %>%
  derive_vars_dt(
    dtc = RSDTC,
    new_vars_prefix = "A",
    highest_imputation = "D",
    date_imputation = "last"
  ) %>%
  mutate(AVISIT = VISIT)
```

## Derive `AVALC` and `AVAL`

Populate `AVALC` with assessed values and create the numeric version `AVAL`.

```{r derive-aval}
adrs_aval <- adrs_imputed %>%
  mutate(
    AVALC = RSSTRESC,
    AVAL = aval_resp(AVALC)
  )
```

## Flag Worst Assessment at Each Date (`ANL01FL`)

Flag the worst assessment at each date, considering only valid assessments from the randomization date onward.

```{r flag-worst-assessment}
worst_resp <- function(arg) {
  case_when(
    arg == "NE" ~ 1,
    arg == "CR" ~ 2,
    arg == "PR" ~ 3,
    arg == "SD" ~ 4,
    arg == "NON-CR/NON-PD" ~ 5,
    arg == "PD" ~ 6,
    TRUE ~ 0
  )
}

adrs_anl01fl <- adrs_aval %>%
  restrict_derivation(
    derivation = derive_var_extreme_flag,
    args = params(
      by_vars = exprs(STUDYID, USUBJID, ADT),
      order = exprs(worst_resp(AVALC), RSSEQ),
      new_var = ANL01FL,
      mode = "last"
    ),
    filter = !is.na(AVAL) & ADT >= RANDDT
  )
```


```{r eval=TRUE, echo=FALSE, purl=FALSE}
print_df(adrs_anl01fl %>% select(USUBJID, PARAMCD, ADT, AVAL, AVALC, ANL01FL), n = 10)
```

# Deriving Parameters

## Derive Progressive Disease Parameter

Use the `admiral::derive_extreme_records()` function to find the date of first `PD`.

```{r derive-pd}
adrs_pd <- adrs_anl01fl %>%
  derive_extreme_records(
    dataset_ref = adsl,
    dataset_add = adrs_anl01fl,
    by_vars = exprs(STUDYID, USUBJID),
    filter_add = PARAMCD == "OVR" & AVALC == "PD" & ANL01FL == "Y",
    order = exprs(ADT, RSSEQ),
    mode = "first",
    exist_flag = AVALC,
    false_value = "N",
    set_values_to = exprs(
      PARAMCD = "PD",
      PARAM = "Disease Progression by Investigator",
      PARCAT1 = "Tumor Response",
      PARCAT2 = "Investigator",
      PARCAT3 = "RECIST 1.1",
      AVAL = yn_to_numeric(AVALC),
      ANL01FL = "Y"
    )
  )
```


```{r eval=TRUE, echo=FALSE, purl=FALSE}
print_df(adrs_pd %>% select(USUBJID, PARAMCD, ADT, AVAL, AVALC, ANL01FL) %>% filter(PARAMCD == "PD"), n = 10)
```

## Derive Death Parameter

Create a new death parameter using the death date from `ADSL`.

```{r derive-death}
adsldth <- adsl %>%
  select(STUDYID, USUBJID, DTHDT, !!!adsl_vars)

adrs_death <- adrs_pd %>%
  derive_extreme_records(
    dataset_ref = adsldth,
    dataset_add = adsldth,
    by_vars = exprs(STUDYID, USUBJID),
    filter_add = !is.na(DTHDT),
    exist_flag = AVALC,
    false_value = "N",
    set_values_to = exprs(
      PARAMCD = "DEATH",
      PARAM = "Death",
      PARCAT1 = "Reference Event",
      AVAL = yn_to_numeric(AVALC),
      ANL01FL = "Y",
      ADT = DTHDT
    )
  ) %>%
  select(-DTHDT)
```

## Derive Last Disease Assessment Parameter

Create a parameter for the last disease assessment.

```{r derive-lsta}
adrs_lsta <- adrs_death %>%
  derive_extreme_records(
    dataset_ref = adsl,
    dataset_add = adrs_death,
    by_vars = exprs(STUDYID, USUBJID),
    filter_add = PARAMCD == "OVR" & ANL01FL == "Y",
    order = exprs(ADT, RSSEQ),
    mode = "last",
    set_values_to = exprs(
      PARAMCD = "LSTA",
      PARAM = "Last Disease Assessment by Investigator",
      PARCAT1 = "Tumor Response",
      PARCAT2 = "Investigator",
      PARCAT3 = "RECIST 1.1",
      ANL01FL = "Y"
    )
  )
```


```{r eval=TRUE, echo=FALSE, purl=FALSE}
print_df(adrs_lsta %>% select(USUBJID, PARAMCD, ADT, AVAL, AVALC, ANL01FL) %>% filter(PARAMCD == "LSTA"), n = 10)
```

# Apply Metadata and Perform Associated Checks

Apply metadata and conduct checks to ensure data quality and compliance.

```{r apply-metadata-check, message=FALSE, warning=FALSE}
adrs_checked <- adrs_lsta %>%
  add_variables(metacore) %>% # Add variables specified in the metadata
  drop_unspec_vars(metacore) %>% # Drop variables not specified in metadata
  check_variables(metacore) %>% # Check all variables specified are present and no more
  check_ct_data(metacore) %>% # Check controlled terminology
  order_cols(metacore) %>% # Order columns according to metadata
  sort_by_key(metacore) # Sort rows by sort keys
```

# Apply Labels and Formats with xportr

Finally, apply labels, formats, and export the dataset to an XPT file.

```{r xportr}
dir <- tempdir() # Specify the directory for saving the XPT file

adrs_xpt <- adrs_checked %>%
  xportr_type(metacore, domain = "ADRS") %>% # Coerce variable types to match metadata
  xportr_length(metacore) %>% # Assign variable lengths from metadata
  xportr_label(metacore) %>% # Assign variable labels from metadata
  xportr_format(metacore) %>% # Assign variable formats from metadata
  xportr_df_label(metacore) %>% # Assign dataset labels from metadata
  xportr_write(file.path(dir, "adrs.xpt")) # Write the XPT file
```
 
Cookie Preferences