Creating a BDS Exposure ADaM

Introduction

This article describes creating an Exposure ADaM using the BDS structure. Examples are currently presented using an underlying EX domain where the EX domain represents data as collected on the CRF and the ADEX ADaM is output. However, the examples can be applied to situations where an EC domain is used as input and/or ADEC or another exposure ADaM is created.

There are many different approaches to modeling exposure data. This vignette gives examples of creating PARAMCD and AVAL combinations using exposure data. This vignette is not meant to be a guide or standard for the structure of exposure analysis datasets.

Note: All examples assume CDISC SDTM and/or ADaM format as input unless otherwise specified.

Programming Workflow

Read in Data

To start, all data frames needed for the creation of ADEX should be read into the environment. This will be a company specific process. Some of the data frames needed may be EX and ADSL.

For example purpose, the CDISC Pilot SDTM and ADaM datasets—which are included in {pharmaversesdtm}—are used.

library(admiral)
library(dplyr, warn.conflicts = FALSE)
library(pharmaversesdtm)
library(lubridate)
library(stringr)
library(tibble)

ex <- pharmaversesdtm::ex
adsl <- admiral::admiral_adsl

ex <- convert_blanks_to_na(ex)

At this step, it may be useful to join ADSL to your EX domain as well. Only the ADSL variables used for derivations are selected at this step. The rest of the relevant ADSL variables would be added later.

adsl_vars <- exprs(TRTSDT, TRTSDTM, TRTEDT, TRTEDTM)

adex <- derive_vars_merged(
  ex,
  dataset_add = adsl,
  new_vars = adsl_vars,
  by_vars = get_admiral_option("subject_keys")
)
USUBJID EXTRT EXDOSE EXDOSFRQ VISIT EXSTDTC EXENDTC TRTSDTM TRTEDTM
01-701-1015 PLACEBO 0 QD BASELINE 2014-01-02 2014-01-16 2014-01-02 2014-07-02 23:59:59
01-701-1015 PLACEBO 0 QD WEEK 2 2014-01-17 2014-06-18 2014-01-02 2014-07-02 23:59:59
01-701-1015 PLACEBO 0 QD WEEK 24 2014-06-19 2014-07-02 2014-01-02 2014-07-02 23:59:59
01-701-1023 PLACEBO 0 QD BASELINE 2012-08-05 2012-08-27 2012-08-05 2012-09-01 23:59:59
01-701-1023 PLACEBO 0 QD WEEK 2 2012-08-28 2012-09-01 2012-08-05 2012-09-01 23:59:59
01-703-1086 XANOMELINE 54 QD BASELINE 2012-09-02 2012-09-16 2012-09-02 2012-12-04 23:59:59
01-703-1086 XANOMELINE 54 QD WEEK 2 2012-09-17 2012-12-04 2012-09-02 2012-12-04 23:59:59
01-703-1096 PLACEBO 0 QD BASELINE 2013-01-25 2013-02-09 2013-01-25 2013-03-16 23:59:59
01-703-1096 PLACEBO 0 QD WEEK 2 2013-02-10 2013-03-16 2013-01-25 2013-03-16 23:59:59
01-707-1037 XANOMELINE 54 QD BASELINE 2013-12-20 2013-12-24 2013-12-20 2013-12-24 23:59:59

The CDISC pilot EX domain data does not contain a dose adjustment flag or the planned dose information. For demonstration purposes, this will be added to the data.

adex <- adex %>%
  mutate(
    EXADJ = case_when(
      USUBJID == "01-701-1028" & VISIT %in% c("WEEK 2") ~ "ADVERSE EVENT",
      USUBJID == "01-701-1148" & VISIT %in% c("WEEK 2", "WEEK 24") ~ "MEDICATION ERROR",
      TRUE ~ NA_character_
    ),
    EXDOSE = case_when(
      USUBJID == "01-701-1028" & VISIT %in% c("WEEK 2") ~ 0,
      USUBJID == "01-701-1148" & VISIT %in% c("WEEK 2", "WEEK 24") ~ 0,
      TRUE ~ EXDOSE
    )
  ) %>%
  mutate(EXPLDOS = if_else(EXTRT == "PLACEBO", 0, 54))

