Introduction
If you are a clinical programmer moving from raw clinical-trial data into regulatory submission datasets, SDTM is one of the most important standards you will encounter.
The difficult part is not memorizing that adverse events belong in
AE or that laboratory data belong in
LB. The real programming challenge is learning
how to transform study-specific source data into a standardized structure
without changing the meaning of the observations.
SDTM stands for Study Data Tabulation Model. It provides a standardized way to organize and format clinical study data for downstream review, analysis, and submission.
Where SDTM Fits in the CDISC Ecosystem
A useful way to understand SDTM is to place it alongside the other major CDISC standards used during the clinical-trial lifecycle.
These standards are related, but they are not interchangeable.
SDTM Versus SDTMIG
One of the first distinctions a new programmer should understand is the difference between the SDTM model and the SDTM Implementation Guide.
| Item | Purpose | Programming Interpretation |
|---|---|---|
| SDTM | Conceptual standard/model | Defines the underlying structure and concepts |
| SDTMIG | Implementation guidance | Shows how domains and variables are practically implemented |
| Controlled Terminology | Standardized values | Defines permitted or expected coded values for applicable variables |
| Define-XML | Dataset metadata | Documents datasets, variables, origins, methods, and relationships |
For a real project, always use the versions specified by the sponsor, submission strategy, protocol/SAP conventions, and regulatory requirements. CDISC continues to evolve its standards, so the latest published or development version should not automatically be substituted for the version specified by the project.
A Note on Current SDTM Versions
At the time of writing, the established published baseline commonly encountered by programmers includes SDTM v2.0 together with SDTMIG v3.4. CDISC is also advancing newer versions, so programmers should verify the standards baseline for the specific submission before programming.
What Is an SDTM Domain?
An SDTM domain is a standardized collection of observations about a particular subject-matter area.
Examples include:
| Domain | Subject | Observation Class |
|---|---|---|
| DM | Demographics | Special-purpose |
| AE | Adverse events | Events |
| CM | Concomitant medications | Interventions |
| EX | Exposure | Interventions |
| LB | Laboratory test results | Findings |
| VS | Vital signs | Findings |
| EG | ECG test results | Findings |
| MH | Medical history | Events |
| DS | Disposition | Events |
| SV | Subject visits | Special-purpose |
A domain is usually represented as a dataset whose observations follow the structure defined by the applicable SDTM and SDTMIG specifications.
Observation Classes
The observation classes are among the most important SDTM concepts for a programmer.
They help determine what kind of observation is being represented and therefore which variable structures are appropriate.
| Class | Concept | Examples |
|---|---|---|
| Interventions | What was given, administered, or done to the subject | CM, EX, EC |
| Events | Incidents or occurrences involving the subject | AE, MH, DS |
| Findings | Observations or measurements made about the subject | LB, VS, EG |
| Findings About | Observations about an entity or finding | FA domains |
The Core SDTM Variable Pattern
Many SDTM domains can be understood using a small set of variable roles.
| Role | Purpose | Typical Examples |
|---|---|---|
| Identifier | Identifies the study, subject, or record | STUDYID, DOMAIN, USUBJID, --SEQ |
| Topic | Defines the main subject of the observation | AETERM, LBTESTCD, VSTESTCD |
| Qualifier | Adds context to the observation | --SEV, --CAT, --SCAT, --STAT |
| Timing | Describes when the observation occurred | --DTC, --DY, --ENDTC |
| Result | Captures the actual finding or result where applicable | --ORRES, --STRESC, --STRESN, --STRESU |
This structure is more useful than memorizing isolated variable names because the same design patterns recur across domains.
Identifiers: STUDYID, DOMAIN, and USUBJID
Three variables appear frequently across SDTM domains:
- STUDYID: identifies the study.
- DOMAIN: identifies the SDTM domain.
- USUBJID: identifies the unique subject within the study.
For example:
The exact construction of USUBJID is study-specific
and should follow the sponsor's conventions and SDTM implementation rules.
Sequence Variables
Many domains require a sequence variable such as AESEQ,
CMSEQ, or LBSEQ.
The sequence identifies individual records within a subject/domain context. It is not simply a row number copied from the source database.
Findings Domains
Findings domains represent observations or measurements.
Common examples include:
- LB: laboratory tests
- VS: vital signs
- EG: ECG findings
- QS: questionnaires
- PE: physical examination findings
A typical Findings record has a test code, test name, original result, and standardized result.
| Variable | Example | Purpose |
|---|---|---|
| LBTESTCD | ALT | Short standardized test code |
| LBTEST | Alanine Aminotransferase | Test name |
| LBORRES | 42 | Original result |
| LBORRESU | U/L | Original unit |
| LBSTRESC | 42 | Standardized character result |
| LBSTRESN | 42 | Standardized numeric result |
| LBSTRESU | U/L | Standardized unit |
Original Results Versus Standardized Results
A critical SDTM programming principle is the distinction between the original result and the standardized result.
For example, a source system might store:
If the project standardizes the unit and representation, the standardized variables may contain the converted result.
Events Domains
Events describe occurrences such as adverse events, medical history, or study disposition.
The AE domain is one of the most familiar examples.
| Variable | Example | Concept |
|---|---|---|
| AETERM | Headache | Reported term |
| AEDECOD | Headache | Coded dictionary term |
| AESTDTC | 2026-01-15 | Start date/time |
| AEENDTC | 2026-01-17 | End date/time |
| AESEV | MILD | Severity |
| AESER | Y | Seriousness |
Notice the distinction between severity and seriousness. They are different concepts and should not be treated as synonyms.
Interventions Domains
Interventions describe treatments, medications, procedures, or other interventions.
Common domains include:
- CM: concomitant medications
- EX: exposure
- EC: exposure as collected, where applicable to the implementation
For medication data, programmers frequently need to standardize drug names, doses, units, routes, frequencies, and start/end timing.
Timing Variables
Timing is one of the areas where SDTM programming becomes especially important. A clinical observation is rarely meaningful without knowing when it occurred.
Common timing variables include:
| Variable | Meaning |
|---|---|
| --DTC | ISO 8601 date/time character representation |
| --STDTC | Start date/time for domains where this structure applies |
| --ENDTC | End date/time where applicable |
| --DY | Study day relative to the defined reference point |
| --DUR | Duration where applicable |
| VISIT | Visit description where applicable |
ISO 8601 Dates
SDTM date/time variables commonly use ISO 8601 representations.
Examples include:
| Value | Interpretation |
|---|---|
| 2026-03-15 | Known date |
| 2026-03 | Known year and month, day unknown |
| 2026 | Known year only |
| 2026-03-15T14:30 | Date and time |
Study Day
Study day is often derived relative to a defined reference date, commonly the date of first exposure.
For a post-reference observation:
For observations occurring before the reference date, the applicable derivation convention produces negative study days.
DY.
Controlled Terminology
Controlled terminology is another foundational SDTM concept.
Instead of allowing every study to use its own spelling for standardized categorical concepts, CDISC controlled terminology provides standardized codelists and values for applicable variables.
Examples of concepts that may use controlled terminology include:
- Severity
- Yes/no indicators
- Routes of administration
- Units
- Outcome or status categories
Controlled terminology is not a license to change source meaning.
Source-to-SDTM Mapping
Most SDTM programming begins with a mapping exercise.
Worked Mapping Example: Vital Signs
Suppose a source system contains:
| Source Variable | Example |
|---|---|
| SUBJECT | 101-001 |
| SYSBP | 128 |
| SYSBP_UNIT | mmHg |
| COLLECTED_DTM | 2026-03-15T09:30 |
A conceptual SDTM mapping might look like:
| Source | SDTM VS |
|---|---|
| Study identifier | STUDYID |
| Subject identifier | USUBJID |
| SYSBP | VSORRES |
| mmHg | VSORRESU |
| Collection datetime | VSDTC |
| Derived test code | VSTESTCD = SYSBP |
| Derived test name | VSTEST = Systolic Blood Pressure |
The important programming point is that SYSBP in
the source database does not automatically determine the complete SDTM record.
The programmer must construct the standardized observation around it.
SAS Example: Creating a VS Domain
The following is a conceptual example rather than a sponsor-specific production program.
data vs;
set source_vitals;
length domain $2
vstestcd $8
vstest $40
vsorres $40
vsorresu $20
vsdtc $20;
domain = "VS";
usubjid = catx("-", studyid, subject);
vstestcd = "SYSBP";
vstest = "Systolic Blood Pressure";
vsorres = strip(put(sysbp, best.));
vsorresu = "mmHg";
if not missing(collected_dtm) then
vsdtc = put(collected_dtm, e8601dt.);
keep studyid domain usubjid
vstestcd vstest
vsorres vsorresu
vsdtc;
run;
Finding Results: ORRES, STRESC, and STRESN
For Findings domains, programmers frequently need to understand three related result concepts:
--ORRES— original result as collected or received.--STRESC— standardized character result.--STRESN— standardized numeric result where appropriate.
For a numeric laboratory result:
A typical standardized representation could retain both the character form and numeric form so that the result is useful to both reviewers and downstream programs.
SAS Example: Laboratory Standardization
data lb;
set source_lab;
length domain $2
lbtestcd $8
lbtest $80
lborres lbstresc $40
lborresu lbstresu $20;
domain = "LB";
usubjid = catx("-", studyid, subject);
lbtestcd = upcase(test_code);
lbtest = strip(test_name);
lborres = strip(result_char);
lborresu = strip(result_unit);
/* Example: numeric standardization */
if not missing(result_num) then do;
lbstresn = result_num;
lbstresc = strip(put(result_num, best.-l));
end;
lbstresu = lborresu;
keep studyid domain usubjid
lbtestcd lbtest
lborres lborresu
lbstresc lbstresn lbstresu;
run;
Events: Coding and Dictionary Variables
For event data, source terms often require dictionary coding.
For example, a source term might be:
The coded dictionary term could be represented in
AEDECOD, while the original reported term remains
in AETERM.
Domains Are Not Just Tables With Short Names
A frequent beginner mistake is to think of SDTM as a naming exercise:
"Take the source table, rename the columns, and call it AE."
That approach fails because SDTM is a semantic model.
The programmer must understand:
- What each source variable means
- Which observations belong together
- Which domain represents the observation
- Which SDTM variable represents each concept
- Which values require controlled terminology
- Which values can legitimately be derived
- Which source information should remain unchanged
Special-Purpose Domains
Not every important SDTM dataset follows the same observation-class structure.
Special-purpose domains include datasets such as:
- DM: Demographics
- SV: Subject Visits
- SE: Subject Elements, where applicable
These datasets are important because they provide subject-level or trial-structure information that other domains rely upon.
The DM Domain
DM is particularly important because it provides one record per subject and contains key subject-level identifiers and demographic information.
| Variable | Example | Purpose |
|---|---|---|
| STUDYID | ABC123 | Study identifier |
| DOMAIN | DM | Domain identifier |
| USUBJID | ABC123-001-001 | Unique subject identifier |
| SUBJID | 001-001 | Subject identifier |
| RFSTDTC | 2026-01-15 | Reference start date/time |
| SEX | F | Sex |
| AGE | 57 | Age |
Because DM is special-purpose, do not force the Findings/Events/Interventions variable pattern onto it.
Supplemental Qualifiers: SUPPQUAL
Sometimes a collected concept does not have an appropriate standard variable in the parent domain.
Supplemental Qualifiers provide a structured mechanism for representing additional non-standard variables associated with a parent domain, subject to the applicable SDTM implementation rules.
The basic structure includes concepts such as:
| Variable | Purpose |
|---|---|
| QNAM | Name of the supplemental qualifier |
| QLABEL | Label describing the qualifier |
| QVAL | Value of the qualifier |
| IDVAR | Identifies the parent-domain variable used to link the record |
| IDVARVAL | Value of that identifier variable |
Example of SUPPQUAL Logic
Suppose an AE-related concept was collected but has no appropriate standard variable for the specific implementation.
data suppae;
set ae_extra;
rdomain = "AE";
idvar = "AESEQ";
idvarval = strip(put(aeseq, best.));
qnam = "EXTRA01";
qlabel = "Example Additional Qualifier";
qval = strip(extra_value);
keep studyid rdomain usubjid idvar idvarval
qnam qlabel qval;
run;
The exact variable set and naming convention must follow the applicable SDTM implementation guidance and project standards.
Relationships Between Records: RELREC
Clinical observations sometimes have meaningful relationships that cannot be fully represented by simply placing them in separate domains.
For example, an adverse event may be related to a concomitant medication.
The RELREC structure can be used to describe relationships between records when the applicable implementation requires it.
Traceability
Traceability means that a reviewer should be able to understand where an SDTM value came from and how it was produced.
A simple conceptual chain is:
Traceability becomes especially important for derived values. If a variable is derived, the derivation should be reproducible and documented.
Define-XML
Define-XML is metadata describing the submitted datasets and their variables.
For a programmer, it helps answer questions such as:
- What is this dataset?
- What does this variable mean?
- What is its type and length?
- What controlled terminology applies?
- Where did the value originate?
- Was the value derived?
- What method was used?
- How is the dataset related to other metadata?
Domain Selection: A Practical Decision Process
When you receive an unfamiliar source dataset, use a repeatable decision process rather than relying on memory.
Common SDTM Domains Programmers Should Know
| Domain | What It Represents | Class / Type |
|---|---|---|
| DM | Demographics | Special-purpose |
| AE | Adverse events | Events |
| CM | Concomitant medications | Interventions |
| EX | Study treatment exposure | Interventions |
| LB | Laboratory results | Findings |
| VS | Vital signs | Findings |
| EG | ECG results | Findings |
| MH | Medical history | Events |
| DS | Disposition events | Events |
| SV | Subject visits | Special-purpose |
| QS | Questionnaire data | Findings |
| PE | Physical examination | Findings |
| SC | Subject characteristics | Special-purpose |
Example: AE Programming Workflow
Imagine a source AE dataset containing:
| Source | Example |
|---|---|
| SUBJECT | 001-001 |
| TERM | Headache |
| START_DATE | 2026-02-03 |
| END_DATE | 2026-02-05 |
| SEVERITY | Mild |
| SERIOUS | No |
The programmer should determine the appropriate mappings rather than simply copying the source column names.
data ae;
set source_ae;
length domain $2
aeterm $200
aedecod $200
aestdtc aeendtc $20
aesev $20
aeser $1;
domain = "AE";
usubjid = catx("-", studyid, subject);
aeterm = strip(term);
/* Dictionary coding would normally be supplied by the
validated coding process rather than hard-coded here. */
aedecod = strip(dictionary_term);
if not missing(start_date) then
aestdtc = put(start_date, yymmdd10.);
if not missing(end_date) then
aeendtc = put(end_date, yymmdd10.);
aesev = upcase(strip(severity));
if upcase(strip(serious)) = "YES" then
aeser = "Y";
else if upcase(strip(serious)) = "NO" then
aeser = "N";
keep studyid domain usubjid
aeterm aedecod
aestdtc aeendtc
aesev aeser;
run;
Generating Sequence Variables
Sequence variables should be generated after the records to be included in the domain have been defined and sorted appropriately.
proc sort data=ae;
by usubjid aestdtc aeterm;
run;
data ae;
set ae;
by usubjid;
if first.usubjid then aeseq = 0;
aeseq + 1;
run;
Using SQL for Mapping and QC
SQL can also be useful for source-to-SDTM checks and simple transformations.
select
studyid,
usubjid,
count(*) as n_records
from ae
group by
studyid,
usubjid
having missing(usubjid);
The exact SQL dialect and missing-value syntax depend on the environment. The important point is that SDTM QC can be expressed as explicit data-quality questions.
SDTM Validation
Validation is not a final step performed after programming is "finished." It should be built into the workflow.
| Validation Area | Example Question |
|---|---|
| Structure | Are the expected datasets present? |
| Variables | Are required variables present and correctly named? |
| Types | Are character/numeric types correct? |
| Lengths | Are variable lengths appropriate? |
| Values | Do values conform to the applicable terminology? |
| Dates | Are dates valid and represented correctly? |
| Identifiers | Are USUBJID and sequence values consistent? |
| Relationships | Do linked records actually exist? |
| Traceability | Can important values be traced back to source? |
| Clinical review | Do the records make clinical sense? |
Programmatic QC Checklist
Example QC Checks in SAS
proc sort data=ae out=ae_qc;
by usubjid aeseq;
run;
data duplicate_ae;
set ae_qc;
by usubjid aeseq;
if not (first.aeseq and last.aeseq);
run;
proc print data=duplicate_ae;
run;
This is only one example. Production QC should include structural, semantic, clinical, and metadata checks appropriate to the domain.
Common SDTM Programming Mistakes
- Treating SDTM as simple renaming. The semantic meaning of source data must be understood before mapping.
- Inventing source information. A programmer should not manufacture clinical facts merely to populate a standard variable.
- Overwriting original values. Original collected meaning should be preserved where the standard provides separate original and standardized variables.
- Using the wrong observation class. Classifying a finding as an event or intervention can lead to an incorrect domain structure.
- Using controlled terminology without semantic review. Similar words do not necessarily mean equivalent concepts.
- Ignoring partial dates. Missing precision should not be silently converted into false precision.
- Generating sequences from accidental source order. Sequence logic should be deterministic and documented.
- Putting everything unusual into SUPPQUAL. First determine whether an existing standard variable or domain applies.
- Failing to validate relationships. A relationship record pointing to a nonexistent parent record is a serious data-quality problem.
- Ignoring metadata. The dataset is only part of the submission package; metadata and traceability matter too.
Domain Versus Dataset
The words domain and dataset are often used interchangeably in casual programming conversations, but they are conceptually different.
A domain is the standardized subject-matter structure. A dataset is the actual file containing records that implement that structure.
Custom Domains
Not every collected concept necessarily has an existing standard domain that fits perfectly.
When a custom domain is needed, the programmer should not simply invent a two-letter abbreviation and proceed.
The need for a custom domain should be evaluated against the applicable SDTM and SDTMIG guidance, sponsor standards, regulatory expectations, and the clinical concept being represented.
A custom domain should still follow the relevant SDTM design principles, including consistent identifiers, topics, qualifiers, timing, terminology, and metadata.
How Source Data Become SDTM
Worked End-to-End Example
Consider a subject with a blood-pressure measurement collected during a study visit.
| Source Concept | Value |
|---|---|
| Study | ABC123 |
| Subject | 001-001 |
| Visit | Week 4 |
| Test | Systolic Blood Pressure |
| Result | 128 |
| Unit | mmHg |
| Date/time | 2026-02-12T09:10 |
The programmer reasons:
- This is a measurement, so it belongs to the Findings class.
- Blood pressure is represented in VS.
- The standardized test code is SYSBP.
- The original result is retained.
- The unit is represented appropriately.
- The collection datetime becomes VSDTC.
- Subject and study identifiers are populated.
- The resulting record is validated against source data.
The resulting conceptual record is:
| SDTM Variable | Value |
|---|---|
| STUDYID | ABC123 |
| DOMAIN | VS |
| USUBJID | ABC123-001-001 |
| VSTESTCD | SYSBP |
| VSTEST | Systolic Blood Pressure |
| VSORRES | 128 |
| VSORRESU | mmHg |
| VSDTC | 2026-02-12T09:10 |
What Makes a Good SDTM Programmer?
A strong SDTM programmer is not simply someone who knows SAS syntax.
The most important skills are:
- Clinical understanding: knowing what the source data represent.
- Standards knowledge: understanding SDTM structures and terminology.
- Programming discipline: writing reproducible transformations.
- Traceability: being able to explain where values came from.
- QC discipline: independently testing important assumptions.
- Documentation: recording derivations and decisions clearly.
SAS is the implementation language. SDTM knowledge is the conceptual skill.
How to Read an SDTM Specification
When you receive a domain specification, do not immediately start coding. Read it systematically.
SDTM Programming Specification Template
| Specification Item | Example |
|---|---|
| Domain | VS |
| Source | Clinical vital-signs form |
| Population | All subjects with collected vital-sign measurements |
| Key identifier | USUBJID |
| Topic | VSTESTCD / VSTEST |
| Result | VSORRES / VSSTRES* |
| Timing | VSDTC and applicable visit variables |
| Terminology | Applicable CDISC controlled terminology |
| Derivations | Documented and reproducible |
| QC | Independent validation of records and attributes |
Clinical Review of SDTM
Technical validation cannot determine whether every clinical mapping makes sense.
Clinical review may identify issues such as:
- A medication mapped to the wrong intervention concept
- An adverse event coded to an unexpected term
- A laboratory test assigned the wrong unit
- A visit date inconsistent with the clinical record
- A source value interpreted differently from its intended meaning
Knowledge Check
Question 1: Which observation class most naturally contains a laboratory result?
Answer: Findings.
Question 2: Why should the original result be retained when the standard provides a standardized result variable?
Answer: To preserve the collected/source representation and maintain semantic meaning and traceability while providing a standardized representation for downstream use.
Question 3: Should a programmer invent a date when only the month and year were collected?
Answer: No. Missing precision should be handled according to the applicable SDTM and project conventions rather than silently manufacturing information.
Question 4: Is SUPPQUAL the first choice whenever a source variable has no obvious one-to-one SDTM mapping?
Answer: No. First determine whether an existing standard variable, domain, or applicable implementation structure already represents the concept.
A Practical SDTM Programmer Checklist
The Most Important SDTM Concept
The most important idea for a new clinical programmer is this:
A good SDTM program therefore has three properties:
- Standardized: it follows the applicable SDTM model and implementation guidance.
- Traceable: important values can be explained back to source.
- Reproducible: another programmer can understand and reproduce the logic.
Summary
SDTM provides a standardized framework for organizing clinical study data. For programmers, the essential skill is learning to translate study-specific clinical observations into that framework without losing their meaning.
The core concepts to remember are:
- Observation classes determine the broad structure of clinical observations.
- Domains organize related observations into standardized datasets.
- Identifiers establish study, subject, and record context.
- Topics describe what is being observed.
- Qualifiers add clinically meaningful context.
- Timing variables describe when observations occurred.
- Original and standardized results may coexist.
- Controlled terminology standardizes applicable coded values.
- SUPPQUAL and RELREC address specific additional-standardization needs.
- Traceability and Define-XML provide important metadata context.
- Validation must cover both technical structure and clinical meaning.
References
CDISC. Study Data Tabulation Model (SDTM).
Clinical Data Interchange Standards Consortium.
CDISC. SDTM Implementation Guide.
Clinical Data Interchange Standards Consortium.
CDISC. SDTM v2.0.
Clinical Data Interchange Standards Consortium, published 2021.
CDISC. SDTMIG v3.4.
Clinical Data Interchange Standards Consortium, published 2021.
CDISC. Controlled Terminology.
Clinical Data Interchange Standards Consortium.
CDISC. Define-XML.
Clinical Data Interchange Standards Consortium.