Why this matters
Regulators don’t want you to rebuild your database in SDTM. They expect you to transform what you actually collected (and what vendors delivered) into standardized structures with clear lineage to the sources. Getting this wrong leads to:
- CRFs that mirror SDTM (hard for sites to use),
- fragile mappings that break when vendors change a file,
- failed validation and weak traceability during inspection.
Treat SDTM as a repeatable data engineering pipeline with documented rules, not manual re‑entry. Mapping reshapes, recodes and converts; it never corrects or fills in what was collected. A data problem goes back as a data query to the site, or to the vendor to correct and re‑send.
Core concepts & definitions
SDTM (Study Data Tabulation Model) — The CDISC standard for tabulation data: what was collected, arranged in standard datasets and variables for submission (e.g., DM: Demographics; VS: Vital Signs; AE: Adverse Events; LB: Laboratory). The FDA and Japan’s PMDA require it in submissions; analysis datasets follow a separate CDISC standard, ADaM.
Domain — One dataset for one topic of data, with a two‑letter code and a stated grain (VS: one record per subject, visit and test; DM: one per subject). Variables are Required (never empty), Expected (present, may be empty) or Permissible (used when collected or derived).
General Observation Classes —
- Events (e.g., AE),
- Findings (e.g., LB, VS),
- Interventions (e.g., EX).
Variable roles and names — Each variable is an Identifier (
STUDYID,DOMAIN,USUBJID,--SEQ), a Topic (--TESTCDin Findings,--TERMin Events,--TRTin Interventions), a Timing variable (--DTC,VISIT) or a Qualifier.--stands for the two‑letter domain code (--ORRESisVSORRESin VS).USUBJIDidentifies one subject across the submission;--SEQnumbers that subject’s records in a domain.Mapping / Transformation — Rules that move and reshape data from sources (EDC, vendor files, derived outputs) into SDTM variables and structures.
Controlled terminology — Standard code lists: CDISC Controlled Terminology (versioned codelists for test codes, units, yes/no answers) and external dictionaries (MedDRA for adverse events, WHODrug for medications). A CDISC codelist is extensible (the sponsor may add a documented term when none fits) or non‑extensible (published terms only, e.g., yes/no). Aim for one canonical code per concept.
Value‑Level Metadata (VLM) — Metadata that apply to specific values/rows, not just the whole variable (e.g., when
VSTESTCD = SYSBP, the unit inVSSTRESUmust be mmHg). It is recorded in define.xml.Traceability — Ability to follow each SDTM value back to its source field(s) and derivation. It is documented in define.xml (Define‑XML: machine‑readable metadata for every dataset, variable and codelist, with each Origin and derivation Method), the aCRF (annotated CRF: the blank CRF marked with the SDTM variable each field maps to) and the internal mapping spec. For cross‑domain links, use the RELREC (related records) dataset or linking variables (e.g.,
--LNKID).Supplemental qualifiers (SUPP--) — Datasets such as
SUPPAEfor collected values with no standard variable, tied to their parent record; never a test result.
The process, step‑by‑step
Inventory sources List every input: EDC forms/fields, vendor transfers (labs, ECG, PK), coded data (MedDRA, WHODrug), and planned derivations. Note file versions and delivery frequencies.
Assign SDTM domains Decide where each concept lands (e.g., vitals → VS, concomitant meds → CM). Every study has DM; other special‑purpose datasets (e.g., SE, SV, CO) are used as needed. Create a custom (non‑standard) domain only when no published domain fits, and build it on one of the three classes.
Define mappings Build a variable‑level mapping table with: Source.Table, Source.Field, Rule/Transform, Target.Domain.Variable, Conditions, Origin (e.g., CRF, eDT (electronic data transfer, such as a vendor file), Derived, or Assigned for coded terms), and Algorithm/Version for derivations. Add VLM when a rule depends on test code or other values.
Apply controlled terms Normalize to CDISC codelists (sponsor codelists where CDISC has none) through a documented crosswalk:
Yes→YandNo→Nis one‑to‑one, the spelling changes and the categories do not. Never force a value into the nearest term: extend an extensible codelist with a documented term, or raise a data query if the value is unclear. Document unit conversions (what changed, how, and why). Keep the collected result and unit in--ORRES/--ORRESUexactly as recorded. Store the standardized result as text in--STRESC, as a number in--STRESN(empty when not numeric, e.g.,NEGATIVE), and its unit in--STRESU.Validate early and often Run conformance rules with a validator (e.g., Pinnacle 21, P21). Fix Error class findings, fix or justify Warning findings with evidence, and investigate Notice items that hint at quality gaps. Fix each finding where it starts: a mapping fault in the spec and program; a data fault through a data query to the site or a vendor re‑send. A finding that reflects true data is explained in the Study Data Reviewer’s Guide (SDRG). Never edit SDTM values or hard‑code a correction.
Document lineage Produce a complete aCRF, mapping spec, controlled terminology plan, and ultimately define.xml with Origin and Method text for derivations. Keep everything versioned.
What good looks like
A mapping spec that reads like a recipe, not a narrative:
- Source → Rule → Target for every variable (and VLM when rules vary by value).
- Algorithm names/versions (e.g.,
BMI_v1.1) referenced wherever used. - Origins (CRF/eDT/Derived) declared consistently.
A terminology plan: which codelists and versions you use, how units convert, who governs updates.
A validation report with triage: Errors fixed at their cause or, where they reflect true data, explained in the reviewer’s guide; Warnings either fixed or justified with evidence (not blanket waivers).
Submission‑ready artifacts: aCRF, SDRG, and define.xml that tell the same traceability story as your mapping spec.
Worked examples
Example 1 — Vitals from EDC → VS (with BMI derivation)
Scenario. An EDC “Vitals” form captures Systolic BP, Diastolic BP, Heart Rate, Height, Weight, with local units (some sites use imperial, others metric). BMI is not collected in EDC; this sponsor’s standards derive it in VS (many sponsors derive it only in analysis datasets).
Source (EDC extract, simplified).
| Form | Field | Example value |
|---|---|---|
| VITALS | SYS_BP | 120 |
| VITALS | DIA_BP | 80 |
| VITALS | HR | 72 |
| VITALS | HEIGHT | 170 (cm) |
| VITALS | WEIGHT | 70 (kg) |
| VITALS | UNIT_HEIGHT | cm |
| VITALS | UNIT_WEIGHT | kg |
| VITALS | VISIT | Week 4 |
| VITALS | DATE_TIME | 2024-06-15T09:30 |
Mapping highlights.
Create one VS record per test (
VSTESTCD:SYSBP,DIABP,HR,HEIGHT,WEIGHT, and derivedBMI): the form’s one row for the visit becomes six VS records.Keep collected values/units in
VSORRES/VSORRESU. Store standardized results inVSSTRESC(text; not shown below),VSSTRESN(numeric) andVSSTRESU. Convert as needed (e.g., lb to kg, in to m).Derive BMI in VS with the named algorithm (weight in kg divided by the square of height in m: 70 ÷ 2.89 = 24.22); flag the record as derived (
VSDRVFL = Y) and mark Origin = Derived and Method = BMI_v1.1 in define.xml.Note: SDTM tabulates what was collected, so most derivations belong in analysis datasets (ADaM). BMI has a standard test code (
VSTESTCD = BMI), so a collected or SDTM‑derived BMI is a VS record, never a supplemental qualifier (SUPP--).
Sample rows (target: VS).
| STUDYID | USUBJID | DOMAIN | VSSEQ | VSTESTCD | VSTEST | VSORRES | VSORRESU | VSSTRESN | VSSTRESU | VSDTC | VISIT | Note (not a variable) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ABC123 | ABC-001 | VS | 1 | SYSBP | Systolic Blood Pressure | 120 | mmHg | 120 | mmHg | 2024-06-15T09:30 | Week 4 | collected |
| ABC123 | ABC-001 | VS | 2 | DIABP | Diastolic Blood Pressure | 80 | mmHg | 80 | mmHg | 2024-06-15T09:30 | Week 4 | collected |
| ABC123 | ABC-001 | VS | 3 | HR | Heart Rate | 72 | beats/min | 72 | beats/min | 2024-06-15T09:30 | Week 4 | collected |
| ABC123 | ABC-001 | VS | 4 | HEIGHT | Height | 170 | cm | 1.70 | m | 2024-06-15T09:30 | Week 4 | standardized |
| ABC123 | ABC-001 | VS | 5 | WEIGHT | Weight | 70 | kg | 70 | kg | 2024-06-15T09:30 | Week 4 | collected |
| ABC123 | ABC-001 | VS | 6 | BMI | Body Mass Index | — | — | 24.22 | kg/m2 | 2024-06-15T09:30 | Week 4 | Derived (VSDRVFL = Y): BMI_v1.1 |
Value‑Level Metadata (VLM) snapshot (VS).
| Where (Condition) | Variable | Rule |
|---|---|---|
VSTESTCD = SYSBP |
VSSTRESU |
must be mmHg |
VSTESTCD = HR |
VSSTRESU |
must be beats/min |
VSTESTCD = HEIGHT |
VSSTRESU |
must be m (convert from cm/in) |
VSTESTCD = WEIGHT |
VSSTRESU |
must be kg (convert from lb) |
VSTESTCD = BMI |
VSORRES/VSORRESU |
not populated (derived); Method = BMI_v1.1 |
Traceability. Mapping spec shows the exact EDC fields used; define.xml includes Origin = Derived and Method with the algorithm name/version.
Example 2 — Adverse Events (EDC + MedDRA) → AE
Scenario. Sites record AE verbatim and attributes; coding uses MedDRA (dictionary version captured by the coder).
Source (EDC extract, simplified).
| Field | Example |
|---|---|
| AE_TERM (verbatim) | Headache |
| AE_START_DT / AE_END_DT | 2024‑05‑01 / 2024‑05‑03 |
| AE_SERIOUS | No |
| AE_SEVERITY | Moderate |
| AE_RELATED | Not Related |
| AE_ACTION_TAKEN | Drug Interrupted |
| AE_OUTCOME | Recovered |
| MEDDRA_PT / SOC | Headache / Nervous system disorders |
| MEDDRA_VERSION | 26.1 |
| VISIT | Week 2 |
Mapping highlights.
- Verbatim term →
AETERM; coded terms →AEDECOD(Preferred Term),AESOC(System Organ Class); recordAELLTif available. - Start/end →
AESTDTC,AEENDTC(ISO 8601 text, e.g.,2024-05-01or2024-06-15T09:30; allow partial dates if that’s how they were collected—don’t impute in SDTM). - Seriousness, severity, relationship, action taken, outcome → corresponding Qualifier variables (
AESER,AETOXGRorAESEVper collection,AEREL,AEACN,AEOUT). - Collected text is mapped to the codelist term, not copied:
No→N,Recovered→RECOVERED/RESOLVED. - Dictionary name and version (here MedDRA 26.1) → documented once in define.xml and the reviewer’s guide, not in a spare or sponsor‑invented AE variable (a standard domain takes only SDTM variables).
Sample rows (target: AE).
| STUDYID | USUBJID | DOMAIN | AESEQ | AETERM | AEDECOD | AESOC | AESTDTC | AEENDTC | AESER | AESEV | AEREL | AEACN | AEOUT | Note (not a variable) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ABC123 | ABC-001 | AE | 1 | Headache | Headache | Nervous system disorders | 2024‑05‑01 | 2024‑05‑03 | N | MODERATE | NOT RELATED | DRUG INTERRUPTED | RECOVERED/RESOLVED | coded with MedDRA 26.1 |
Validation tip. Ensure AEDECOD is present when coding is required; verify AESTDTC <= AEENDTC; confirm codelist values match controlled terms.
Example 3 — Central lab file → LB (with unit standardization)
Scenario. Vendor sends labs in mixed units; sponsor requires standardized units.
Source (vendor extract, simplified).
| LBTESTCD | LBORRES | LBORRESU | LBDTC | VISIT |
|---|---|---|---|---|
| ALT | 40 | U/L | 2024‑06‑10 | Week 4 |
| GLUC | 95 | mg/dL | 2024‑06‑10 | Week 4 |
Mapping highlights.
- Keep originals in
LBORRES/LBORRESU. - Convert to the study’s standard units in
LBSTRESC/LBSTRESN/LBSTRESUwith a sponsor‑approved, versioned conversion. Glucose: 95 mg/dL ÷ 18.016 (molar mass 180.16 g/mol) = 5.27 mmol/L; a rounded factor of 18.0 gives 5.28, so the algorithm fixes the factor. - Capture the lab’s reference range as received (
LBORNRLO/LBORNRHI) and in standard units (LBSTNRLO/LBSTNRHI), and the resulting indicator (LBNRIND); ranges are omitted here.
Sample rows (target: LB).
| STUDYID | USUBJID | DOMAIN | LBSEQ | LBTESTCD | LBTEST | LBORRES | LBORRESU | LBSTRESN | LBSTRESU | LBDTC | LBNRIND |
|---|---|---|---|---|---|---|---|---|---|---|---|
| ABC123 | ABC-001 | LB | 1 | ALT | Alanine Aminotransferase | 40 | U/L | 40 | U/L | 2024‑06‑10 | NORMAL |
| ABC123 | ABC-001 | LB | 2 | GLUC | Glucose | 95 | mg/dL | 5.27 | mmol/L | 2024‑06‑10 | NORMAL |
VLM snapshot (LB).
| Where (Condition) | Variable | Rule |
|---|---|---|
LBTESTCD = ALT |
LBSTRESU |
U/L only |
LBTESTCD = GLUC |
LBSTRESU |
mmol/L only; mg/dL ÷ 18.016 (sponsor‑approved, e.g., UnitConvLib v2.1) |
Pitfalls & misconceptions
- Myth: “SDTM is data re‑entry.” No—SDTM is a mapping/transformation pipeline. Re‑entry destroys provenance and is error‑prone.
- CRFs that mimic SDTM. Forcing SDTM’s submission structure (one row per test, coded values, variable names) onto forms adds burden to sites and can still fail validation. Design for clean capture with collection standards (CDISC CDASH, built to map to SDTM) and plan the mapping at CRF design.
- Using SUPP-- for standard variables. A test result (e.g., BMI) is a record in its parent domain (VS), and a qualifier that has a standard variable uses that variable; supplemental qualifiers are only for non‑standard variables.
- Silent waivers. Marking all validator findings as “known issues” without root‑cause analysis is risky. Fix upstream where possible.
- Fixing data in the mapping. A weight of 150 in a kg‑only field may be pounds, but mapping never guesses: it does not rescale the value, swap dates or fill gaps. Data management raises a data query and the site corrects or confirms its own data.
- Unit chaos.
Inconsistent unit conversions (or missing VLM rules) lead to conflicting
--STRESUvalues across records. - Imputing dates in SDTM.
SDTM reflects what was collected. Partial dates are allowed: a start date known only as May 2024 is stored as
2024-05, not2024-05-01. Do not impute in SDTM (that belongs in analysis datasets).
Practice in the wild (checklist)
- Build a variable‑level mapping table (Source → Rule → SDTM variable), including Origin and Algorithm/Version for derivations.
- Define Value‑Level Metadata where rules depend on a test/code value.
- Normalize to controlled terminology; document every unit conversion.
- Run validator rules (e.g., P21). Fix Errors, justify Warnings with evidence, and address Notices when they indicate quality issues.
- Keep aCRF, mapping spec, define.xml consistent and version‑controlled.
- Prove traceability: each SDTM value has a path back to source (and forward to analysis if applicable).
Key points to remember
- Treat SDTM as a traceable transformation pipeline—never as data re‑entry.
- Design CRFs for clean capture, then map concepts to the correct SDTM domains (DM, VS, AE, LB, etc.); do not make CRFs mimic SDTM structures.
- Build a variable‑level Source → Rule/Transform → Target mapping with Origin (CRF/eDT/Derived) declared for every value.
- Document derivations with named, versioned algorithms and record the Method in submission metadata (e.g., define.xml) and the mapping spec.
- Keep original results/units in
--ORRES/--ORRESU; place standardized results/units in--STRESC/--STRESN/--STRESU, with clear unit conversion logic. - Govern and apply controlled terminology (e.g., MedDRA, unit/test codelists) and track dictionary versions consistently.
- Use Value‑Level Metadata (VLM) to constrain rules and units by specific tests/codes; ensure unit standardization is explicit and auditable.
- Most derivations belong in analysis datasets; one that is tabulated (e.g., BMI in VS) is a flagged record in its parent domain; reserve SUPP-- for non‑standard qualifiers only.
- Reflect partial dates as collected in SDTM; do not impute within SDTM.
- Maintain end‑to‑end traceability across the aCRF, mapping spec, and define.xml; use RELREC/ linking variables (e.g.,
--LNKID) for cross‑domain relationships. - Validate early and often (e.g., with Pinnacle 21): fix Errors, fix or justify Warnings with evidence, and review Notices for quality signals; fix each issue where it starts (the mapping, or the data via a data query or vendor re‑send), never by editing SDTM values.
- Version‑control mapping specs, terminology plans, algorithms, and submission artifacts so the lineage is reproducible and inspection‑ready.
- Use special‑purpose datasets appropriately (e.g., SE, SV, CO) and avoid creating non‑standard domains unless truly necessary.