distinct(adex, EXTRT, EXPLDOS)
#> # A tibble: 2 × 2
#>   EXTRT      EXPLDOS
#>   <chr>        <dbl>
#> 1 PLACEBO          0
#> 2 XANOMELINE      54
count(adex, EXADJ)
#> # A tibble: 1 × 2
#>   EXADJ     n
#>   <chr> <int>
#> 1 <NA>     13

Derive/Impute Numeric Date/Time and Analysis Day (ADT, ADTM, ADY, ADTF, ATMF)

The function derive_vars_dt() can be used to derive ADT. This function allows the user to impute the date as well.

Example calls:

adex <- derive_vars_dt(adex, new_vars_prefix = "AST", dtc = EXSTDTC)
adex <- derive_vars_dt(adex, new_vars_prefix = "AEN", dtc = EXENDTC)
USUBJID VISIT EXSTDTC EXENDTC ASTDT AENDT
01-701-1015 BASELINE 2014-01-02 2014-01-16 2014-01-02 2014-01-16
01-701-1015 WEEK 2 2014-01-17 2014-06-18 2014-01-17 2014-06-18
01-701-1015 WEEK 24 2014-06-19 2014-07-02 2014-06-19 2014-07-02
01-701-1023 BASELINE 2012-08-05 2012-08-27 2012-08-05 2012-08-27
01-701-1023 WEEK 2 2012-08-28 2012-09-01 2012-08-28 2012-09-01
01-703-1086 BASELINE 2012-09-02 2012-09-16 2012-09-02 2012-09-16
01-703-1086 WEEK 2 2012-09-17 2012-12-04 2012-09-17 2012-12-04
01-703-1096 BASELINE 2013-01-25 2013-02-09 2013-01-25 2013-02-09
01-703-1096 WEEK 2 2013-02-10 2013-03-16 2013-02-10 2013-03-16
01-707-1037 BASELINE 2013-12-20 2013-12-24 2013-12-20 2013-12-24

The next examples demonstrates the datetime imputation features available in the derive_vars_dtm() function, where the time is imputed as “00:00:00”:

adex <- derive_vars_dtm(
  adex,
  dtc = EXSTDTC,
  highest_imputation = "M",
  new_vars_prefix = "AST"
)

adex <- derive_vars_dtm(
  adex,
  dtc = EXENDTC,
  highest_imputation = "M",
  date_imputation = "last",
  new_vars_prefix = "AEN"
)
USUBJID VISIT EXSTDTC EXENDTC ASTDTM AENDTM
01-701-1015 BASELINE 2014-01-02 2014-01-16 2014-01-02 2014-01-16
01-701-1015 WEEK 2 2014-01-17 2014-06-18 2014-01-17 2014-06-18
01-701-1015 WEEK 24 2014-06-19 2014-07-02 2014-06-19 2014-07-02
01-701-1023 BASELINE 2012-08-05 2012-08-27 2012-08-05 2012-08-27
01-701-1023 WEEK 2 2012-08-28 2012-09-01 2012-08-28 2012-09-01
01-703-1086 BASELINE 2012-09-02 2012-09-16 2012-09-02 2012-09-16
01-703-1086 WEEK 2 2012-09-17 2012-12-04 2012-09-17 2012-12-04
01-703-1096 BASELINE 2013-01-25 2013-02-09 2013-01-25 2013-02-09
01-703-1096 WEEK 2 2013-02-10 2013-03-16 2013-02-10 2013-03-16
01-707-1037 BASELINE 2013-12-20 2013-12-24 2013-12-20 2013-12-24

