---
title: "Creating ADSL"
output: 
  rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Creating ADSL}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

library(admiraldev)
```

# Introduction

This article describes creating an `ADSL` ADaM. Examples are currently 
presented and tested using `DM`, `EX` , `AE`, `LB` and `DS` SDTM domains. However, other domains 
could be used.

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

# Programming Flow

* [Read in Data](#readdata)
* [Derive Period, Subperiod, and Phase Variables (e.g. `APxxSDT`, `APxxEDT`, ...)](#periodvars)
* [Derive Treatment Variables (`TRT0xP`, `TRT0xA`)](#treatmentvar)
* [Derive/Impute Numeric Treatment Date/Time and Duration (`TRTSDT`, `TRTEDT`, `TRTDURD`)](#trtdatetime)
* [Derive Disposition Variables](#disposition)
  * [Disposition Dates (e.g. `EOSDT`)](#disposition_date)
  * [Disposition Status (e.g. `EOSTT`)](#disposition_status)
  * [Disposition Reason(s) (e.g. `DCSREAS`, `DCSREASP`)](#disposition_reason)
  * [Randomization Date (`RANDDT`)](#randomization_date)
* [Derive Death Variables](#death)
  * [Death Date (`DTHDT`)](#death_date)
  * [Cause of Death (`DTHCAUS`)](#death_cause)
  * [Duration Relative to Death](#death_other)
* [Derive Last Known Date Alive (`LSTALVDT`)](#lstalvdt)
* [Derive Groupings and Populations](#groupings)
  * [Grouping (e.g. `AGEGR1` or `REGION1`)](#groupings_ex)
  * [Population Flags (e.g. `SAFFL`)](#popflag)
* [Derive Other Variables](#other)
* [Add Labels and Attributes](#attributes)


## Read in Data {#readdata}

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

For example purpose, the CDISC Pilot SDTM datasets---which are included in 
`{admiral.test}`---are used.

```{r, message=FALSE, warning=FALSE}
library(admiral)
library(dplyr, warn.conflicts = FALSE)
library(admiral.test)
library(lubridate)
library(stringr)

data("admiral_dm")
data("admiral_ds")
data("admiral_ex")
data("admiral_ae")
data("admiral_lb")

dm <- convert_blanks_to_na(admiral_dm)
ds <- convert_blanks_to_na(admiral_ds)
ex <- convert_blanks_to_na(admiral_ex)
ae <- convert_blanks_to_na(admiral_ae)
lb <- convert_blanks_to_na(admiral_lb)
```

The `DM` domain is used as the basis for `ADSL`:

```{r eval=TRUE}
adsl <- dm %>%
  select(-DOMAIN)
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  adsl,
  display_vars = exprs(USUBJID, RFSTDTC, COUNTRY, AGE, SEX, RACE, ETHNIC, ARM, ACTARM)
)
```

## Derive Period, Subperiod, and Phase Variables (e.g. `APxxSDT`, `APxxEDT`, ...) {#periodvars}

See the ["Visit and Period Variables"
vignette](visits_periods.html#periods_adsl) for more information.

If the variables are not derived based on a period reference dataset, they may
be derived at a later point of the flow. For example, phases like "Treatment
Phase" and "Follow up" could be derived based on treatment start and end date.

## Derive Treatment Variables (`TRT0xP`, `TRT0xA`) {#treatmentvar}

The mapping of the treatment variables is left to the ADaM programmer. An
example mapping for a study without periods may be:

```{r eval=TRUE}
adsl <- dm %>%
  mutate(TRT01P = ARM, TRT01A = ACTARM)
```

For studies with periods see the ["Visit and Period Variables"
vignette](visits_periods.html#treatment_adsl).

## Derive/Impute Numeric Treatment Date/Time and Duration (`TRTSDTM`, `TRTEDTM`, `TRTDURD`) {#trtdatetime}

The function `derive_vars_merged()` can be used to derive the treatment start
and end date/times using the `ex` domain. A pre-processing step for `ex` is
required to convert the variable `EXSTDTC` and `EXSTDTC` to datetime variables
and impute missing date or time components. Conversion and imputation is done by
`derive_vars_dtm()`.

Example calls:

```{r eval=TRUE}
# impute start and end time of exposure to first and last respectively, do not impute date
ex_ext <- ex %>%
  derive_vars_dtm(
    dtc = EXSTDTC,
    new_vars_prefix = "EXST"
  ) %>%
  derive_vars_dtm(
    dtc = EXENDTC,
    new_vars_prefix = "EXEN",
    time_imputation = "last"
  )

