- What ADaM Is
- Where ADaM Fits
- The Three Major ADaM Structures
- ADSL: The Subject-Level Dataset
- BDS: Basic Data Structure
- OCCDS: Occurrence Data Structure
- Core Analysis Variables
- PARAM and PARAMCD
- Baseline and Change
- Treatment Variables
- Timing and Analysis Windows
- Analysis Flags
- Derivations and Analysis Logic
- Traceability
- SAS Implementation
- Worked Example
- Common Mistakes
- Final Checklist
1. What ADaM Is
The Analysis Data Model (ADaM) is designed to support efficient generation, replication, and review of clinical-trial analyses. Whereas SDTM primarily organizes standardized tabulation data, ADaM organizes data in a form that directly supports the statistical analyses described in the study's analysis documentation.
The key idea is simple: ADaM should make the analysis understandable and reproducible. A reviewer should be able to determine where an analysis value came from, how it was derived, which population it belongs to, and why a particular record was selected.
ADaM is not simply "SDTM with more variables"
An ADaM dataset often contains variables that do not exist in SDTM, such as BASE, CHG, PCHG, analysis flags, treatment variables, analysis dates, and analysis-window variables.
These variables exist because the analysis needs them. Their derivation should be documented and traceable rather than created merely because a programmer finds them convenient.
2. Where ADaM Fits in the Data Flow
A useful mental model is the progression from collection to analysis:
| Layer | Primary Question | Typical Example |
|---|---|---|
| Source | What was collected? | CRF, laboratory result, vendor assessment |
| SDTM | How should the clinical observation be standardized? | LB, VS, AE, EX, DS |
| ADaM | How should the data be represented for analysis? | ADSL, ADAE, ADLB, ADVS |
| Output | What statistical result should be reported? | Summary table, forest plot, KM curve |
3. The Three Major ADaM Structures
Three ADaM structures are especially important for programmers: ADSL, BDS, and OCCDS. They solve different data-shaping problems.
| Structure | Purpose | Typical Dataset | Typical Grain |
|---|---|---|---|
| ADSL | One record per subject containing subject-level analysis information | ADSL | One record per subject |
| BDS | Repeated analysis records organized around a parameter | ADLB, ADVS | Subject + parameter + timepoint |
| OCCDS | Occurrence-oriented events and records | ADAE | Subject + occurrence/event |
4. ADSL: The Subject-Level Dataset
ADSL contains one record per subject and serves as the central subject-level analysis dataset. It commonly contains treatment assignments, population flags, important dates, demographic variables, baseline characteristics, and other subject-level analysis variables.
| Variable | Purpose | Example |
|---|---|---|
USUBJID | Unique subject identifier | ABC-001-001 |
TRT01P | Planned treatment | Drug A |
TRT01A | Actual treatment | Drug A |
SAFFL | Safety population flag | Y |
ITTFL | Intent-to-treat population flag, when defined by the study | Y |
RANDFL | Randomized population flag, when applicable | Y |
TRTSDT | Treatment start date | 2026-01-15 |
TRTEDT | Treatment end date | 2026-04-09 |
ADSL is often used as the subject-level backbone for other ADaM datasets. A BDS dataset can be linked to ADSL using USUBJID, allowing subject-level population and treatment information to be attached to analysis records.
ADSL should remain one record per subject
A common programming error is accidentally creating multiple ADSL records by merging a one-to-many source dataset into ADSL without summarizing it first. If a subject has three adverse events, that does not mean ADSL should have three records.
5. BDS: Basic Data Structure
BDS is one of the most important structures to understand because it supports repeated analysis measurements. A typical BDS record represents one subject, one analysis parameter, and one analysis timepoint or assessment.
| Variable | Meaning |
|---|---|
USUBJID | Subject identifier |
PARAMCD | Short parameter code |
PARAM | Human-readable parameter description |
AVAL | Analysis value |
BASE | Baseline analysis value, when applicable |
CHG | Change from baseline |
PCHG | Percent change from baseline, when applicable |
ADT | Analysis date |
AVISIT | Analysis visit |
ANL01FL | Example analysis-record selection flag |
The concept of grain
Before writing code, state the intended grain in plain English. For example:
If your program cannot preserve that grain, stop and investigate. Many ADaM defects are actually grain defects caused by joins, duplicate source records, or poorly defined derivations.
6. OCCDS: Occurrence Data Structure
Occurrence-oriented data structures are useful when the fundamental unit is an event or occurrence rather than a numeric measurement. A common example is an adverse-event analysis dataset.
For example, an ADAE record may represent one adverse-event occurrence for a subject, with variables describing the event, treatment, dates, seriousness, severity, relationship, and analysis flags.
| Concept | Example |
|---|---|
| Subject | ABC-001-001 |
| Event term | Headache |
| Start date | 2026-02-03 |
| End date | 2026-02-05 |
| Severity | Moderate |
| Serious | No |
| Analysis flag | Y |
The exact variables and derivations depend on the study, ADaM guidance, and analysis requirements. The important structural idea is that the record represents an occurrence.
7. Core Analysis Variables
ADaM variables are easiest to understand when grouped by purpose rather than memorized individually.
| Group | Examples | Why They Matter |
|---|---|---|
| Identifiers | STUDYID, USUBJID | Identify the study and subject |
| Treatment | TRT01P, TRT01A | Define planned and actual treatment |
| Parameter | PARAM, PARAMCD | Define what is being analyzed |
| Analysis value | AVAL, AVALC | Represent the value used in analysis |
| Baseline/change | BASE, CHG, PCHG | Support longitudinal analyses |
| Timing | ADT, ADY, AVISIT, AVISITN | Place observations in analysis time |
| Selection | ANL01FL, ONTRTFL, ABLFL | Identify records used for particular analyses |
| Population | SAFFL, ITTFL, PPROTFL | Define analysis populations |
8. PARAM and PARAMCD
In BDS, PARAM and PARAMCD define the analysis concept represented by the record.
| PARAMCD | PARAM |
|---|---|
| SYSBP | Systolic Blood Pressure (mmHg) |
| DIABP | Diastolic Blood Pressure (mmHg) |
| HR | Heart Rate (beats/min) |
| WEIGHT | Weight (kg) |
A subject may therefore have multiple records at a visit because each parameter is represented separately.
For example, if one subject has systolic blood pressure and heart rate measured at Week 4, the BDS structure might contain:
| USUBJID | PARAMCD | PARAM | AVISIT | AVAL |
|---|---|---|---|---|
| 001 | SYSBP | Systolic Blood Pressure (mmHg) | Week 4 | 124 |
| 001 | HR | Heart Rate (beats/min) | Week 4 | 72 |
9. Baseline, Change, and Percent Change
Baseline is an analysis definition, not automatically the first value found in the raw data.
Suppose a subject has baseline \(120\) and a post-baseline value \(108\). Change from baseline is:
\[ CHG = AVAL - BASE = 108 - 120 = -12 \]Percent change is:
\[ PCHG = \frac{AVAL - BASE}{BASE}\times100 \]For the same subject:
\[ PCHG = \frac{108-120}{120}\times100 = -10\% \]| Record | AVAL | BASE | CHG | PCHG |
|---|---|---|---|---|
| Baseline | 120 | 120 | 0 | 0% |
| Week 4 | 108 | 120 | -12 | -10% |
| Week 8 | 105 | 120 | -15 | -12.5% |
10. Treatment Variables
Treatment variables allow analysis datasets to retain the treatment concepts needed by the analysis. A common distinction is between planned treatment and actual treatment.
| Concept | Typical Variable | Meaning |
|---|---|---|
| Planned treatment | TRT01P | Treatment planned according to the study design/randomization |
| Actual treatment | TRT01A | Treatment actually received, according to the analysis definition |
| Planned treatment code | TRT01PN | Numeric representation for ordering/statistical processing |
| Actual treatment code | TRT01AN | Numeric representation for ordering/statistical processing |
The exact treatment strategy is analysis-dependent. The programmer should not decide treatment assignment logic solely from the variable names. The study specification and analysis conventions control the derivation.
11. Timing and Analysis Windows
Clinical observations have source dates and visits, but analysis often requires a standardized analysis date, study day, visit, and analysis-window assignment.
| Variable | Concept |
|---|---|
| ADT | Analysis date |
| ADY | Analysis day relative to a defined reference date |
| AVISIT | Analysis visit label |
| AVISITN | Numeric analysis visit used for ordering |
| ATPT | Analysis timepoint, when applicable |
For a simple study-day derivation, if the analysis date is January 20 and the reference treatment-start date is January 15:
\[ ADY = ADT - TRTSDT + 1 = 20 - 15 + 1 = 6 \]Be careful with the reference date. Study-day conventions are not universal across every analysis dataset, and the specification should determine whether the reference is treatment start, randomization, first dose, or another date.
12. Analysis Flags
Analysis flags are one of the defining practical features of ADaM. They allow the dataset to retain multiple valid observations while identifying which record should be used for a particular analysis.
| Flag | Illustrative Purpose |
|---|---|
| ANL01FL | Primary analysis record selection |
| ANL02FL | Another prespecified analysis selection |
| ABLFL | Identifies the analysis baseline record |
| ONTRTFL | Identifies records meeting an on-treatment definition |
| SAFFL | Subject belongs to the safety population |
Example: selecting one record per visit
Suppose several measurements fall inside a Week 4 analysis window. The specification may define a rule such as closest to the target day, with a tie-breaker based on date or time. The selected record can then receive ANL01FL='Y'.
13. Derivations and Analysis Logic
ADaM derivations should be reproducible from documented inputs. A useful derivation hierarchy is:
For example, change from baseline follows a simple mathematical relationship:
\[ CHG_i = AVAL_i - BASE_i \]But the difficult part is usually not the subtraction. The difficult part is defining which record supplies BASE and which records are eligible for AVAL.
14. Traceability
Traceability is the ability to follow an analysis result backward through the analysis dataset and its derivations to the standardized clinical data and, where appropriate, the source data.
| Layer | Example |
|---|---|
| Output | Mean change from baseline at Week 12 |
| ADaM | ADLB with AVAL, BASE, CHG, AVISIT, ANL01FL |
| SDTM | LB with LBSTRESN, LBDTC, VISIT |
| Source | Laboratory result collected for the subject |
A good ADaM dataset does not merely produce the correct number. It makes the path to that number understandable.
15. SAS Implementation
The following example illustrates a simple BDS-style derivation of change from baseline. The actual production program would normally contain substantially more checks and study-specific logic.
data adlb;
set sdtm_lb;
length PARAMCD $8 PARAM $60;
PARAMCD = "SYSBP";
PARAM = "Systolic Blood Pressure (mmHg)";
AVAL = LBSTRESN;
ADT = input(substr(LBDTC,1,10), yymmdd10.);
format ADT yymmdd10.;
run;
Baseline can then be determined using an explicit study rule. A simplified illustration is shown below.
proc sort data=adlb;
by USUBJID PARAMCD ADT;
run;
data adlb_base;
set adlb;
by USUBJID PARAMCD;
retain BASE;
if first.PARAMCD then BASE = .;
/* Illustrative rule only:
replace with the study-specific baseline definition. */
if missing(BASE) and ABLFL = "Y" then BASE = AVAL;
if not missing(BASE) then do;
CHG = AVAL - BASE;
if BASE ne 0 then
PCHG = 100 * (AVAL - BASE) / BASE;
end;
drop ABLFL;
run;
Using PROC SQL for subject-level joins
proc sql;
create table adlb2 as
select
a.*,
b.TRT01P,
b.TRT01A,
b.SAFFL,
b.ITTFL
from adlb_base as a
left join adsl as b
on a.USUBJID = b.USUBJID
;
quit;
The join is safe only if ADSL truly contains one record per subject. If ADSL has duplicate subject records, the join can multiply BDS records.
16. Worked Example: From SDTM LB to ADLB
Consider a simplified laboratory dataset. A subject has two systolic-style numeric laboratory observations in our hypothetical example: a baseline measurement of 120 and a Week 4 measurement of 108.
| USUBJID | LBDTC | LBSTRESN | VISIT |
|---|---|---|---|
| 001 | 2026-01-15 | 120 | Baseline |
| 001 | 2026-02-12 | 108 | Week 4 |
The analysis representation could become:
| USUBJID | PARAMCD | AVISIT | AVAL | BASE | CHG | ABLFL | ANL01FL |
|---|---|---|---|---|---|---|---|
| 001 | SYSBP | Baseline | 120 | 120 | 0 | Y | Y |
| 001 | SYSBP | Week 4 | 108 | 120 | -12 | Y |
Notice what changed. SDTM supplied the standardized observation. ADaM added the analysis interpretation: a parameter, analysis value, baseline, change, analysis visit, and record-selection logic.
Why this structure is useful
A summary program can now group by treatment and analysis visit without reconstructing the baseline logic every time:
proc means data=adlb2 n mean std median min max;
where ANL01FL = "Y"
and PARAMCD = "SYSBP";
class TRT01A AVISIT;
var CHG;
run;
The important point is not that PROC MEANS is complicated. The important point is that the analysis dataset has already encoded the decisions required by the analysis.
17. Common ADaM Programming Mistakes
1. Treating ADaM as a simple copy of SDTM
ADaM should support analysis. Simply renaming SDTM variables without implementing the analysis definitions usually produces a weak dataset.
2. Defining baseline incorrectly
Using the first chronological record without checking the study-specific baseline rule is a common source of errors.
3. Ignoring dataset grain
Unexpected duplicates often originate from joins that violate the intended one-record-per-subject, subject-parameter, or subject-event structure.
4. Creating analysis flags without documenting their purpose
A flag named ANL01FL is not self-explanatory. Its derivation and intended use should be defined in the metadata/specification.
5. Mixing planned and actual treatment
Treatment variables have different statistical meanings. The correct variable depends on the analysis population and treatment assignment convention.
6. Recalculating derivations independently in every output program
If every table program independently determines baseline and analysis windows, inconsistent results become much more likely. Centralizing analysis logic in ADaM improves reproducibility.
7. Losing traceability during transformations
Complex derivations should remain understandable. When source records are collapsed, selected, or combined, the logic should be documented and testable.
18. ADaM Programming Checklist
- ☐ Confirm the required ADaM structure and applicable implementation guidance.
- ☐ Define the intended dataset grain before programming.
- ☐ Confirm the source SDTM domains and variables.
- ☐ Confirm planned and actual treatment definitions.
- ☐ Define the analysis population rules.
- ☐ Define baseline using the approved analysis convention.
- ☐ Define analysis windows and visit assignment rules.
- ☐ Derive AVAL/AVALC consistently with the analysis parameter.
- ☐ Derive BASE, CHG, and PCHG only where appropriate.
- ☐ Define analysis flags and document their purpose.
- ☐ Check for duplicate records at the intended grain.
- ☐ Validate subject-level joins against ADSL.
- ☐ Check dates, study days, visits, and treatment periods.
- ☐ Verify traceability back to SDTM.
- ☐ Reconcile ADaM results with independent programming or validation outputs.
- ☐ Confirm metadata and Define-XML consistency.
- ☐ Review validation findings rather than simply suppressing them.
19. References and Further Learning
- Consult the applicable CDISC ADaM documentation and ADaM Implementation Guide version for the study.
- Use the study-specific analysis dataset specifications and approved analysis documentation as the controlling source for derivations.
- Review applicable controlled terminology and metadata requirements.
- Review regulatory study-data technical-conformance expectations applicable to the submission.