The example above imputes the start date to the first first day of the month and imputes the end date to the last day of the month.

Please see the Date and Time Imputation for additional examples on calculating and imputing analysis dates.

Next, the analysis study days can be derived:

adex <-
  derive_vars_dy(adex,
    reference_date = TRTSDT,
    source_vars = exprs(ASTDT, AENDT)
  )
USUBJID VISIT ASTDT ASTDY AENDT AENDY TRTSDT
01-701-1015 BASELINE 2014-01-02 1 2014-01-16 15 2014-01-02
01-701-1015 WEEK 2 2014-01-17 16 2014-06-18 168 2014-01-02
01-701-1015 WEEK 24 2014-06-19 169 2014-07-02 182 2014-01-02
01-701-1023 BASELINE 2012-08-05 1 2012-08-27 23 2012-08-05
01-701-1023 WEEK 2 2012-08-28 24 2012-09-01 28 2012-08-05
01-703-1086 BASELINE 2012-09-02 1 2012-09-16 15 2012-09-02
01-703-1086 WEEK 2 2012-09-17 16 2012-12-04 94 2012-09-02
01-703-1096 BASELINE 2013-01-25 1 2013-02-09 16 2013-01-25
01-703-1096 WEEK 2 2013-02-10 17 2013-03-16 51 2013-01-25
01-707-1037 BASELINE 2013-12-20 1 2013-12-24 5 2013-12-20

Compute duration for a record

To compute the duration of treatment or exposure for a record, the derive_vars_duration() function can be used.

adex <- adex %>%
  derive_vars_duration(
    new_var = EXDURD,
    start_date = ASTDT,
    end_date = AENDT
  )
USUBJID VISIT ASTDT ASTDY AENDT AENDY EXDURD
01-701-1015 BASELINE 2014-01-02 1 2014-01-16 15 15
01-701-1015 WEEK 2 2014-01-17 16 2014-06-18 168 153
01-701-1015 WEEK 24 2014-06-19 169 2014-07-02 182 14
01-701-1023 BASELINE 2012-08-05 1 2012-08-27 23 23
01-701-1023 WEEK 2 2012-08-28 24 2012-09-01 28 5
01-703-1086 BASELINE 2012-09-02 1 2012-09-16 15 15
01-703-1086 WEEK 2 2012-09-17 16 2012-12-04 94 79
01-703-1096 BASELINE 2013-01-25 1 2013-02-09 16 16
01-703-1096 WEEK 2 2013-02-10 17 2013-03-16 51 35
01-707-1037 BASELINE 2013-12-20 1 2013-12-24 5 5

The units of the calculated duration can also be changed. In this example, the duration is output as years:

adex <- adex %>%
  derive_vars_duration(
    new_var = EXDURDY,
    out_unit = "years",
    start_date = ASTDT,
    end_date = AENDT
  )
USUBJID VISIT ASTDT AENDT EXDURD EXDURDY
01-701-1015 BASELINE 2014-01-02 2014-01-16 15 0.0410678
01-701-1015 WEEK 2 2014-01-17 2014-06-18 153 0.4188912
01-701-1015 WEEK 24 2014-06-19 2014-07-02 14 0.0383299
01-701-1023 BASELINE 2012-08-05 2012-08-27 23 0.0629706
01-701-1023 WEEK 2 2012-08-28 2012-09-01 5 0.0136893
01-703-1086 BASELINE 2012-09-02 2012-09-16 15 0.0410678
01-703-1086 WEEK 2 2012-09-17 2012-12-04 79 0.2162902
01-703-1096 BASELINE 2013-01-25 2013-02-09 16 0.0438056
01-703-1096 WEEK 2 2013-02-10 2013-03-16 35 0.0958248
01-707-1037 BASELINE 2013-12-20 2013-12-24 5 0.0136893

Please refer to the derive_vars_duration() documentation for detailed information on the input parameters.