adsl <- adsl %>%
  derive_vars_merged(
    dataset_add = ex_ext,
    filter_add = (EXDOSE > 0 |
      (EXDOSE == 0 &
        str_detect(EXTRT, "PLACEBO"))) & !is.na(EXSTDTM),
    new_vars = exprs(TRTSDTM = EXSTDTM, TRTSTMF = EXSTTMF),
    order = exprs(EXSTDTM, EXSEQ),
    mode = "first",
    by_vars = exprs(STUDYID, USUBJID)
  ) %>%
  derive_vars_merged(
    dataset_add = ex_ext,
    filter_add = (EXDOSE > 0 |
      (EXDOSE == 0 &
        str_detect(EXTRT, "PLACEBO"))) & !is.na(EXENDTM),
    new_vars = exprs(TRTEDTM = EXENDTM, TRTETMF = EXENTMF),
    order = exprs(EXENDTM, EXSEQ),
    mode = "last",
    by_vars = exprs(STUDYID, USUBJID)
  )
```

This call returns the original data frame with the column `TRTSDTM`, `TRTSTMF`,
`TRTEDTM`, and `TRTETMF` added. Exposure observations with incomplete date and
zero doses of non placebo treatments are ignored. Missing time parts are imputed
as first or last for start and end date respectively.

The datetime variables returned can be converted to dates using the `derive_vars_dtm_to_dt()` 
function.

```{r eval=TRUE}
adsl <- adsl %>%
  derive_vars_dtm_to_dt(source_vars = exprs(TRTSDTM, TRTEDTM))
```


Now, that `TRTSDT` and `TRTEDT` are derived, the function `derive_var_trtdurd()`
can be used to calculate the Treatment duration (`TRTDURD`).

```{r eval=TRUE}
adsl <- adsl %>%
  derive_var_trtdurd()
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  adsl,
  display_vars = exprs(USUBJID, RFSTDTC, TRTSDTM, TRTSDT, TRTEDTM, TRTEDT, TRTDURD)
)
```


## Derive Disposition Variables {#disposition}

### Disposition Dates (e.g. `EOSDT`) {#disposition_date}

The functions `derive_vars_dt()` and `derive_vars_merged()` can be used to
derive a disposition date. First the character disposition date (`DS.DSSTDTC`)
is converted to a numeric date (`DSSTDT`) calling `derive_vars_dt()`. Then the
relevant disposition date is selected by adjusting the `filter_add` parameter.

To derive the End of Study date (`EOSDT`), a call could be:

```{r eval=TRUE}
# convert character date to numeric date without imputation
ds_ext <- derive_vars_dt(
  ds,
  dtc = DSSTDTC,
  new_vars_prefix = "DSST"
)

adsl <- adsl %>%
  derive_vars_merged(
    dataset_add = ds_ext,
    by_vars = exprs(STUDYID, USUBJID),
    new_vars = exprs(EOSDT = DSSTDT),
    filter_add = DSCAT == "DISPOSITION EVENT" & DSDECOD != "SCREEN FAILURE"
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  ds,
  display_vars = exprs(USUBJID, DSCAT, DSDECOD, DSTERM, DSSTDTC),
  filter = DSDECOD != "SCREEN FAILURE"
)
```

We would get :

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(adsl, display_vars = exprs(USUBJID, EOSDT))
```

This call would return the input dataset with the column `EOSDT` added. 
This function allows the user to impute partial dates as well. If imputation is needed and the date 
is to be imputed to the first of the month, then set `date_imputation = "FIRST"`.

### Disposition Status (e.g. `EOSSTT`) {#disposition_status}

The function `derive_var_merged_cat()` can be used to derive a disposition status at a specific
timepoint. The relevant disposition variable (`DS.DSDECOD`) is selected by adjusting the filter 
parameter and used to derive `EOSSTT`.

To derive the End of Study status (`EOSSTT`), the function expects a mapping derivation for the `cat_fun` argument.
The mapping derivation for the call below is

- `"NOT STARTED"` if `DSDECOD` is `"SCREEN FAILURE"`
- `"COMPLETED"` if `DSDECOD == "COMPLETED"`
- `"DISCONTINUED"` if `DSDECOD` is not `"COMPLETED"` or `NA`
- `"ONGOING"` otherwise

Example function `format_eosstt()`:

