Building ADSL with admiral
The subject-level analysis dataset, derived end to end.
Learning objectives
- 1Derive treatment variables and population flags (SAFFL, ITTFL, FASFL).
- 2Compute treatment start/end dates and durations using admiral helpers.
- 3Create demographic groupings (AGEGR1, AGEGR2, RACE, etc.).
- 4Assemble a submission-ready ADSL with proper variable ordering and labels.
Key SAS® → R comparison
| Task | SAS® | R |
|---|---|---|
| Population flags | Multiple if/else or macros on DM+EX | admiral::derive_var_merged() + case_when |
| Treatment dates | PROC SUMMARY + retain/merge | derive_vars_merged(derivation = date_source(...)) |
| Duration (days) | TRTEDT - TRTSDT + 1 | derive_var_trtdurd() |
| Baseline characteristics | Custom formats + PROC FREQ | admiral + dplyr summaries |
Code examples
if first.usubjid;
saffl = 'Y' if ex exists and not screen failure;
ittfl = 'Y';
run;adsl <- dm |>
derive_vars_merged(
dataset_add = ex,
filter_add = !is.na(EXSTDTC),
new_vars = exprs(TRTSDT = convert_dtc_to_dt(EXSTDTC))
) |>
mutate(
SAFFL = if_else(!is.na(TRTSDT) & !is.na(RFENDT), "Y", "N"),
ITTFL = "Y"
)Note: admiral's date conversion functions handle ISO dates robustly and are heavily tested for regulatory use.
trtdurd = trtedt - trtsdt + 1;
if trt01a = '' then trt01a = trt01p;adsl <- adsl |>
derive_var_trtdurd() |>
mutate(TRT01A = if_else(is.na(TRT01A), TRT01P, TRT01A))Note: derive_var_trtdurd() is a one-liner that respects the exact FDA/PMDA conventions for duration calculation.
if age < 65 then agegr1 = '<65';
else if age < 75 then agegr1 = '65-74';
else agegr1 = '>=75';
bmi = weight / (height/100)**2;adsl <- adsl |>
mutate(
AGEGR1 = case_when(
AGE < 65 ~ "<65",
AGE < 75 ~ "65-74",
TRUE ~ ">=75"
),
BMIBL = round(WEIGHTBL / (HEIGHTBL / 100)^2, 1)
)Note: All derived variables in ADSL should carry clear labels and be documented in the ADaM spec (define.xml).
Explanation
ADSL is the single most important analysis dataset you will create. Every other ADaM (ADLB, ADVS, ADAE, ADTTE, etc.) left-joins to it. Because of this, errors or missing flags in ADSL cascade into every table and figure.
admiral shines here by giving you battle-tested functions for the repetitive parts (treatment date derivation, population flags, duration) while still letting you use ordinary dplyr for study-specific logic. This combination produces code that is both concise and auditable.
In a real submission you will also add sponsor-specific variables (e.g. custom stratification factors, region groupings, biomarker flags). The discipline of keeping ADSL derivation in one well-commented script pays enormous dividends during validation and regulatory review.