It may be necessary to calculate additional intermediate values. For example, the cumulative doses received and cumulative planned doses may be calculated as:

adex <- adex %>%
  mutate(
    DOSEO = EXDOSE * EXDURD,
    PDOSEO = EXPLDOS * EXDURD
  )
USUBJID EXDOSE EXPLDOS EXDURD DOSEO PDOSEO
01-701-1015 0 0 15 0 0
01-701-1015 0 0 153 0 0
01-701-1015 0 0 14 0 0
01-701-1023 0 0 23 0 0
01-701-1023 0 0 5 0 0
01-703-1086 54 54 15 810 810
01-703-1086 54 54 79 4266 4266
01-703-1096 0 0 16 0 0
01-703-1096 0 0 35 0 0
01-707-1037 54 54 5 270 270

It may be of additional interest to turn a single record containing dosing summary information into a set of multiple single records, each representing a single dose over the interval specified by the summary record. This is another approach to deriving a total dose parameter when EXDOSFRQ != ONCE.

The function create_single_dose_dataset() can be used to expand a record containing a start date, an end date, and a dosing frequency to a corresponding set of records each representing one dose (i.e. EXDOSFRQ == "ONCE").

single_dose <- adex %>%
  filter(USUBJID == "01-701-1015" & EXSTDY == 1) %>%
  create_single_dose_dataset(keep_source_vars = exprs(USUBJID, EXDOSE, EXPLDOS, EXDOSFRQ, ASTDT, AENDT))
USUBJID EXDOSE EXPLDOS EXDOSFRQ ASTDT AENDT
01-701-1015 0 0 ONCE 2014-01-02 2014-01-02
01-701-1015 0 0 ONCE 2014-01-03 2014-01-03
01-701-1015 0 0 ONCE 2014-01-04 2014-01-04
01-701-1015 0 0 ONCE 2014-01-05 2014-01-05
01-701-1015 0 0 ONCE 2014-01-06 2014-01-06
01-701-1015 0 0 ONCE 2014-01-07 2014-01-07
01-701-1015 0 0 ONCE 2014-01-08 2014-01-08
01-701-1015 0 0 ONCE 2014-01-09 2014-01-09
01-701-1015 0 0 ONCE 2014-01-10 2014-01-10
01-701-1015 0 0 ONCE 2014-01-11 2014-01-11

Create 1:1 mapping records

The first set of exposure records to create will be records mapped 1:1 to an existing collected exposure record in SDTM. For these records, the AVAL or AVALC would be calculated using columns that exist on the data and no summarizing of records would be necessary.

These records may be used for input into summary records or be used individually for summarization in outputs. Some examples may be exposure duration, dose administered, dose adjusted, etc. based on one exposure record in SDTM.

These records can be derived using simple dplyr::mutate assignments and then combined:

adex_durd <- adex %>%
  mutate(
    PARAMCD = "DURD",
    AVAL = EXDURD
  )

adex_dose <- adex %>%
  mutate(
    PARAMCD = "DOSE",
    AVAL = DOSEO
  )

adex_pldos <- adex %>%
  mutate(
    PARAMCD = "PLDOSE",
    AVAL = PDOSEO
  )

adex_adj <- adex %>%
  mutate(
    PARAMCD = "ADJ",
    AVALC = if_else(!is.na(EXADJ), "Y", NA_character_)
  )

adex_adjae <- adex %>%
  mutate(
    PARAMCD = "ADJAE",
    AVALC = if_else(EXADJ == "ADVERSE EVENT", "Y", NA_character_)
  )

adex <- bind_rows(
  adex_durd,
  adex_dose,
  adex_pldos,
  adex_adj,
  adex_adjae
) %>%
  mutate(PARCAT1 = "INDIVIDUAL")