```{r eval=TRUE}
format_eosstt <- function(x) {
  case_when(
    x %in% c("COMPLETED") ~ "COMPLETED",
    x %in% c("SCREEN FAILURE") ~ NA_character_,
    !is.na(x) ~ "DISCONTINUED",
    TRUE ~ "ONGOING"
  )
}
```

The customized mapping function `format_eosstt()` can now be passed to the main function:

```{r eval=TRUE}
adsl <- adsl %>%
  derive_var_merged_cat(
    dataset_add = ds,
    by_vars = exprs(STUDYID, USUBJID),
    filter_add = DSCAT == "DISPOSITION EVENT",
    new_var = EOSSTT,
    source_var = DSDECOD,
    cat_fun = format_eosstt,
    missing_value = "ONGOING"
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(adsl, display_vars = exprs(USUBJID, EOSDT, EOSSTT))
```

This call would return the input dataset with the column `EOSSTT` added. 

If the derivation must be changed, the user can create his/her own function and pass it to 
the `cat_fun` argument of the function (`cat_fun = new_mapping`) to map `DSDECOD` 
to a suitable `EOSSTT` value.

### Disposition Reason(s) (e.g. `DCSREAS`, `DCSREASP`) {#disposition_reason}

The main reason for discontinuation is usually stored in `DSDECOD` while `DSTERM` provides 
additional details regarding subject’s discontinuation (e.g., description of `"OTHER"`).

The function `derive_vars_merged()` can be used to derive a disposition reason (along with the details, if required) at a specific timepoint. 
The relevant disposition variable(s) (`DS.DSDECOD`, `DS.DSTERM`) are selected by adjusting the filter parameter and used to derive the main reason (and details).

To derive the End of Study reason(s) (`DCSREAS` and `DCSREASP`), the function will map 

- `DCSREAS` as `DSDECOD`, and `DCSREASP` as `DSTERM` if `DSDECOD` is not `"COMPLETED"`, `"SCREEN FAILURE"`, or `NA`, `NA` otherwise

```{r}
adsl <- adsl %>%
  derive_vars_merged(
    dataset_add = ds,
    by_vars = exprs(USUBJID),
    new_vars = exprs(DCSREAS = DSDECOD, DCSREASP = DSTERM),
    filter_add = DSCAT == "DISPOSITION EVENT" & DSDECOD %notin% c("SCREEN FAILURE", "COMPLETED", NA)
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(adsl, display_vars = exprs(USUBJID, EOSDT, EOSSTT, DCSREAS, DCSREASP))
```
This call would return the input dataset with the column `DCSREAS` and `DCSREASP` added. 

If the derivation must be changed, the user can define that derivation in the `filter_add` argument of the function to map `DSDECOD` and  `DSTERM` to a suitable `DCSREAS`/`DCSREASP` value.

The call below maps `DCSREAS` and `DCREASP` as follows:

- `DCSREAS` as `DSDECOD` if `DSDECOD` is not `"COMPLETED"` or `NA`, `NA` otherwise
- `DCSREASP` as `DSTERM` if `DSDECOD` is equal to `OTHER`, `NA` otherwise

```{r, eval=TRUE, echo=FALSE}
adsl <- adsl %>%
  select(-DCSREAS, -DCSREASP)
```

```{r}
adsl <- adsl %>%
  derive_vars_merged(
    dataset_add = ds,
    by_vars = exprs(USUBJID),
    new_vars = exprs(DCSREAS = DSDECOD),
    filter_add = DSCAT == "DISPOSITION EVENT" & DSDECOD %notin% c("SCREEN FAILURE", "COMPLETED", NA)
  ) %>%
  derive_vars_merged(
    dataset_add = ds,
    by_vars = exprs(USUBJID),
    new_vars = exprs(DCSREASP = DSTERM),
    filter_add = DSCAT == "DISPOSITION EVENT" & DSDECOD %in% "OTHER"
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(adsl, display_vars = exprs(USUBJID, EOSDT, EOSSTT, DCSREAS, DCSREASP))
```

### Randomization Date (`RANDDT`) {#randomization_date}

The function `derive_vars_merged()` can be used to derive randomization date 
variable. To map Randomization Date (`RANDDT`), the call would be:

```{r eval=TRUE}
adsl <- adsl %>%
  derive_vars_merged(
    dataset_add = ds_ext,
    filter_add = DSDECOD == "RANDOMIZED",
    by_vars = exprs(STUDYID, USUBJID),
    new_vars = exprs(RANDDT = DSSTDT)
  )
```