count(adex, PARAMCD)
#> # A tibble: 5 × 2
#>   PARAMCD     n
#>   <chr>   <int>
#> 1 ADJ        13
#> 2 ADJAE      13
#> 3 DOSE       13
#> 4 DURD       13
#> 5 PLDOSE     13
USUBJID VISIT ASTDT AENDT PARAMCD AVAL AVALC
01-701-1015 BASELINE 2014-01-02 2014-01-16 PLDOSE 0 NA
01-701-1015 BASELINE 2014-01-02 2014-01-16 DURD 15 NA
01-701-1015 BASELINE 2014-01-02 2014-01-16 DOSE 0 NA
01-701-1015 BASELINE 2014-01-02 2014-01-16 ADJAE NA NA
01-701-1015 BASELINE 2014-01-02 2014-01-16 ADJ NA NA
01-701-1015 WEEK 2 2014-01-17 2014-06-18 PLDOSE 0 NA
01-701-1015 WEEK 2 2014-01-17 2014-06-18 DURD 153 NA
01-701-1015 WEEK 2 2014-01-17 2014-06-18 DOSE 0 NA
01-701-1015 WEEK 2 2014-01-17 2014-06-18 ADJAE NA NA
01-701-1015 WEEK 2 2014-01-17 2014-06-18 ADJ NA NA

Create Summary Records

Exposure is commonly analyzed by a timing interval (e.g. APHASE, APERIOD, AVISIT, etc.). For these types of calculations, the derive_param_exposure() function may be used. In addition to creating a summarized AVAL, the function will also compute minimum and maximum dates for the record.

For example, to calculate the total dose by subject and treatment,

adex <- derive_param_exposure(
  adex,
  dataset_add = adex,
  by_vars = c(get_admiral_option("subject_keys"), adsl_vars),
  input_code = "DOSE",
  set_values_to = exprs(
    PARAMCD = "TDOSE",
    PARCAT1 = "OVERALL",
    AVAL = sum(AVAL, na.rm = TRUE)
  )
)
USUBJID VISIT PARCAT1 PARAMCD AVAL ASTDT AENDT
01-701-1015 BASELINE INDIVIDUAL ADJ NA 2014-01-02 2014-01-16
01-701-1015 WEEK 2 INDIVIDUAL ADJ NA 2014-01-17 2014-06-18
01-701-1015 WEEK 24 INDIVIDUAL ADJ NA 2014-06-19 2014-07-02
01-701-1015 BASELINE INDIVIDUAL ADJAE NA 2014-01-02 2014-01-16
01-701-1015 WEEK 2 INDIVIDUAL ADJAE NA 2014-01-17 2014-06-18
01-701-1015 WEEK 24 INDIVIDUAL ADJAE NA 2014-06-19 2014-07-02
01-701-1015 BASELINE INDIVIDUAL DOSE 0 2014-01-02 2014-01-16
01-701-1015 WEEK 2 INDIVIDUAL DOSE 0 2014-01-17 2014-06-18
01-701-1015 WEEK 24 INDIVIDUAL DOSE 0 2014-06-19 2014-07-02
01-701-1015 BASELINE INDIVIDUAL DURD 15 2014-01-02 2014-01-16

A record with PARAMCD == "TDOSE" is created with PARCAT1 set to "OVERALL" using the records in ADEX where PARAMCD == "DOSE" by summing AVAL. In addition, the ASTDT, and AENDT are created as the minimum and maximum date/times associated with each by_vars grouping. Note that, in addition to PARAMCD, PARCAT1, AVAL, ASTDT and AENDT, only those variables specified in the by_vars argument will be populated in the new records.

Multiple parameters (records) may be created at one time using the call_derivation() function:

adex <- adex %>%
  call_derivation(
    derivation = derive_param_exposure,
    variable_params = list(
      params(
        set_values_to = exprs(
          PARAMCD = "TDOSE",
          PARCAT1 = "OVERALL",
          AVAL = sum(AVAL, na.rm = TRUE)
        ),
        input_code = "DOSE"
      ),
      params(
        set_values_to = exprs(
          PARAMCD = "TPDOSE",
          PARCAT1 = "OVERALL",
          AVAL = sum(AVAL, na.rm = TRUE)
        ),
        input_code = "PLDOSE"
      ),
      params(
        set_values_to = exprs(
          PARAMCD = "TDURD",
          PARCAT1 = "OVERALL",
          AVAL = sum(AVAL, na.rm = TRUE)
        ),
        input_code = "DURD"
      ),
      params(
        set_values_to = exprs(
          PARAMCD = "TADJ",
          PARCAT1 = "OVERALL",
          AVALC = if_else(sum(!is.na(AVALC)) > 0, "Y", NA_character_)
        ),
        input_code = "ADJ"
      ),
      params(
        set_values_to = exprs(
          PARAMCD = "TADJAE",
          PARCAT1 = "OVERALL",
          AVALC = if_else(sum(!is.na(AVALC)) > 0, "Y", NA_character_)
        ),
        input_code = "ADJAE"
      )
    ),
    dataset_add = adex,
    by_vars = c(get_admiral_option("subject_keys"), adsl_vars)
  )

count(adex, PARAMCD, PARCAT1)
#> # A tibble: 10 × 3
#>    PARAMCD PARCAT1        n
#>    <chr>   <chr>      <int>
#>  1 ADJ     INDIVIDUAL    13
#>  2 ADJAE   INDIVIDUAL    13
#>  3 DOSE    INDIVIDUAL    13
#>  4 DURD    INDIVIDUAL    13
#>  5 PLDOSE  INDIVIDUAL    13
#>  6 TADJ    OVERALL        6
#>  7 TADJAE  OVERALL        6
#>  8 TDOSE   OVERALL        6
#>  9 TDURD   OVERALL        6
#> 10 TPDOSE  OVERALL        6
USUBJID VISIT PARCAT1 PARAMCD AVAL AVALC ASTDT AENDT
01-701-1015 BASELINE INDIVIDUAL ADJ NA NA 2014-01-02 2014-01-16
01-701-1015 WEEK 2 INDIVIDUAL ADJ NA NA 2014-01-17 2014-06-18
01-701-1015 WEEK 24 INDIVIDUAL ADJ NA NA 2014-06-19 2014-07-02
01-701-1015 BASELINE INDIVIDUAL ADJAE NA NA 2014-01-02 2014-01-16
01-701-1015 WEEK 2 INDIVIDUAL ADJAE NA NA 2014-01-17 2014-06-18
01-701-1015 WEEK 24 INDIVIDUAL ADJAE NA NA 2014-06-19 2014-07-02
01-701-1015 BASELINE INDIVIDUAL DOSE 0 NA 2014-01-02 2014-01-16
01-701-1015 WEEK 2 INDIVIDUAL DOSE 0 NA 2014-01-17 2014-06-18
01-701-1015 WEEK 24 INDIVIDUAL DOSE 0 NA 2014-06-19 2014-07-02
01-701-1015 BASELINE INDIVIDUAL DURD 15 NA 2014-01-02 2014-01-16

Dose intensity can be calculated using the function derive_param_doseint(). The planned dose and administered dose are passed into the function and a new record is created with the dose intensity calculation. Again, only those variables specified in the by_vars argument will be populated in this new record.

adex <- adex %>%
  derive_param_doseint(
    by_vars = c(get_admiral_option("subject_keys"), adsl_vars),
    set_values_to = exprs(PARAMCD = "TNDOSINT"),
    tadm_code = "TDOSE",
    tpadm_code = "TPDOSE"
  )
USUBJID VISIT EXSTDTC EXENDTC PARCAT1 PARAMCD AVAL ASTDT AENDT
01-701-1015 BASELINE 2014-01-02 2014-01-16 INDIVIDUAL DURD 15 2014-01-02 2014-01-16
01-701-1015 WEEK 2 2014-01-17 2014-06-18 INDIVIDUAL DURD 153 2014-01-17 2014-06-18
01-701-1015 WEEK 24 2014-06-19 2014-07-02 INDIVIDUAL DURD 14 2014-06-19 2014-07-02
01-701-1023 BASELINE 2012-08-05 2012-08-27 INDIVIDUAL DURD 23 2012-08-05 2012-08-27
01-701-1023 WEEK 2 2012-08-28 2012-09-01 INDIVIDUAL DURD 5 2012-08-28 2012-09-01
01-703-1086 BASELINE 2012-09-02 2012-09-16 INDIVIDUAL DURD 15 2012-09-02 2012-09-16
01-703-1086 WEEK 2 2012-09-17 2012-12-04 INDIVIDUAL DURD 79 2012-09-17 2012-12-04
01-703-1096 BASELINE 2013-01-25 2013-02-09 INDIVIDUAL DURD 16 2013-01-25 2013-02-09
01-703-1096 WEEK 2 2013-02-10 2013-03-16 INDIVIDUAL DURD 35 2013-02-10 2013-03-16
01-707-1037 BASELINE 2013-12-20 2013-12-24 INDIVIDUAL DURD 5 2013-12-20 2013-12-24

The default calculation for dose intensity is: Administered Doses / Planned Doses * 100.

Please see the derive_param_doseint() documentation to see how planned doses of 0 or NA are handled.

Assign PARAMCD, PARAMN, etc. from Reference tables

To assign parameter level values such as PARAM, PARAMN, PARCAT1, etc., a lookup can be created to join to the source data.

For example, when creating ADEX, a lookup based on the ADaM PARAMCD value may be created:

PARAMCD PARAM PARAMN
DURD Study drug duration during constant dosing interval (days) 1
DOSE Dose administered during constant dosing interval (mg) 2
PLDOSE Planned dose during constant dosing interval (mg) 3
ADJ Dose adjusted during constant dosing interval 4
ADJAE Dose adjusted due to AE during constant dosing interval 5
TDURD Overall duration (days) 6
TDOSE Total dose administered (mg) 7
TPDOSE Total planned dose (mg) 9
TADJ Dose adjusted during study 10
TADJAE Dose adjusted during study due to AE 11
TNDOSINT Overall dose intensity (%) 12
adex <- derive_vars_merged(
  adex,
  dataset_add = param_lookup,
  by_vars = exprs(PARAMCD)
)

count(adex, PARAMCD, PARAM, PARAMN)
#> # A tibble: 11 × 4
#>    PARAMCD  PARAM                                                   PARAMN     n
#>    <chr>    <chr>                                                    <dbl> <int>
#>  1 ADJ      Dose adjusted during constant dosing interval                4    13
#>  2 ADJAE    Dose adjusted  due to AE during constant dosing interv…      5    13
#>  3 DOSE     Dose administered during constant dosing interval (mg)       2    13
#>  4 DURD     Study drug duration during constant dosing interval (d…      1    13
#>  5 PLDOSE   Planned dose during constant dosing interval (mg)            3    13
#>  6 TADJ     Dose adjusted during study                                  10     6
#>  7 TADJAE   Dose adjusted during study due to AE                        11     6
#>  8 TDOSE    Total dose administered (mg)                                 7     6
#>  9 TDURD    Overall duration (days)                                      6     6
#> 10 TNDOSINT Overall dose intensity (%)                                  12     6
#> 11 TPDOSE   Total planned dose (mg)                                      9     6

Please note, this is an example only and additional columns may be needed for the join depending on your lookup/metadata table.

Derive Categorization Variables (AVALCATy)

We can use the derive_vars_cat() function to derive the categorization variables.