This call would return the input dataset with the column `RANDDT` is added.

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(adsl, display_vars = exprs(USUBJID, RANDDT))
```

## Derive Death Variables {#death}

### Death Date (`DTHDT`) {#death_date}

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

Example calls:

```{r eval=TRUE}
adsl <- adsl %>%
  derive_vars_dt(
    new_vars_prefix = "DTH",
    dtc = DTHDTC
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(adsl, display_vars = exprs(USUBJID, TRTEDT, DTHDTC, DTHDT, DTHFL))
```

This call would return the input dataset with the columns `DTHDT` added and, by default, the 
associated date imputation flag (`DTHDTF`) populated with the controlled terminology outlined in 
the ADaM IG for date imputations. 
If the imputation flag is not required, the user must set the argument `flag_imputation` to "none".

If imputation is needed and the date is to be imputed to the first day of the month/year 
the call would be:

```{r eval=FALSE}
adsl <- adsl %>%
  derive_vars_dt(
    new_vars_prefix = "DTH",
    dtc = DTHDTC,
    date_imputation = "first"
  )
```

See also [Date and Time Imputation](imputation.html).

### Cause of Death  (`DTHCAUS`) {#death_cause}

The cause of death `DTHCAUS` can be derived using the function `derive_var_dthcaus()`.

Since the cause of death could be collected/mapped in different domains (e.g. `DS`, `AE`, `DD`), it 
is important the user specifies the right source(s) to derive the cause of death from.

For example, if the date of death is collected in the AE form when the AE is Fatal, the cause of 
death would be set to the preferred term (`AEDECOD`) of that Fatal AE, while if the date of death is 
collected in  the `DS` form, the cause of death would be set to the disposition term (`DSTERM`).
To achieve this, the `dthcaus_source()` objects must be specified and defined such as it fits the 
study requirement. 

`dthcaus_source()` specifications:

- `dataset_name`: the name of the dataset where to search for death information,
- `filter`: the condition to define death,
- `date`: the date of death,
- `mode`: `first` or `last` to select the first/last date of death if multiple dates are collected,
- `dthcaus`: variable  or text used to populate `DTHCAUS`.
- `traceability_vars`: whether the traceability variables need to be added (e.g source domain,
sequence, variable)

An example call to define the sources would be: 

```{r eval=TRUE}
src_ae <- dthcaus_source(
  dataset_name = "ae",
  filter = AEOUT == "FATAL",
  date = AESTDTM,
  mode = "first",
  dthcaus = AEDECOD
)
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  ae,
  display_vars = exprs(USUBJID, AESTDTC, AEENDTC, AEDECOD, AEOUT),
  filter = AEOUT == "FATAL"
)
```

```{r eval=TRUE}
src_ds <- dthcaus_source(
  dataset_name = "ds",
  filter = DSDECOD == "DEATH" & grepl("DEATH DUE TO", DSTERM),
  date = DSSTDT,
  mode = "first",
  dthcaus = "Death in DS"
)
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  ds,
  display_vars = exprs(USUBJID, DSDECOD, DSTERM, DSSTDTC),
  filter = DSDECOD == "DEATH"
)
```

Once the sources are defined, the function `derive_var_dthcaus()` can be used to derive `DTHCAUS`:

```{r eval=TRUE}
ae_ext <- derive_vars_dtm(
  ae,
  dtc = AESTDTC,
  new_vars_prefix = "AEST",
  highest_imputation = "M",
  flag_imputation = "none"
)

adsl <- adsl %>%
  derive_var_dthcaus(src_ae, src_ds, source_datasets = list(ae = ae_ext, ds = ds_ext))
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  adsl,
  display_vars = exprs(USUBJID, EOSDT, DTHDTC, DTHDT, DTHCAUS),
  filter = DTHFL == "Y"
)
```

The function also offers the option to add some traceability variables (e.g. `DTHDOM` would 
store the domain where the date of death is collected, and `DTHSEQ` would store the `xxSEQ` value of 
that domain). To add them, the `traceability_vars` argument must be added to the `dthcaus_source()`
arguments:

```{r eval=TRUE}
src_ae <- dthcaus_source(
  dataset_name = "ae",
  filter = AEOUT == "FATAL",
  date = AESTDTM,
  mode = "first",
  dthcaus = AEDECOD,
  traceability_vars = exprs(DTHDOM = "AE", DTHSEQ = AESEQ)
)