avalcax_lookup <- exprs(
  ~PARAMCD,            ~condition,             ~AVALCAT1,
  "TDURD",             AVAL >= 90,          ">= 90 days",
  "TDURD", AVAL >= 30 & AVAL < 90, ">= 30 and < 90 days",
  "TDURD",              AVAL < 30,           "< 30 days",
  "TDOSE",            AVAL < 1000,           "< 1000 mg",
  "TDOSE",           AVAL >= 1000,          ">= 1000 mg",
  "TPDOSE",           AVAL < 1000,           "< 1000 mg",
  "TPDOSE",          AVAL >= 1000,          ">= 1000 mg"
)

adex <- adex %>%
  derive_vars_cat(
    definition = avalcax_lookup,
    by_vars = exprs(PARAMCD)
  )
USUBJID VISIT PARCAT1 PARAMCD AVAL AVALCAT1
01-701-1015 NA OVERALL TDOSE 0 < 1000 mg
01-701-1015 NA OVERALL TPDOSE 0 < 1000 mg
01-701-1015 NA OVERALL TDURD 182 >= 90 days
01-701-1015 BASELINE INDIVIDUAL DURD 15 NA
01-701-1015 BASELINE INDIVIDUAL DOSE 0 NA
01-701-1015 BASELINE INDIVIDUAL PLDOSE 0 NA
01-701-1015 BASELINE INDIVIDUAL ADJ NA NA
01-701-1015 BASELINE INDIVIDUAL ADJAE NA NA
01-701-1015 WEEK 2 INDIVIDUAL DURD 153 NA
01-701-1015 WEEK 2 INDIVIDUAL DOSE 0 NA

Assign ASEQ

The {admiral} function derive_var_obs_number() can be used to derive ASEQ. An example call is:

adex <- derive_var_obs_number(
  adex,
  new_var = ASEQ,
  by_vars = get_admiral_option("subject_keys"),
  order = exprs(PARCAT1, ASTDT, VISIT, VISITNUM, EXSEQ, PARAMN),
  check_type = "error"
)
USUBJID VISIT PARCAT1 PARAMCD AVAL ASTDT ASEQ
01-701-1015 BASELINE INDIVIDUAL DURD 15 2014-01-02 1
01-701-1015 BASELINE INDIVIDUAL DOSE 0 2014-01-02 2
01-701-1015 BASELINE INDIVIDUAL PLDOSE 0 2014-01-02 3
01-701-1015 BASELINE INDIVIDUAL ADJ NA 2014-01-02 4
01-701-1015 BASELINE INDIVIDUAL ADJAE NA 2014-01-02 5
01-701-1015 WEEK 2 INDIVIDUAL DURD 153 2014-01-17 6
01-701-1015 WEEK 2 INDIVIDUAL DOSE 0 2014-01-17 7
01-701-1015 WEEK 2 INDIVIDUAL PLDOSE 0 2014-01-17 8
01-701-1015 WEEK 2 INDIVIDUAL ADJ NA 2014-01-17 9
01-701-1015 WEEK 2 INDIVIDUAL ADJAE NA 2014-01-17 10

Add the ADSL variables

If needed, the other ADSL variables can now be added:

adex <- adex %>%
  derive_vars_merged(
    dataset_add = select(adsl, !!!negate_vars(adsl_vars)),
    by_vars = get_admiral_option("subject_keys")
  )

Add Labels and Attributes

Adding labels and attributes for SAS transport files is supported by the following packages:

  • metacore: establish a common foundation for the use of metadata within an R session.

  • metatools: enable the use of metacore objects. Metatools can be used to build datasets or enhance columns in existing datasets as well as checking datasets against the metadata.

  • xportr: functionality to associate all metadata information to a local R data frame, perform data set level validation checks and convert into a transport v5 file(xpt).

NOTE: All these packages are in the experimental phase, but the vision is to have them associated with an End to End pipeline under the umbrella of the pharmaverse. An example of applying metadata and perform associated checks can be found at the pharmaverse E2E example.

Example Script

ADaM Sourcing Command
ADEX use_ad_template("ADEX")