src_ds <- dthcaus_source(
  dataset_name = "ds",
  filter = DSDECOD == "DEATH" & grepl("DEATH DUE TO", DSTERM),
  date = DSSTDT,
  mode = "first",
  dthcaus = DSTERM,
  traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ)
)
adsl <- adsl %>%
  select(-DTHCAUS) %>% # remove it before deriving it again
  derive_var_dthcaus(src_ae, src_ds, source_datasets = list(ae = ae_ext, ds = ds_ext))
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  adsl,
  display_vars = exprs(USUBJID, TRTEDT, DTHDTC, DTHDT, DTHCAUS, DTHDOM, DTHSEQ),
  filter = DTHFL == "Y"
)
```

### Duration Relative to Death {#death_other}

The function `derive_vars_duration()` can be used to derive duration relative to death like the Relative 
Day of Death (`DTHADY`) or the numbers of days from last dose to death (`LDDTHELD`).

Example calls: 

- Relative Day of Death
```{r eval=TRUE}
adsl <- adsl %>%
  derive_vars_duration(
    new_var = DTHADY,
    start_date = TRTSDT,
    end_date = DTHDT
  )
```

- Elapsed Days from Last Dose to Death
```{r eval=TRUE}
adsl <- adsl %>%
  derive_vars_duration(
    new_var = LDDTHELD,
    start_date = TRTEDT,
    end_date = DTHDT,
    add_one = FALSE
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  adsl,
  display_vars = exprs(USUBJID, TRTEDT, DTHDTC, DTHDT, DTHCAUS, DTHADY, LDDTHELD),
  filter = DTHFL == "Y"
)
```

## Derive the Last Date Known Alive (`LSTALVDT`) {#lstalvdt}

Similarly as for the cause of death (`DTHCAUS`), the last known alive date
(`LSTALVDT`) can be derived from multiples sources and the user must ensure the
sources (`date_source()`) are correctly defined.

`date_source()` specifications:

- `dataset_name`: the name of the dataset where to search for date information,
- `filter`: the filter to apply on the datasets,
- `date`: the date of interest,
- `date_imputation`: whether and how to impute partial dates,
- `traceability_vars`: whether the traceability variables need to be added (e.g
source domain, sequence, variable)

An example could be :

```{r eval=TRUE}
ae_start_date <- date_source(
  dataset_name = "ae",
  date = AESTDT
)
ae_end_date <- date_source(
  dataset_name = "ae",
  date = AEENDT
)
lb_date <- date_source(
  dataset_name = "lb",
  date = LBDT,
  filter = !is.na(LBDT)
)
trt_end_date <- date_source(
  dataset_name = "adsl",
  date = TRTEDT
)
```

Once the sources are defined, the function `derive_var_extreme_dt()` can be used
to derive `LSTALVDT`:

```{r eval=TRUE}
# impute AE start and end date to first
ae_ext <- ae %>%
  derive_vars_dt(
    dtc = AESTDTC,
    new_vars_prefix = "AEST",
    highest_imputation = "M"
  ) %>%
  derive_vars_dt(
    dtc = AEENDTC,
    new_vars_prefix = "AEEN",
    highest_imputation = "M"
  )

# impute LB date to first
lb_ext <- derive_vars_dt(
  lb,
  dtc = LBDTC,
  new_vars_prefix = "LB",
  highest_imputation = "M"
)

adsl <- adsl %>%
  derive_var_extreme_dt(
    new_var = LSTALVDT,
    ae_start_date, ae_end_date, lb_date, trt_end_date,
    source_datasets = list(ae = ae_ext, adsl = adsl, lb = lb_ext),
    mode = "last"
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  adsl,
  display_vars = exprs(USUBJID, TRTEDT, DTHDTC, LSTALVDT),
  filter = !is.na(TRTSDT)
)
```

Similarly to `dthcaus_source()`, the traceability variables can be added by specifying the 
`traceability_vars` argument in `date_source()`.

```{r eval=TRUE}
ae_start_date <- date_source(
  dataset_name = "ae",
  date = AESTDT,
  traceability_vars = exprs(LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AESTDTC")
)
ae_end_date <- date_source(
  dataset_name = "ae",
  date = AEENDT,
  traceability_vars = exprs(LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AEENDTC")
)
lb_date <- date_source(
  dataset_name = "lb",
  date = LBDT,
  filter = !is.na(LBDT),
  traceability_vars = exprs(LALVDOM = "LB", LALVSEQ = LBSEQ, LALVVAR = "LBDTC")
)
trt_end_date <- date_source(
  dataset_name = "adsl",
  date = TRTEDTM,
  traceability_vars = exprs(LALVDOM = "ADSL", LALVSEQ = NA_integer_, LALVVAR = "TRTEDTM")
)

adsl <- adsl %>%
  select(-LSTALVDT) %>% # created in the previous call
  derive_var_extreme_dt(
    new_var = LSTALVDT,
    ae_start_date, ae_end_date, lb_date, trt_end_date,
    source_datasets = list(ae = ae_ext, adsl = adsl, lb = lb_ext),
    mode = "last"
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  adsl,
  display_vars = exprs(USUBJID, TRTEDT, DTHDTC, LSTALVDT, LALVDOM, LALVSEQ, LALVVAR),
  filter = !is.na(TRTSDT)
)
```
 

## Derive Groupings and Populations {#groupings}

### Grouping (e.g. `AGEGR1` or `REGION1`) {#groupings_ex}

Numeric and categorical variables (`AGE`, `RACE`, `COUNTRY`, etc.) may need to be grouped to perform
the required analysis.
`{admiral}` does not **currently** have functionality to assist with all required groupings. So, the user will often need to create his/her own function to meet his/her study requirement. 

For example, if 

- `AGEGR1` is required to categorize `AGE` into `<18`, `18-64` and `>64`, or
- `REGION1` is required to categorize `COUNTRY` in `North America`, `Rest of the World`,

the user defined functions would look like the following:

```{r eval=TRUE}
format_agegr1 <- function(var_input) {
  case_when(
    var_input < 18 ~ "<18",
    between(var_input, 18, 64) ~ "18-64",
    var_input > 64 ~ ">64",
    TRUE ~ "Missing"
  )
}

format_region1 <- function(var_input) {
  case_when(
    var_input %in% c("CAN", "USA") ~ "North America",
    !is.na(var_input) ~ "Rest of the World",
    TRUE ~ "Missing"
  )
}
```

These functions are then used in a `mutate()` statement to derive the required grouping variables:

```{r eval=TRUE}
adsl <- adsl %>%
  mutate(
    AGEGR1 = format_agegr1(AGE),
    REGION1 = format_region1(COUNTRY)
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  adsl,
  display_vars = exprs(USUBJID, AGE, SEX, COUNTRY, AGEGR1, REGION1)
)
```

### Population Flags (e.g. `SAFFL`) {#popflag}

Since the populations flags are mainly company/study specific no dedicated functions are
provided, but in most cases they can easily be derived using `derive_var_merged_exist_flag`.

An example of an implementation could be:

```{r eval=TRUE}
adsl <- adsl %>%
  derive_var_merged_exist_flag(
    dataset_add = ex,
    by_vars = exprs(STUDYID, USUBJID),
    new_var = SAFFL,
    condition = (EXDOSE > 0 | (EXDOSE == 0 & str_detect(EXTRT, "PLACEBO")))
  )
```

```{r, eval=TRUE, echo=FALSE}
dataset_vignette(
  adsl,
  display_vars = exprs(USUBJID, TRTSDT, ARM, ACTARM, SAFFL)
)
```


## Derive Other Variables  {#other}
The users can add specific code to cover their need for the analysis.

The following functions are helpful for many ADSL derivations:

  - `derive_vars_merged()` - Merge Variables from a Dataset to the Input Dataset
  - `derive_var_merged_exist_flag()` - Merge an Existence Flag
  - `derive_var_merged_cat()` - Merge a Categorization Variable
  - `derive_var_merged_character()` - Merge a Character Variable
  - `derive_var_merged_summary()` - Merge a Summary Variable

See also [Generic Functions](generic.html).

## Add Labels and Attributes {#attributes}

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

- [metacore](https://atorus-research.github.io/metacore/): establish a common
foundation for the use of metadata within an R session.

- [metatools](https://pharmaverse.github.io/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](https://atorus-research.github.io/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)](https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/movefile/n1xbwdre0giahfn11c99yjkpi2yb.htm).

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](https://github.com/pharmaverse). An example of applying metadata 
and perform associated checks can be found at the [pharmaverse E2E example](https://examples.pharmaverse.org/data/adsl/).

# Example Script 

ADaM | Sample Code
---- | --------------
ADSL | [ad_adsl.R](https://github.com/pharmaverse/admiral/blob/main/inst/templates/ad_adsl.R){target="_blank"} 
