<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2315822260943695633</id><updated>2026-05-06T10:03:54.813-04:00</updated><category term="Proc SQL"/><category term="Macro"/><category term="FDA"/><category term="ODS escapechar"/><category term="SDTM"/><category term="call symput"/><category term="input"/><category term="Do loops"/><category term="Proc Datasets"/><category term="Proc Export"/><category term="Proc Import"/><category term="Proc Sort"/><category term="SAS Programming Tips"/><category term="SASHELP views"/><category term="SDTM Validation"/><category term="missover"/><category term=".CSV"/><category term=".XPT to SAS"/><category term="ADaM"/><category term="Arrays"/><category term="CDISC"/><category term="CDISC Audio Seminars"/><category term="CRF&#39;s"/><category term="Custom Domains"/><category term="DLM"/><category term="DM Commands"/><category term="DSD"/><category term="Data _null_"/><category term="Data step"/><category term="Datastep"/><category term="Define.XML Define.PDF SAS Metadata Case Report Tabulations(CRT&#39;s) FDA"/><category term="Display Manager commands"/><category term="Do-loop"/><category term="Emailing with SAS"/><category term="Excel files"/><category term="Firstobs="/><category term="Infile"/><category term="Label"/><category term="MLOGIC"/><category term="MPRINT"/><category term="Macros"/><category term="Missing Values"/><category term="NOBS"/><category term="NODUP"/><category term="NODUPKEY"/><category term="New SAS Functions"/><category term="ODM SDTM CDISC ADaM ISO HL7"/><category term="Page X of Y"/><category term="Proc CDISC"/><category term="Proc compare"/><category term="Propcase Function in SAS"/><category term="RFSTDTC"/><category term="Replace"/><category term="Resolving Macro Variables"/><category term="SAS 9.2"/><category term="SAS Arrays"/><category term="SAS Graph"/><category term="SAS Interview Questions"/><category term="SAS Procedures"/><category term="SYMBOLGEN"/><category term="Sending Email using SAS"/><category term="VCOLUMN"/><category term="VTABLE"/><category term="Validvarname=Upcase"/><category term="call symputx"/><category term="compress"/><category term="delimiters"/><category term="findc"/><category term="intck"/><category term="missing"/><category term="protocol"/><category term="put"/><category term="substr"/><category term="wlatin1"/><category term="$as extension"/><category term="$upcasew. format"/><category term="%eval and %sysevalf macro functions"/><category term="%global"/><category term="%include"/><category term="%local"/><category term="%sysfunc"/><category term="--DY"/><category term="--ENDY"/><category term="--OBJ"/><category term="--OCCUR"/><category term="--PRESP"/><category term="--STDY"/><category term=".A"/><category term=".CSV files"/><category term=".Z"/><category term=".xpt creation"/><category term="1.3 and 1.7"/><category term="20 SAS Macros Tips in 30 Minutes"/><category term="3.1.2"/><category term="3.1.3"/><category term="3.2. 3.3 and 3.4"/><category term="? or ?? format Modifiers"/><category term="ADaM Datasets VS SDTM Datasets"/><category term="ALT"/><category term="ALTER TABLE"/><category term="ANY"/><category term="ANYDTDTMw format"/><category term="ASCII files"/><category term="ASCIIANY"/><category term="Accurately Calculating Age with Only One Line of Code"/><category term="Actual Number of Subjects"/><category term="Adaptive Design"/><category term="Adding extra columns or Variables in the existing table with PROC SQL"/><category term="Advanced SAS programming Techniques"/><category term="Advantages"/><category term="Annotated CRF&#39;s"/><category term="Annotation"/><category term="Application Data"/><category term="Arrays to detect the missing values. Definition of Missing Values"/><category term="Auto Save SAS Code"/><category term="Automate QC Checks"/><category term="Automate data processing"/><category term="Automation"/><category term="Axis control"/><category term="Bar charts"/><category term="Base SAS Certification Assignments"/><category term="Base SAS Certification Summary Functions"/><category term="Base SAS Interview"/><category term="Base SAS Tips"/><category term="Behavioural type Interview"/><category term="Best Practices for adding Columns"/><category term="Better programming practice"/><category term="Blackjack"/><category term="Blinded study"/><category term="CAT"/><category term="CATS"/><category term="CATT"/><category term="CATX"/><category term="CDISC SDTM/ADaM Pilot Project"/><category term="CDISC Standards"/><category term="CMISS()"/><category term="COMMA10."/><category term="COUNT()"/><category term="CRO&#39;s"/><category term="CTRL"/><category term="Calculating group totals and the counts within each group"/><category term="Call Execute"/><category term="Carriage Returns"/><category term="Case Report Tabulations"/><category term="Changing Careers to Become a SAS Programmer in the Biotech"/><category term="Character Encoding"/><category term="Charcter to numeric conversion"/><category term="Clinical Data Management"/><category term="Clinical Event"/><category term="Clinical SAS Interview"/><category term="Clinical SAS Programming Interview Questions and Answers"/><category term="Clinical Trial Terminology"/><category term="Clinical Trials"/><category term="Clinplus Project"/><category term="Coalsece"/><category term="Code Review"/><category term="Code readability"/><category term="Combining/ Merging data in SAS/ SQL"/><category term="Comments Tab in Define.xml"/><category term="Compare 2 approaches"/><category term="Comparing EX and EC domains"/><category term="Comparing SAS steps and Proc SQL"/><category term="Complaince Checks"/><category term="Compltetypes"/><category term="Concatenation Functions"/><category term="Controlling the Graph Axis"/><category term="Convert SAS to SPSS"/><category term="Convert SDTM data to ADaM data"/><category term="Convert a character variable - numeric variable with PROC SQL"/><category term="Creating SAS Tranport files of datasets"/><category term="Creating macro variables"/><category term="Creating missing Values"/><category term="Cynthia Johnson"/><category term="DATDIF"/><category term="DBMS"/><category term="DD-MM-YYYY"/><category term="DDE"/><category term="DEXPORT"/><category term="DIMPORT"/><category term="Data Listings"/><category term="Data Tabulations"/><category term="Datalines"/><category term="Dataset Structure Documentation in Define.xml"/><category term="Dataset Structure and Keys Column in Define.xml"/><category term="Date/Time of First Study Treatment"/><category term="Datetime functions"/><category term="David Franklin&#39;s SAS Tips"/><category term="David Ghan"/><category term="Debugging"/><category term="Debugging SAS Code"/><category term="Define"/><category term="Define.XML/PDF"/><category term="Define.xml"/><category term="Define.xml Review Checklist"/><category term="Delete observations"/><category term="Deleting Formats and informats"/><category term="Derive Study Start Date"/><category term="Dictionary Tables"/><category term="Dictionary.Tables"/><category term="Dictionary.colums"/><category term="Dinctionary Tables"/><category term="Distinct"/><category term="Do Until"/><category term="Do over Zero"/><category term="Do we need to create ADaM dataset for each SDTM dataset?"/><category term="Do you want to know if your datasets is sorted or not"/><category term="Double Blind Study"/><category term="Double Programming"/><category term="Dubugging"/><category term="Dummy Dataset"/><category term="Dynamic Data Exchange"/><category term="Dynamic Macro"/><category term="EBCDICANY"/><category term="ENCODING=Dataset Option"/><category term="ENCODING=option"/><category term="EPOCH Assignment for Pre-Consent Data"/><category term="ERROR 29-185: Width Specified for format ----  is invalid; Invalid Width; ERROR 29-185;"/><category term="ERROR/WARNING/UNINITIALIZED messages"/><category term="ERROR: Some character data was lost during transcoding in the dataset"/><category term="EX and EC (Exposure as Collected) Domains"/><category term="EX vs EC domains"/><category term="EXECFILENAME"/><category term="EXECFILEPATH"/><category term="EXIST"/><category term="Efficacy Datasets"/><category term="Efficiency Tips"/><category term="Efficient Directory Management in SAS: A Custom Macro"/><category term="Electronic Data Capture( EDC)"/><category term="Enhanced Editor"/><category term="Equivalent of NODUPKEY in PROC SQL"/><category term="Everything You Ever Wanted to Know"/><category term="Expandtabs"/><category term="Export unsuccessful"/><category term="FAOBJ"/><category term="FDA vs PMDA Submissions"/><category term="February 29"/><category term="Filename"/><category term="Finding Unique EPOCH values from SDTM datasets in entire library."/><category term="Findings About"/><category term="Floor"/><category term="Format Details"/><category term="Format that Doesn&#39;t Remove Leading Zero"/><category term="Format that inserts a slash"/><category term="GET SAS"/><category term="Get name/Location of file"/><category term="Getting Data into SAS"/><category term="Global"/><category term="Guidelines for Coding of SAS® Programs"/><category term="HANDLING SPECIAL EMBEDDED CHARACTERS"/><category term="HASH and Double HASH"/><category term="HL7"/><category term="Helpful documents for Proc SQL:"/><category term="How to extract year information from three formats of dates in a dataset?"/><category term="How to know with what variables the dataset got sorted without looking at the SAS code"/><category term="How to scan more than 20 records to determine variable attributes in EFI"/><category term="IFC"/><category term="IFN"/><category term="IMPLEMENTATION OF CDISC STANDARDS"/><category term="IND application"/><category term="INNER JOIN"/><category term="IRB"/><category term="ISE benefit/risk profile"/><category term="ISS"/><category term="Identify blank columns"/><category term="Implementation"/><category term="Import strange datetime format"/><category term="Importance of Warnings and Notes messages from SAS log"/><category term="Importing DBF files to SAS Datasets"/><category term="Importing excel files into SAS"/><category term="Imputed Dates"/><category term="Integrated Summary of Efficacy"/><category term="Integrated Summary of Safety"/><category term="Interleaving"/><category term="Introduction to SAS Informats and Formats"/><category term="JANUS"/><category term="JOB prospects for Clinical trial coordinators and SAS Programmers in INDIA"/><category term="Japanese Text"/><category term="KD"/><category term="KILL"/><category term="Kent Reeve"/><category term="Key Principles for Analysis Datasets Creation"/><category term="Keyboard Shortcuts"/><category term="LAG Function"/><category term="LB Unit Conversion in SDTM"/><category term="LB domain expansion"/><category term="LEFT"/><category term="LLT"/><category term="Last Fileref"/><category term="Lead Function"/><category term="Learn SAS in 6 weeks"/><category term="Legends"/><category term="Letter"/><category term="Line Feeds"/><category term="Line Plot"/><category term="Lost SAS Code"/><category term="MACROGEN and MFILE"/><category term="MERGE"/><category term="MFILE"/><category term="MINDELIMITER"/><category term="MINOPERATOR"/><category term="MISSING()"/><category term="MM-YYYY"/><category term="MMDDYY+"/><category term="MMDDYYB"/><category term="MMDDYYC"/><category term="MMDDYYD"/><category term="MMDDYYN"/><category term="MMDDYYP"/><category term="MMDDYYS"/><category term="MODIFY statement"/><category term="Macro Calls"/><category term="Macro Debugging Options"/><category term="Macro IN operator"/><category term="Macro creation"/><category term="Macro for Sorting the Datasets"/><category term="Macro for merging Datsets with same prefix name"/><category term="Macro to replace missing values"/><category term="Manipulating the Data"/><category term="Many to Many Merge"/><category term="Many-to-Many Merge without  Proc SQl"/><category term="Mapping"/><category term="Mastering Directory Management in SAS: A Guide to Copying Directories"/><category term="MedDRA Coding"/><category term="Memtype"/><category term="Merge macro"/><category term="Merge multiple datasets"/><category term="Merge statements"/><category term="Merging Data Seven Different Ways"/><category term="Missing Function"/><category term="Missing=0"/><category term="Multiple Graphs on One Page Using SAS/GRAPH® V9"/><category term="Multiple ampersands"/><category term="N and NMISS"/><category term="NDA"/><category term="NDA application"/><category term="NMISS()"/><category term="NODUPRECS"/><category term="NOTE: The SAS System stopped processing this step because of errors."/><category term="NOUNIQUEKEYS"/><category term="NVAR"/><category term="Name"/><category term="New SAS 9 Format"/><category term="Nolist"/><category term="Non Printable Hex characters"/><category term="Non Printable characters in SAS datasets. Remove or Drop non printable characters"/><category term="Non-Standard SDTM domains"/><category term="Not sure if the variable is character or numeric?"/><category term="Number of Observations"/><category term="Numeric to character conversion"/><category term="Numeric to character or character to numeric using Proc SQL"/><category term="ODM"/><category term="ODS  tip  report writing  cell width"/><category term="ODS HTML RTF LISTING Output Delivery System"/><category term="Official List"/><category term="One liner"/><category term="Open"/><category term="Open CDISC"/><category term="Open Label study"/><category term="Ophthalmic Examinations Domain"/><category term="Opposite to LAG function"/><category term="Options"/><category term="Order of Missing Values"/><category term="Out="/><category term="Overview"/><category term="P-value"/><category term="P21 Enterprise Issues"/><category term="PROC IMPORT with a Twist"/><category term="PROC SQl ( Left join"/><category term="PRXMATCH"/><category term="PT"/><category term="PUTLOG"/><category term="PUTNAMES=NO; %ds2CSV; ODS CSV; CSV tagset; table_headers=’NO’; Column Headers;"/><category term="Path"/><category term="Pathname"/><category term="Patient Profiles"/><category term="Pattern Matching"/><category term="Perl Regular Expressions"/><category term="Permanant and Temporary Formats"/><category term="Phase 2 and Phase3"/><category term="Phase 4"/><category term="Phase1"/><category term="Phase1/2"/><category term="Phase1b"/><category term="Picture Format"/><category term="Pinnacle 21"/><category term="Poger"/><category term="Power Up Your Data Cleaning with the SAS COMPRESS Function"/><category term="Prefix"/><category term="Preloadfmt option"/><category term="Problems and Soutions"/><category term="Proc Catalog"/><category term="Proc Copy"/><category term="Proc Freq"/><category term="Proc GCHART"/><category term="Proc Gplot"/><category term="Proc Lifetest: Survival Analysis Using SAS"/><category term="Proc Means"/><category term="Proc Printto"/><category term="Proc Report"/><category term="Proc SQ"/><category term="Proc SQL GROUP BY clause"/><category term="Proc SQL Tips"/><category term="Proc STDIZE"/><category term="Proc Surveyselect"/><category term="Proc Transpose"/><category term="QC"/><category term="QUIT"/><category term="QuoteLenMax"/><category term="RANUNI"/><category term="RELREC"/><category term="REPONLY"/><category term="RFXSTDTC"/><category term="RUN"/><category term="Random Number"/><category term="Random records"/><category term="Random sampling"/><category term="Reading Data into SAS"/><category term="Reference Start Date"/><category term="Remove"/><category term="Remove Characters form string"/><category term="Resource Tips"/><category term="Retain"/><category term="Retain Statement in SAS"/><category term="Retaining Values without Lag Functions"/><category term="Right Join and Full Joins) and SAS GRAPH and Output deliver System (ODS)"/><category term="Routing the Output"/><category term="SAS"/><category term="SAS 9.3 and later versions"/><category term="SAS Array"/><category term="SAS Datasteps"/><category term="SAS Date"/><category term="SAS Documentation"/><category term="SAS Exercises"/><category term="SAS Import and Export"/><category term="SAS Infile Options"/><category term="SAS Instructor Tips 1 and 2"/><category term="SAS Interview Questions/Answers:Clinical trials"/><category term="SAS Interview Skills and Process"/><category term="SAS Missing functions"/><category term="SAS ODS LISTING CLOSE"/><category term="SAS OnlineTutor®: Advanced SAS®"/><category term="SAS Proficiency Test"/><category term="SAS Programmer"/><category term="SAS Programmer responsibities"/><category term="SAS Programming Errors"/><category term="SAS Programming in Pharmaceutical Industry"/><category term="SAS Programs"/><category term="SAS Quiz"/><category term="SAS Tip 1: Use Less code"/><category term="SAS Tips Archive"/><category term="SAS Tips and Tricks"/><category term="SAS Toolbar Settings"/><category term="SAS Tutorials"/><category term="SAS Unix"/><category term="SAS analyst"/><category term="SAS date 17750"/><category term="SAS forums/groups"/><category term="SAS free study tutorials"/><category term="SAS in Clinical Trials"/><category term="SAS in Life Sciences"/><category term="SAS sample Projects"/><category term="SAS sample programs"/><category term="SAS software"/><category term="SAS to XPT"/><category term="SAS video Tutorials"/><category term="SAS ® PROGRAM EFFICIENCY FOR BEGINNERS"/><category term="SAShelp.Vcolumn"/><category term="SAShelp.Vtable"/><category term="SAS® Programming Guidelines"/><category term="SCAN Function in SAS"/><category term="SDTM Compliance Checks"/><category term="SDTM IG 3.1.1"/><category term="SDTM Package"/><category term="SDTM Programming interview."/><category term="SDTM QC Checks"/><category term="SDTM V 1.2"/><category term="SDTM VALIDATION TOOLS"/><category term="SDTM Validation Checks"/><category term="SDTM Validation Checks for V3.1.1/V.3.1.2 and or V 3.1.3"/><category term="SDTM compliance"/><category term="SET"/><category term="SET statement"/><category term="SET statementm First. and Last. variables"/><category term="SHIFT"/><category term="SOC"/><category term="SPSS"/><category term="SQLOBS"/><category term="STRIP"/><category term="SUM function"/><category term="SUPPDS Domain revised assumption"/><category term="Safety datasets examples"/><category term="Sample Base SAS Certification Questions"/><category term="Sampling Datasets"/><category term="Save the log file"/><category term="Saving the Log and Output files"/><category term="Search a character expression for a string"/><category term="Self Teach SAS Tutorials"/><category term="Sending the Log and Output"/><category term="Separating Unique and Duplicate Observations Using"/><category term="Set and Merge Statements"/><category term="Shuffling"/><category term="Single Blind study"/><category term="Skin Response Domain"/><category term="Solitaire"/><category term="Sort multiple SAS datasets using single Proc sort and CALL Execute"/><category term="Sparse Option"/><category term="Special Missing Values"/><category term="Special missing characaters"/><category term="Statistical Analaysis Plan (SAP)"/><category term="Statistical Programming"/><category term="Strip characters"/><category term="Study DAY"/><category term="Study Day calculation"/><category term="Study design"/><category term="Subject Reference Start Date."/><category term="Subscript"/><category term="Superscript"/><category term="TRIM"/><category term="TS Domain"/><category term="TS.SSTDTC"/><category term="TSPARMCD=ACTSUB"/><category term="TSPARMCD=ADAPT"/><category term="TSPARMCD=SSTDTC. Study Start Date"/><category term="Techniques"/><category term="Temporary SAS Dataset"/><category term="The MS Excel table (worksheetname) has been opened for OUTPUT"/><category term="Therapetic areas"/><category term="This engine does not support the REPLACE option"/><category term="Three SAS Programs that use Arrays"/><category term="Time"/><category term="Tips and Techniques"/><category term="Tips for Producing Comprehensive Integrated Summaries"/><category term="Transport files"/><category term="Transpose vs Arrays"/><category term="Trasposing the data using Arrays"/><category term="Treatment Emergent AE"/><category term="Trial Summary Domain"/><category term="Trscoding Error UTF-8"/><category term="Tumor domains.--STAT."/><category term="UNIQUEOUT"/><category term="UTF-8"/><category term="UTF-8 encoding"/><category term="Unblinding"/><category term="Unlease the power of Proc Datasets"/><category term="Upcase SAS variables with PROC Datasets."/><category term="Upcase all variables"/><category term="Upcase funtion"/><category term="Update"/><category term="Uppercase and lowercase shortcut key"/><category term="VEXTFILES"/><category term="VEXTFL"/><category term="VISITS TV domain vs SDTM datasets"/><category term="VT"/><category term="VTITLES"/><category term="Validation Rules"/><category term="Validation checks on SDTM data"/><category term="Validation of programs"/><category term="Variable exists in dataset or not"/><category term="Varnum"/><category term="WEBSDM"/><category term="WHERE expressions"/><category term="WHODrug Coding"/><category term="What&#39;s New in SAS 9.2"/><category term="When should I put a variable in the CLASS statement? What does the CLASS statement do?"/><category term="Where statement"/><category term="Where vs IF statements"/><category term="Whole Path"/><category term="Why SAS"/><category term="Without Lag Function"/><category term="Working With Missing Values"/><category term="Write Log and Output to a seperate file"/><category term="XPORT engine"/><category term="Xpath"/><category term="YRDIF"/><category term="YYYY"/><category term="You can do so much with Proc Datasets"/><category term="Zero Observations"/><category term="Zw.d format"/><category term="_character_"/><category term="_numerric_"/><category term="act/act"/><category term="add leading zeros to numeric variables"/><category term="annotate"/><category term="anydate"/><category term="anydtdte30."/><category term="autoexec.sas"/><category term="axis1"/><category term="cSDRG study design section"/><category term="call routines"/><category term="char_cars (i)"/><category term="character conversions"/><category term="character type"/><category term="check if numeric/character variable exists in same prefix name variables"/><category term="cmiss vs nmiss in SAS"/><category term="cntlout"/><category term="color"/><category term="compress functions etc"/><category term="copy directories from one folder to another"/><category term="correctencoding=wlatin1"/><category term="criterion"/><category term="data cleaning"/><category term="datestyle=dmy"/><category term="datestyle=mdy"/><category term="datetime"/><category term="define xml"/><category term="detect the missing values. non missing"/><category term="difference"/><category term="dim function"/><category term="displays column names as column headings instead of column labels"/><category term="dot-Z"/><category term="duplicates"/><category term="explicit step boundaries"/><category term="fileexist"/><category term="flyover"/><category term="fmtsearch option"/><category term="formatting differences"/><category term="generate the month name from a numeric value"/><category term="in SDTM Programming: A Detailed Guide with Examples"/><category term="index"/><category term="indexc"/><category term="just use Proc datasets"/><category term="keep characters"/><category term="keydef"/><category term="keys"/><category term="leading zeros."/><category term="left functions"/><category term="length of any character values cannot be more than 200 characters"/><category term="line pointer controls"/><category term="list of variables in a DATA set"/><category term="macro to list all folders present in a specified directory"/><category term="mdy"/><category term="mdyampm"/><category term="mdyampm25.2"/><category term="memlabel"/><category term="memname"/><category term="mergeNoBy=nowarn"/><category term="minor"/><category term="mmddyy10. Z8."/><category term="monname3."/><category term="monnamew. format"/><category term="month and year"/><category term="more than 262 characters long"/><category term="noQuoteLenMax"/><category term="noobs"/><category term="number of missing and non missing records of variables"/><category term="numeric variables length more than 8"/><category term="openCDISC"/><category term="openCDISC validator"/><category term="option nofmterr"/><category term="or word:INDEX/INDEXC/INDEXW Functions"/><category term="output SAS graphics in to PS file"/><category term="page number"/><category term="parsing"/><category term="pattern"/><category term="practice Base SAS questions"/><category term="preclinical"/><category term="proc cimport"/><category term="proc cport"/><category term="protocol to cSDRG tense changes"/><category term="read datetime string directly into SAS datetime format"/><category term="read next record while working on the current record"/><category term="remove characters"/><category term="repeat function"/><category term="routine reports"/><category term="rtf output"/><category term="sas LOG width of comments is not in between 1 and 200 characters"/><category term="scan"/><category term="seed"/><category term="space or &quot;-&quot; between the date"/><category term="specific character"/><category term="string functions"/><category term="study design documentation"/><category term="tod8. format"/><category term="transcoding error"/><category term="truncover"/><category term="unbalanced quotation marks"/><category term="upcase functions"/><category term="upcase macro"/><category term="using formats and format libraries"/><category term="validation"/><category term="what to use"/><category term="writing SAS log file to output file"/><category term="xml review and findings"/><category term="yymmdd8."/><title type='text'>STUDYSAS BLOG</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://studysas.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>277</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-1819660908879287709</id><published>2026-04-09T20:53:00.007-04:00</published><updated>2026-04-24T07:20:20.169-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="LB Unit Conversion in SDTM"/><title type='text'>7 Mistakes in LB Unit Conversion That Still Show Up in SDTM</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
&lt;title&gt;7 Mistakes in LB Unit Conversion That Still Show Up in SDTM | StudySAS&lt;/title&gt;
&lt;style&gt;
body {
  font-family: Georgia, &#39;Times New Roman&#39;, serif;
  font-size: 16px;
  line-height: 1.8;
  color: #2c2c2c;
  background: #ffffff;
  margin: 0;
  padding: 40px 20px 80px;
}
.wrap {
  max-width: 820px;
  margin: 0 auto;
}
.meta {
  font-family: Arial, sans-serif;
  font-size: 12.5px;
  color: #888;
  margin-bottom: 6px;
  letter-spacing: 0.03em;
}
h1 {
  font-size: 2rem;
  color: #1a1a2e;
  line-height: 1.3;
  margin: 0 0 12px 0;
}
h2 {
  font-size: 1.35rem;
  color: #1a1a2e;
  font-weight: bold;
  margin-top: 54px;
  margin-bottom: 14px;
  border-bottom: 2px solid #e0e4ef;
  padding-bottom: 6px;
}
h3 {
  font-size: 1.08rem;
  color: #1a1a2e;
  font-weight: bold;
  margin-top: 32px;
  margin-bottom: 10px;
}
p {
  margin: 0 0 18px 0;
}
pre {
  background: #f5f5f5;
  border-left: 4px solid #0066cc;
  font-family: &#39;Courier New&#39;, Courier, monospace;
  font-size: 13.5px;
  line-height: 1.65;
  padding: 16px 20px;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
  margin: 22px 0;
  border-radius: 0 4px 4px 0;
}
code {
  font-family: &#39;Courier New&#39;, Courier, monospace;
  font-size: 13.5px;
  background: #f0f0f0;
  color: #b5432a;
  padding: 2px 5px;
  border-radius: 3px;
}
pre code {
  background: none;
  color: inherit;
  padding: 0;
}
.note {
  background: #fff8e1;
  border-left: 4px solid #f9a825;
  padding: 13px 16px;
  margin: 22px 0;
  border-radius: 0 4px 4px 0;
  font-size: 15px;
}
.warn {
  background: #fff3f3;
  border-left: 4px solid #cc2222;
  padding: 13px 16px;
  margin: 22px 0;
  border-radius: 0 4px 4px 0;
  font-size: 15px;
}
.takeaway {
  background: #eef3ff;
  border-left: 4px solid #4a6cf7;
  padding: 16px 20px;
  margin: 26px 0;
  border-radius: 0 4px 4px 0;
  font-size: 16px;
  line-height: 2;
}
table {
  width: 100%;
  border-collapse: collapse;
  margin: 26px 0;
  font-size: 14.5px;
}
thead tr {
  background: #1a1a2e;
  color: #fff;
}
thead th {
  padding: 10px 13px;
  text-align: left;
  font-family: Arial, sans-serif;
  font-size: 13px;
  letter-spacing: 0.03em;
}
td {
  padding: 10px 13px;
  border-bottom: 1px solid #e0e0e0;
  vertical-align: top;
}
td code {
  font-size: 12.5px;
}
tbody tr:nth-child(even) {
  background: #f8f9fc;
}
.hl td {
  background: #fff8e1 !important;
}
hr {
  border: none;
  border-top: 1px solid #dde2ee;
  margin: 48px 0;
}
.mistake-num {
  display: inline-block;
  background: #1a1a2e;
  color: #fff;
  font-family: Arial, sans-serif;
  font-size: 11px;
  font-weight: bold;
  padding: 2px 8px;
  border-radius: 3px;
  letter-spacing: 0.06em;
  margin-right: 6px;
  vertical-align: middle;
}
.footnote {
  font-size: 13.5px;
  color: #555;
  margin-top: 44px;
  border-top: 1px solid #dde2ee;
  padding-top: 18px;
  line-height: 1.7;
}
.footnote p {
  margin-bottom: 8px;
}
.footnote a {
  color: #0066cc;
  text-decoration: none;
}
.footnote a:hover {
  text-decoration: underline;
}
.tags {
  font-family: Arial, sans-serif;
  font-size: 12.5px;
  margin-top: 36px;
  padding-top: 16px;
  border-top: 1px solid #e0e4ef;
}
.tags span {
  display: inline-block;
  background: #eef1f8;
  color: #1a1a2e;
  padding: 3px 10px;
  border-radius: 12px;
  margin: 3px 3px 3px 0;
  font-size: 12px;
}
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;wrap&quot;&gt;

&lt;p&gt;LB unit conversion is not hard to understand. The variable definitions are clear. The model is well-documented. And yet unit-related problems remain among the most common issues in SDTM submissions — not because teams do not know the rules, but because the failures are quiet. Nothing crashes. The dataset looks valid. Pinnacle 21 returns a clean report. Then a reviewer runs a simple cross-tabulation and finds creatinine flagged HIGH at a value that belongs well within the normal range — because the reference range was never converted to match the standard unit.&lt;/p&gt;

&lt;p&gt;This post is a close look at seven implementation mistakes, each with enough context and worked examples to make the failure mode visible before it reaches a submission.&lt;/p&gt;

&lt;div class=&quot;takeaway&quot;&gt;
&lt;strong&gt;LBORRES is what was collected. Verbatim. Untouched.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;LBSTRES* is the standardized representation. One unit per test.&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;LBSTNR* must follow the same unit system as LBSTRES*.&lt;/strong&gt;
&lt;/div&gt;

&lt;p&gt;That three-line rule explains most of what goes wrong. The seven mistakes below are elaborations of what happens when any part of that contract is broken.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Background: what the standard requires&lt;/h2&gt;

&lt;p&gt;SDTMIG defines the LB domain variable roles clearly. &lt;code&gt;LBORRES&lt;/code&gt; holds the result exactly as collected from the source. &lt;code&gt;LBORRESU&lt;/code&gt; holds the unit as reported by the lab. &lt;code&gt;LBSTRESC&lt;/code&gt; holds the standardized result in character form. &lt;code&gt;LBSTRESN&lt;/code&gt; holds the numeric portion of that standardized result. &lt;code&gt;LBSTRESU&lt;/code&gt; holds the standard unit — and this unit must be consistent for a given &lt;code&gt;LBTESTCD&lt;/code&gt; across the entire dataset. &lt;code&gt;LBSTNRLO&lt;/code&gt; and &lt;code&gt;LBSTNRHI&lt;/code&gt; hold the standardized reference range limits, which must be in the same unit as &lt;code&gt;LBSTRESU&lt;/code&gt;. &lt;code&gt;LBNRIND&lt;/code&gt; holds the normal/abnormal flag, and SDTMIG explicitly requires that sponsors document whether this flag is derived from original ranges or standard ranges.&lt;/p&gt;

&lt;p&gt;FDA&#39;s Study Data Technical Conformance Guide v6.1 (December 2025) adds a structural requirement on top of this: for clinical submissions, the &lt;code&gt;LB&lt;/code&gt; domain should carry SI-standardized results, and a parallel custom domain &lt;code&gt;LC&lt;/code&gt; should carry conventional-unit results. These are not alternative approaches — they are parallel datasets required in the same submission package. PMDA&#39;s guidance reinforces SI use in the standardized result fields and additionally requires that the conversion equation be documented in reviewer-facing materials when original and converted values coexist.&lt;/p&gt;

&lt;p&gt;That is the framework. Now, where it breaks.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;&lt;span class=&quot;mistake-num&quot;&gt;01&lt;/span&gt; Changing LBORRES&lt;/h2&gt;

&lt;p&gt;This is the foundational error, and it is more common than it should be. &lt;code&gt;LBORRES&lt;/code&gt; is the traceability anchor for the entire LB record. Its purpose is to preserve what the site or lab actually reported, in the exact form it was reported. The moment you alter &lt;code&gt;LBORRES&lt;/code&gt;, you have introduced a gap between the submitted dataset and the source document — and that gap is very difficult to justify under audit.&lt;/p&gt;

&lt;p&gt;The alterations I see most often are trimming trailing zeros (&lt;code&gt;1.20&lt;/code&gt; becomes &lt;code&gt;1.2&lt;/code&gt;), standardizing case (&lt;code&gt;POSITIVE&lt;/code&gt; becomes &lt;code&gt;Positive&lt;/code&gt;), removing comparison operators (&lt;code&gt;&amp;lt;0.10&lt;/code&gt; becomes &lt;code&gt;0.10&lt;/code&gt;), and normalizing text qualifiers (&lt;code&gt;Below LOQ&lt;/code&gt; becomes &lt;code&gt;BLQ&lt;/code&gt;). Each of these looks like a cleanup. None of them is permitted.&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Scenario&lt;/th&gt;&lt;th&gt;Source value&lt;/th&gt;&lt;th&gt;LBORRES — wrong&lt;/th&gt;&lt;th&gt;LBORRES — correct&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
  &lt;td&gt;Trailing zero trimmed&lt;/td&gt;
  &lt;td&gt;1.20 mg/dL&lt;/td&gt;
  &lt;td&gt;1.2&lt;/td&gt;
  &lt;td&gt;1.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Operator stripped&lt;/td&gt;
  &lt;td&gt;&amp;lt;0.10 ng/mL&lt;/td&gt;
  &lt;td&gt;0.10&lt;/td&gt;
  &lt;td&gt;&amp;lt;0.10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Text normalized&lt;/td&gt;
  &lt;td&gt;Below LOQ&lt;/td&gt;
  &lt;td&gt;BLQ&lt;/td&gt;
  &lt;td&gt;Below LOQ&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Case changed&lt;/td&gt;
  &lt;td&gt;NEGATIVE&lt;/td&gt;
  &lt;td&gt;Negative&lt;/td&gt;
  &lt;td&gt;NEGATIVE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The right place for cleanup is &lt;code&gt;LBSTRESC&lt;/code&gt;. If the sponsor has a standard for how qualitative results should be represented, that standard is applied in the standardized layer — not by modifying the original. &lt;code&gt;LBORRES&lt;/code&gt; is read-only from the moment data is collected.&lt;/p&gt;

&lt;div class=&quot;warn&quot;&gt;
&lt;strong&gt;Regulatory implication:&lt;/strong&gt; FDA expects that submitted data can be traced back to the source CRF or lab report. If LBORRES has been altered from the source value, the auditor&#39;s reconciliation path is broken. This is not a conformance warning — it is a data integrity issue.
&lt;/div&gt;

&lt;hr&gt;

&lt;h2&gt;&lt;span class=&quot;mistake-num&quot;&gt;02&lt;/span&gt; Using LBSTRESC as a cosmetic copy of LBORRES&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;LBSTRESC&lt;/code&gt; exists to do real work: converting units, standardizing result formats, or mapping to a controlled representation. When a team populates &lt;code&gt;LBSTRESC&lt;/code&gt; merely by reformatting &lt;code&gt;LBORRES&lt;/code&gt; — trimming a zero, changing &lt;code&gt;1.20&lt;/code&gt; to &lt;code&gt;1.2&lt;/code&gt;, or left-justifying a string — without any underlying standardization rule, the column exists but contributes nothing.&lt;/p&gt;

&lt;p&gt;The problem goes beyond cosmetics. A dataset where &lt;code&gt;LBSTRESC&lt;/code&gt; is a visual cleanup of &lt;code&gt;LBORRES&lt;/code&gt; looks standardized to a tool like Pinnacle 21 — all the required variables are populated. But a reviewer who pulls &lt;code&gt;LBSTRESN&lt;/code&gt; expecting a consistent, analysis-ready numeric result will find that the values are in whatever unit each site happened to report, because no actual standardization happened.&lt;/p&gt;

&lt;p&gt;This mistake is hardest to detect in single-site studies where the lab reports all results in one unit. Everything looks fine because conversion was never needed. The hidden problem surfaces when the same mapping spec is reused in a multi-site follow-on study with a different lab, and the team assumes the spec is handling standardization when it is only handling formatting.&lt;/p&gt;

&lt;div class=&quot;note&quot;&gt;
&lt;strong&gt;The test:&lt;/strong&gt; for every LB record, ask whether &lt;code&gt;LBSTRESC&lt;/code&gt; would have a different value if &lt;code&gt;LBORRES&lt;/code&gt; were in a different unit. If the answer is no — if the logic does not touch the unit at all — then &lt;code&gt;LBSTRESC&lt;/code&gt; is not doing standardization work. It is doing formatting work. That belongs in output displays, not in the SDTM submission dataset.
&lt;/div&gt;

&lt;hr&gt;

&lt;h2&gt;&lt;span class=&quot;mistake-num&quot;&gt;03&lt;/span&gt; Converting the result but not the reference range&lt;/h2&gt;

&lt;p&gt;This is the most dangerous mistake on the list because it is completely silent in conformance validation and produces flags that look correct but are not. The result moves into the standard unit. The reference range stays in the original unit. &lt;code&gt;LBNRIND&lt;/code&gt; is derived by comparing the converted result against the unconverted range. The comparison is numerically meaningless, but the output looks like a legitimate flag.&lt;/p&gt;

&lt;p&gt;Here is a concrete worked example. A study collects glucose from US sites in mg/dL and from European sites in mmol/L. The sponsor selects mmol/L as the standard unit. The JCTLM-recommended conversion factor for mg/dL to mmol/L is division by 18.018.&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Variable&lt;/th&gt;&lt;th&gt;US site record (collected in mg/dL)&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBORRES&lt;/code&gt;&lt;/td&gt;&lt;td&gt;95&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBORRESU&lt;/code&gt;&lt;/td&gt;&lt;td&gt;mg/dL&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBSTRESN&lt;/code&gt;&lt;/td&gt;&lt;td&gt;5.27 &amp;nbsp;(95 ÷ 18.018)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBSTRESU&lt;/code&gt;&lt;/td&gt;&lt;td&gt;mmol/L&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBNRLO&lt;/code&gt; as reported by lab&lt;/td&gt;&lt;td&gt;70 mg/dL&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBNRHI&lt;/code&gt; as reported by lab&lt;/td&gt;&lt;td&gt;100 mg/dL&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;hl&quot;&gt;&lt;td&gt;&lt;code&gt;LBSTNRLO&lt;/code&gt; — wrong&lt;/td&gt;&lt;td&gt;70 &amp;nbsp;(not converted)&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;hl&quot;&gt;&lt;td&gt;&lt;code&gt;LBSTNRHI&lt;/code&gt; — wrong&lt;/td&gt;&lt;td&gt;100 &amp;nbsp;(not converted)&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;hl&quot;&gt;&lt;td&gt;&lt;code&gt;LBNRIND&lt;/code&gt; derived&lt;/td&gt;&lt;td&gt;LOW &amp;nbsp;(5.27 &amp;lt; 70 in the comparison)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;A glucose of 5.27 mmol/L is squarely within the normal range (approximately 3.9–6.1 mmol/L). But the range stored in &lt;code&gt;LBSTNRLO&lt;/code&gt; is 70 and the stored unit is mmol/L — producing a comparison of 5.27 against 70, which flags the record as LOW. That flag travels into every safety table and shift table built from &lt;code&gt;LBNRIND&lt;/code&gt;. Nothing in P21 catches it.&lt;/p&gt;

&lt;p&gt;The correct derived ranges for this record are 70 ÷ 18.018 = 3.88 mmol/L and 100 ÷ 18.018 = 5.55 mmol/L. The conversion factor used for &lt;code&gt;LBSTNRLO&lt;/code&gt; and &lt;code&gt;LBSTNRHI&lt;/code&gt; must be identical to the one used for &lt;code&gt;LBSTRESN&lt;/code&gt;. Same metadata table, same factor, same rounding rule.&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Variable&lt;/th&gt;&lt;th&gt;Wrong&lt;/th&gt;&lt;th&gt;Correct&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBSTRESN&lt;/code&gt;&lt;/td&gt;&lt;td&gt;5.27&lt;/td&gt;&lt;td&gt;5.27&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBSTRESU&lt;/code&gt;&lt;/td&gt;&lt;td&gt;mmol/L&lt;/td&gt;&lt;td&gt;mmol/L&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBSTNRLO&lt;/code&gt;&lt;/td&gt;&lt;td&gt;70 &amp;nbsp;(mg/dL scale, unconverted)&lt;/td&gt;&lt;td&gt;3.88 &amp;nbsp;(mmol/L, converted)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBSTNRHI&lt;/code&gt;&lt;/td&gt;&lt;td&gt;100 &amp;nbsp;(mg/dL scale, unconverted)&lt;/td&gt;&lt;td&gt;5.55 &amp;nbsp;(mmol/L, converted)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;LBNRIND&lt;/code&gt;&lt;/td&gt;&lt;td&gt;LOW &amp;nbsp;(wrong)&lt;/td&gt;&lt;td&gt;NORMAL &amp;nbsp;(correct)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; The value &lt;code&gt;5.27&lt;/code&gt; is correct in both cases. The failure is not the numeric result — it is that the reference ranges were not converted to match the standard unit. This breaks &lt;code&gt;LBNRIND&lt;/code&gt; even when the result itself is correct.&lt;/p&gt;

&lt;p&gt;SDTMIG also requires that sponsors document in Define.xml comments whether &lt;code&gt;LBNRIND&lt;/code&gt; is based on original ranges or standardized ranges. This is explicit guidance, not optional. If you derive &lt;code&gt;LBNRIND&lt;/code&gt; from standardized ranges — which is the cleaner and more consistent approach — state that. If you derive from original lab ranges, state that too. I have reviewed submissions where 20–30% of &lt;code&gt;LBNRIND&lt;/code&gt; flags were wrong for exactly the reason shown above. Nothing in P21 caught it. A reviewer running basic summary statistics was the one who found it.&lt;/p&gt;

&lt;div class=&quot;warn&quot;&gt;
&lt;strong&gt;Check to run:&lt;/strong&gt; for every record where LBORRESU ≠ LBSTRESU, verify that LBSTNRLO and LBSTNRHI are numerically consistent with the standard unit — not the original unit. If your LBSTRESN values are in the range 3–7 but your LBSTNRHI values are in the range 70–110, you have unconverted reference ranges.
&lt;/div&gt;

&lt;hr&gt;

&lt;h2&gt;&lt;span class=&quot;mistake-num&quot;&gt;04&lt;/span&gt; Forcing qualitative results into LBSTRESN&lt;/h2&gt;

&lt;p&gt;SDTMIG is unambiguous: &lt;code&gt;LBSTRESN&lt;/code&gt; holds the numeric portion of the standardized result. When the standardized result is qualitative — POSITIVE, NEGATIVE, NORMAL, ABNORMAL, TRACE, 1+, 2+, 3+ — there is no numeric portion. &lt;code&gt;LBSTRESN&lt;/code&gt; must be null. The result goes into &lt;code&gt;LBSTRESC&lt;/code&gt; in character form and stays there.&lt;/p&gt;

&lt;p&gt;The pressure to encode ordinal results numerically in SDTM usually comes from analysts who want to sort or compute on the scale downstream. That is a legitimate need, but it belongs in ADaM — typically as a derived numeric variable in ADLB — not in the SDTM submission dataset. Populating &lt;code&gt;LBSTRESN&lt;/code&gt; with 0 for NEGATIVE and 1 for POSITIVE, or with 0.5 for TRACE and 1 for 1+ and 2 for 2+, introduces a numeric encoding that SDTMIG does not support and that Pinnacle 21 will flag as SD0086 or similar depending on the ruleset.&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;LBORRES&lt;/th&gt;&lt;th&gt;LBSTRESC&lt;/th&gt;&lt;th&gt;LBSTRESN — wrong&lt;/th&gt;&lt;th&gt;LBSTRESN — correct&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;NEGATIVE&lt;/td&gt;&lt;td&gt;NEGATIVE&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;. (null)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;TRACE&lt;/td&gt;&lt;td&gt;TRACE&lt;/td&gt;&lt;td&gt;0.5&lt;/td&gt;&lt;td&gt;. (null)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;1+&lt;/td&gt;&lt;td&gt;1+&lt;/td&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;. (null)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;2+&lt;/td&gt;&lt;td&gt;2+&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;. (null)&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;3+&lt;/td&gt;&lt;td&gt;3+&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;. (null)&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The exception is a BLQ result that includes a numeric boundary. A result reported as &lt;code&gt;&amp;lt;0.10 ng/mL&lt;/code&gt; is not purely qualitative — it has a numeric component. In this case, the boundary value belongs in &lt;code&gt;LBSTRESN&lt;/code&gt; and the operator stays in &lt;code&gt;LBSTRESC&lt;/code&gt;. That is the inequality pattern, covered in Mistake 5. The key distinction is whether the result has a numeric boundary at all. If LBORRES is the string &lt;code&gt;BLQ&lt;/code&gt; with no numeric component attached, &lt;code&gt;LBSTRESN&lt;/code&gt; is null. If LBORRES is &lt;code&gt;&amp;lt;0.10&lt;/code&gt;, the boundary 0.10 goes into &lt;code&gt;LBSTRESN&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;
/* Qualitative — LBSTRESN must be null */
LBORRES   = NEGATIVE
LBSTRESC  = NEGATIVE
LBSTRESN  = .

/* Ordinal — LBSTRESN must be null */
LBORRES   = 2+
LBSTRESC  = 2+
LBSTRESN  = .

/* BLQ with numeric boundary — inequality pattern applies */
LBORRES   = &amp;lt;0.10
LBSTRESC  = &amp;lt;0.10
LBSTRESN  = 0.10
LBSTRESU  = ng/mL
&lt;/pre&gt;

&lt;hr&gt;

&lt;h2&gt;&lt;span class=&quot;mistake-num&quot;&gt;05&lt;/span&gt; Losing the operator on inequality results&lt;/h2&gt;

&lt;p&gt;When a lab returns a result as &lt;code&gt;&amp;lt;0.10&lt;/code&gt;, that full string is the result. The operator is not decoration — it is part of the scientific meaning. A value of &lt;code&gt;&amp;lt;0.10&lt;/code&gt; says the measurement was below the limit of detection and the true value is somewhere below the numeric boundary. Stripping the operator and storing &lt;code&gt;0.10&lt;/code&gt; in &lt;code&gt;LBSTRESC&lt;/code&gt; converts an undetected result into a detected one. That changes the data.&lt;/p&gt;

&lt;p&gt;The SDTMIG model for inequality results is: the operator-qualified string goes into &lt;code&gt;LBSTRESC&lt;/code&gt;, and the numeric boundary goes into &lt;code&gt;LBSTRESN&lt;/code&gt;. When unit conversion is also needed, the conversion applies to the numeric boundary — and the converted operator string goes into &lt;code&gt;LBSTRESC&lt;/code&gt;. Both variables must reflect the post-conversion boundary, not the original.&lt;/p&gt;

&lt;p&gt;Here is a full worked example. Glucose is reported as &lt;code&gt;&amp;lt;2.0 mmol/L&lt;/code&gt; — below the limit of detection for the assay. The sponsor standard unit is mg/dL, using a conversion factor of 18.018.&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Variable&lt;/th&gt;&lt;th&gt;Wrong&lt;/th&gt;&lt;th&gt;Correct&lt;/th&gt;&lt;th&gt;Note&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;LBORRES&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;&amp;lt;2.0&lt;/td&gt;
  &lt;td&gt;&amp;lt;2.0&lt;/td&gt;
  &lt;td&gt;Verbatim — same in both cases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;LBORRESU&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;mmol/L&lt;/td&gt;
  &lt;td&gt;mmol/L&lt;/td&gt;
  &lt;td&gt;Original unit — same in both cases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;hl&quot;&gt;
  &lt;td&gt;&lt;code&gt;LBSTRESC&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;36.04&lt;/td&gt;
  &lt;td&gt;&amp;lt;36.04&lt;/td&gt;
  &lt;td&gt;Operator dropped in wrong version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;hl&quot;&gt;
  &lt;td&gt;&lt;code&gt;LBSTRESN&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;36.04&lt;/td&gt;
  &lt;td&gt;36.04&lt;/td&gt;
  &lt;td&gt;Numeric boundary — same in both&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;&lt;code&gt;LBSTRESU&lt;/code&gt;&lt;/td&gt;
  &lt;td&gt;mg/dL&lt;/td&gt;
  &lt;td&gt;mg/dL&lt;/td&gt;
  &lt;td&gt;Standard unit — same in both cases&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The wrong version stores the converted numeric value in &lt;code&gt;LBSTRESC&lt;/code&gt; without the operator. To a reviewer reading that record, glucose is 36.04 mg/dL — a detected value near the low end of the normal range, not a below-detection result. That is a materially different clinical statement.&lt;/p&gt;

&lt;p&gt;A second failure mode is when the conversion is applied to the operator string correctly, but LBSTRESC and LBSTRESN are derived from two independent computations rather than one, causing a floating-point mismatch. The safe pattern is to compute the rounded LBSTRESN first, then derive LBSTRESC from that rounded value:&lt;/p&gt;

&lt;pre&gt;
/* Compute once, derive twice — safe pattern */
lbstresn = round(2.0 * 18.018, 0.01);        /* = 36.04 */
lbstresc = cats(&#39;&amp;lt;&#39;, strip(put(lbstresn, best12.)));  /* = &quot;&amp;lt;36.04&quot; */

/* Independent computation — unsafe pattern */
/* lbstresc = cats(&#39;&amp;lt;&#39;, put(2.0 * 18.018, best12.)); */
/* lbstresn = round(2.0 * 18.018, 0.01);              */
/* These can diverge due to floating-point representation */
&lt;/pre&gt;

&lt;div class=&quot;note&quot;&gt;
&lt;strong&gt;Edge case:&lt;/strong&gt; some lab systems encode above-range results as &lt;code&gt;&amp;gt;5000&lt;/code&gt; and some as the plain value &lt;code&gt;5000&lt;/code&gt; with a separate high flag. If LBORRES contains &lt;code&gt;5000&lt;/code&gt; without an operator, LBSTRESC and LBSTRESN both take the value 5000. Do not infer an operator from an associated flag variable — only use an operator in LBSTRESC when it is present in the source result.
&lt;/div&gt;

&lt;hr&gt;

&lt;h2&gt;&lt;span class=&quot;mistake-num&quot;&gt;06&lt;/span&gt; Allowing more than one LBSTRESU per LBTESTCD&lt;/h2&gt;

&lt;p&gt;The invariant is simple: for a given &lt;code&gt;LBTESTCD&lt;/code&gt;, there is one standard unit. Every record for that test code — regardless of which site collected it, which lab analyzed it, or when it was collected — must have the same value in &lt;code&gt;LBSTRESU&lt;/code&gt;. When that is violated, the standardized layer is not standardized. Analysis results computed across subjects become numerically mixed.&lt;/p&gt;

&lt;p&gt;This mistake happens in three specific situations. The first is unit pass-through: the programmer assigns &lt;code&gt;LBSTRESU&lt;/code&gt; directly from &lt;code&gt;LBORRESU&lt;/code&gt; without going through a conversion metadata table, assuming all sites report in the same unit. When they do not, the assumption introduces the inconsistency silently. The second is a mid-study lab change: the central lab upgrades its reporting system and begins sending TSH in mIU/mL instead of µIU/mL. These units are numerically equivalent — the conversion factor is 1 — so no result values change, but the unit string in &lt;code&gt;LBSTRESU&lt;/code&gt; now varies within the same test code. P21 does not flag this. The third is a new local lab joining mid-study with a unit that was not anticipated in the original mapping spec, and the programmer adds a conditional branch to handle it rather than updating the metadata table.&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;USUBJID&lt;/th&gt;&lt;th&gt;VISIT&lt;/th&gt;&lt;th&gt;LBTESTCD&lt;/th&gt;&lt;th&gt;LBORRES&lt;/th&gt;&lt;th&gt;LBORRESU&lt;/th&gt;&lt;th&gt;LBSTRESN&lt;/th&gt;&lt;th&gt;LBSTRESU&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;US-001&lt;/td&gt;&lt;td&gt;Week 4&lt;/td&gt;&lt;td&gt;TSH&lt;/td&gt;&lt;td&gt;2.1&lt;/td&gt;&lt;td&gt;uIU/mL&lt;/td&gt;&lt;td&gt;2.1&lt;/td&gt;&lt;td&gt;uIU/mL&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;EU-007&lt;/td&gt;&lt;td&gt;Week 4&lt;/td&gt;&lt;td&gt;TSH&lt;/td&gt;&lt;td&gt;2.1&lt;/td&gt;&lt;td&gt;uIU/mL&lt;/td&gt;&lt;td&gt;2.1&lt;/td&gt;&lt;td&gt;uIU/mL&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;hl&quot;&gt;&lt;td&gt;US-001&lt;/td&gt;&lt;td&gt;Week 24&lt;/td&gt;&lt;td&gt;TSH&lt;/td&gt;&lt;td&gt;2.3&lt;/td&gt;&lt;td&gt;mIU/mL&lt;/td&gt;&lt;td&gt;2.3&lt;/td&gt;&lt;td&gt;mIU/mL&lt;/td&gt;&lt;/tr&gt;
&lt;tr class=&quot;hl&quot;&gt;&lt;td&gt;EU-007&lt;/td&gt;&lt;td&gt;Week 24&lt;/td&gt;&lt;td&gt;TSH&lt;/td&gt;&lt;td&gt;2.4&lt;/td&gt;&lt;td&gt;mIU/mL&lt;/td&gt;&lt;td&gt;2.4&lt;/td&gt;&lt;td&gt;mIU/mL&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;The highlighted rows show Week 24 records where the lab changed its reporting unit string. The numeric values are correct — 1 mIU/mL equals 1 µIU/mL — but &lt;code&gt;LBSTRESU&lt;/code&gt; now contains two different strings for the same &lt;code&gt;LBTESTCD&lt;/code&gt;. Pinnacle 21 validates &lt;code&gt;LBSTRESU&lt;/code&gt; against controlled terminology. It does not enforce a single unit per &lt;code&gt;LBTESTCD&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The fix is architectural. &lt;code&gt;LBSTRESU&lt;/code&gt; is assigned from a conversion metadata table keyed on &lt;code&gt;LBTESTCD&lt;/code&gt;, not mapped directly from &lt;code&gt;LBORRESU&lt;/code&gt;. The table says TSH → uIU/mL. It does not matter what string the lab sends in &lt;code&gt;LBORRESU&lt;/code&gt;. The standard unit is always what the metadata says. When a unit change happens at the lab, the metadata table is updated through change control and the unit string is harmonized.&lt;/p&gt;

&lt;pre&gt;
/* QC check: flag any LBTESTCD with multiple LBSTRESU values */
proc freq data=lb noprint;
  tables lbtestcd * lbstresu / out=unit_check;
run;

data unit_fail;
  set unit_check;
  by lbtestcd;
  if not (first.lbtestcd and last.lbtestcd);
run;

/* Any rows in unit_fail = submission-blocking issue */
proc print data=unit_fail; run;
&lt;/pre&gt;

&lt;hr&gt;

&lt;h2&gt;&lt;span class=&quot;mistake-num&quot;&gt;07&lt;/span&gt; Treating alternate units as a late-stage decision&lt;/h2&gt;

&lt;p&gt;This is the structural mistake. The others are implementation errors. This one is a planning failure that cannot be corrected cleanly at database lock.&lt;/p&gt;

&lt;p&gt;For FDA clinical submissions, the current Study Data Technical Conformance Guide v6.1 (December 2025) is explicit: submit two lab domains. &lt;code&gt;LB&lt;/code&gt; holds SI-standardized results in &lt;code&gt;LBSTRESU&lt;/code&gt;, &lt;code&gt;LBSTRESC&lt;/code&gt;, and &lt;code&gt;LBSTRESN&lt;/code&gt;. &lt;code&gt;LC&lt;/code&gt; is a custom domain structured identically to &lt;code&gt;LB&lt;/code&gt;, carrying conventional-unit results in the corresponding &lt;code&gt;–STRESU&lt;/code&gt;, &lt;code&gt;–STRESC&lt;/code&gt;, and &lt;code&gt;–STRESN&lt;/code&gt; fields. The guidance also states that the ideal source for both SI and conventional unit values is the lab vendor itself — not post-hoc conversion in SAS.&lt;/p&gt;

&lt;p&gt;That last point is operationally significant. If the vendor does not provide both unit systems, you are computing the alternate unit yourself. That conversion has to be governed, documented, and validated. A post-hoc conversion that is not in the original study spec, not in Define.xml, and not reviewed by the QC programmer is not defensible under audit. The time to contract for dual-unit vendor output is during study design, not at lock.&lt;/p&gt;

&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Approach&lt;/th&gt;&lt;th&gt;Status&lt;/th&gt;&lt;th&gt;LB content&lt;/th&gt;&lt;th&gt;Alternate unit&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
  &lt;td&gt;SUPPLB workaround&lt;/td&gt;
  &lt;td&gt;Outdated for FDA clinical&lt;/td&gt;
  &lt;td&gt;Sponsor-chosen unit&lt;/td&gt;
  &lt;td&gt;Buried in SUPPQUAL — poor reviewer access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
  &lt;td&gt;Single domain, one unit&lt;/td&gt;
  &lt;td&gt;Outdated for FDA clinical&lt;/td&gt;
  &lt;td&gt;SI or conventional — one only&lt;/td&gt;
  &lt;td&gt;Not submitted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr class=&quot;hl&quot;&gt;
  &lt;td&gt;LB + LC (SDTCG v6.1)&lt;/td&gt;
  &lt;td&gt;Current requirement&lt;/td&gt;
  &lt;td&gt;SI units in LBSTRESU&lt;/td&gt;
  &lt;td&gt;Conventional units in parallel LC domain&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;LC is not a SUPPQUAL extension. It is a full parallel dataset with its own metadata in Define.xml, its own LCSEQ sequencing variable, and its own entry in the Study Data Reviewer&#39;s Guide. A team discovering at lock that FDA expects LC — and that the lab vendor was not contracted to provide conventional units — is looking at a programmatic conversion workstream, a Define.xml rewrite for an additional domain, and an SDRG update, all under submission timelines. That is avoidable with an early planning conversation.&lt;/p&gt;

&lt;p&gt;PMDA&#39;s requirements differ in one important way. PMDA expects SI-standardized results in the submission and additionally requires that when original and converted values coexist in the dataset, the conversion equation must be documented in reviewer-facing materials — explicitly, not by reference. That means the SDRG or Define.xml Comments for &lt;code&gt;LBSTRESN&lt;/code&gt; and &lt;code&gt;LBSTRESC&lt;/code&gt; should state the factor used. &quot;Converted from LBORRESU to LBSTRESU&quot; is not enough. The equation or factor must be present.&lt;/p&gt;

&lt;div class=&quot;note&quot;&gt;
&lt;strong&gt;Global submission design rule:&lt;/strong&gt; if a study will be submitted to both FDA and PMDA, design around SI as the universal standard for LB from the start. Produce LC for conventional units to satisfy FDA&#39;s parallel-domain requirement. Document the conversion equation in Define.xml and the SDRG to satisfy PMDA. These two requirements are compatible — they just both need to be planned for.
&lt;/div&gt;

&lt;hr&gt;

&lt;h2&gt;What good implementation looks like&lt;/h2&gt;

&lt;p&gt;A defensible LB conversion setup rests on a single foundational design decision: conversion logic must live in a governed metadata table, not in SAS code. If your conversion logic lives in SAS code instead of a governed metadata table, you do not have a controlled process. You have an implementation. That distinction matters when a new local lab joins mid-enrollment, when a factor needs to be corrected, when a second programmer tries to independently reproduce the derivation, or when a regulatory reviewer asks how a specific result was computed.&lt;/p&gt;

&lt;p&gt;The metadata table has one row per &lt;code&gt;LBTESTCD&lt;/code&gt; and source unit. It contains the standard unit, the conversion factor, the source of that factor (JCTLM, NIST SP 811, or lab vendor specification), and the rounding precision. Every derivation — result, reference range, and flag — flows from the same table. When the table changes, every downstream derivation changes consistently. That is a controlled process.&lt;/p&gt;

&lt;pre&gt;
/* Example conversion metadata — one row per LBTESTCD × source unit */
data lb_conv_meta;
  length lbtestcd $8  from_unit std_unit $40  source $60;
  input lbtestcd $ from_unit $ std_unit $ factor round_to source $;
  datalines;
CREAT   mg/dL    umol/L   88.4200  0.1   JCTLM
CREAT   umol/L   umol/L    1.0000  0.1   Pass-through
GLUC    mg/dL    mmol/L    0.0555  0.01  JCTLM
GLUC    mmol/L   mmol/L    1.0000  0.01  Pass-through
HGB     g/dL     g/L      10.0000  0.1   JCTLM
HGB     g/L      g/L       1.0000  0.1   Pass-through
TSH     uIU/mL   mIU/L     1.0000  0.001 Unit-equiv
TSH     mIU/mL   mIU/L     1.0000  0.001 Unit-equiv
;
run;
&lt;/pre&gt;

&lt;p&gt;The derivation itself follows a fixed sequence: round LBSTRESN first, then derive LBSTRESC from the rounded value. Never derive LBSTRESC from the raw computation — floating-point residuals will produce character values that do not match LBSTRESN, generating a P21 finding. The same factor and rounding rule that produces LBSTRESN must also produce LBSTNRLO and LBSTNRHI.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;QC checks that matter&lt;/h2&gt;

&lt;p&gt;Standard conformance validation covers the basics — variable presence, type, codelist membership. It does not cover cross-variable consistency, conversion accuracy, or the structural requirement for the LC domain. These checks need to run as part of your standard SDTM QC suite, not as a one-time review.&lt;/p&gt;

&lt;p&gt;The first check is LBSTRESU consistency per LBTESTCD across the full dataset. A single discrepant record passes P21 and fails the analysis. The second is LBSTRESC and LBSTRESN agreement — when LBSTRESN is populated, the numeric portion of LBSTRESC must match it within rounding tolerance. The third is qualitative results with LBSTRESN populated. The fourth is inequality operator preservation — comparing the operator present in LBORRES against what appears in LBSTRESC. The fifth is reference range unit consistency — checking that LBSTNRLO and LBSTNRHI are numerically plausible relative to LBSTRESN and LBSTRESU. The sixth is a factor-based reasonableness check: for each converted record, multiply LBORRES by the expected factor and compare to LBSTRESN. If the difference exceeds the rounding tolerance, the factor is wrong or was applied incorrectly.&lt;/p&gt;

&lt;div class=&quot;warn&quot;&gt;
&lt;strong&gt;P21 does not check:&lt;/strong&gt; LBSTRESU consistency within a LBTESTCD. Conversion accuracy. Reference range unit plausibility. Whether LC is present when FDA clinical submission requires it. These are your responsibility. If your QC plan relies entirely on P21, it is incomplete.
&lt;/div&gt;

&lt;p&gt;Most production LB issues are not single-variable problems. They are mismatches between variables that individually look valid.&lt;/p&gt;
  &lt;p&gt;This is why datasets that pass P21 still fail review.&lt;/p&gt;
&lt;hr&gt;

&lt;h2&gt;Bottom line&lt;/h2&gt;

&lt;p&gt;LB unit conversion fails in the details. A result converts correctly while the reference range does not. A standard unit is assigned directly from the source rather than from controlled metadata, and three records slip through with the wrong LBSTRESU value. A qualitative result gets a numeric encoding for analysis convenience that does not belong in SDTM. An operator disappears during parsing and a boundary value becomes a detected result.&lt;/p&gt;

&lt;p&gt;None of these failures are dramatic. They do not crash anything. They travel silently into Define.xml, into ADaM derivations, into safety tables, and into submission review — where a reviewer with a summary statistics macro finds them in a way that is much harder to explain than if they had been caught in QC.&lt;/p&gt;

&lt;p&gt;The model is simple enough to keep on one line: LBORRES is collected truth, LBSTRES* is the standardized representation, and LBSTNR* follows the same unit system. Every mistake on this list is a version of breaking that contract. Keep the contract. Run the checks. Make the LB/LC structure decision before lock, not at lock.&lt;/p&gt;

&lt;hr&gt;

&lt;div class=&quot;footnote&quot;&gt;
&lt;p&gt;&lt;strong&gt;Sources&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;[1] CDISC SDTMIG v3.4 — LB domain variable definitions: LBORRES, LBORRESU, LBSTRESC, LBSTRESN, LBSTRESU, LBSTNRLO, LBSTNRHI, LBNRIND. LBNRIND documentation requirement in Define.xml. &lt;a href=&quot;https://www.cdisc.org/standards/foundational/sdtmig&quot;&gt;cdisc.org/standards/foundational/sdtmig&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[2] FDA Study Data Technical Conformance Guide v6.1, December 2025 — LB/LC two-domain requirement for clinical submissions, traceability expectations. &lt;a href=&quot;https://www.fda.gov/media/153632/download&quot;&gt;fda.gov/media/153632/download&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[3] CDISC Knowledge Base — Standardized Lab Units: FDA expects SI units in LB domain; conventional units in custom LC domain. &lt;a href=&quot;https://www.cdisc.org/kb/articles/standardized-lab-units&quot;&gt;cdisc.org/kb/articles/standardized-lab-units&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[4] PharmaSUG China 2025 (DS175) — &quot;Bridging FDA and SI Unit Requirements through LB and LC.&quot; Verbatim SDTCG 6.0 mandate and LC domain structure. &lt;a href=&quot;https://www.lexjansen.com/pharmasug-cn/2025/DS/Pharmasug-China-2025-DS175.pdf&quot;&gt;lexjansen.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[5] PMDA Q&amp;amp;A, provisional English translation, March 2025 — SI unit requirement, documentation of conversion equation when original and converted values coexist.&lt;/p&gt;
&lt;p&gt;[6] JCTLM (Joint Committee for Traceability in Laboratory Medicine) — Recommended conversion factors for clinical chemistry analytes. &lt;a href=&quot;https://www.jctlm.org&quot;&gt;jctlm.org&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[7] CDISC CT, LB Units codelist C71620 — NCI EVS. &lt;a href=&quot;https://evs.nci.nih.gov/ftp1/CDISC/SDTM/&quot;&gt;evs.nci.nih.gov&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;div class=&quot;tags&quot;&gt;
&lt;strong&gt;Tags:&lt;/strong&gt;
&lt;span&gt;SDTM&lt;/span&gt;
&lt;span&gt;LB Domain&lt;/span&gt;
&lt;span&gt;LC Domain&lt;/span&gt;
&lt;span&gt;LBORRES&lt;/span&gt;
&lt;span&gt;LBSTRESC&lt;/span&gt;
&lt;span&gt;LBSTRESN&lt;/span&gt;
&lt;span&gt;LBSTRESU&lt;/span&gt;
&lt;span&gt;LBSTNRLO&lt;/span&gt;
&lt;span&gt;LBNRIND&lt;/span&gt;
&lt;span&gt;FDA&lt;/span&gt;
&lt;span&gt;PMDA&lt;/span&gt;
&lt;span&gt;Pinnacle 21&lt;/span&gt;
&lt;span&gt;Define.xml&lt;/span&gt;
&lt;span&gt;SAS&lt;/span&gt;
&lt;/div&gt;

&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/1819660908879287709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/1819660908879287709'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/04/7-mistakes-in-lb-unit-conversion-that.html' title='7 Mistakes in LB Unit Conversion That Still Show Up in SDTM'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-4172477588518113258</id><published>2026-04-09T16:19:00.003-04:00</published><updated>2026-04-24T07:20:39.163-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="LB domain expansion"/><category scheme="http://www.blogger.com/atom/ns#" term="Ophthalmic Examinations Domain"/><category scheme="http://www.blogger.com/atom/ns#" term="Skin Response Domain"/><category scheme="http://www.blogger.com/atom/ns#" term="SUPPDS Domain revised assumption"/><title type='text'>SDTM IG 3.4: SR, OE, LB Domain Expansion, and Revised SUPPDS Assumptions</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
&lt;title&gt;SDTM IG 3.4: SR, OE, LB Expansion, and Revised SUPPDS Assumptions | StudySAS Blog&lt;/title&gt;
&lt;style&gt;
  body {
    font-family: Georgia, &#39;Times New Roman&#39;, serif;
    font-size: 16px;
    line-height: 1.75;
    color: #2c2c2c;
    background: #ffffff;
    margin: 0;
    padding: 0;
  }
  .container {
    max-width: 820px;
    margin: 0 auto;
    padding: 48px 24px 64px;
  }
  h1 {
    font-family: Georgia, serif;
    font-size: 28px;
    color: #1a1a2e;
    line-height: 1.3;
    margin: 0 0 12px 0;
    font-weight: bold;
  }
  h2 {
    font-family: Georgia, serif;
    font-size: 21px;
    color: #1a1a2e;
    margin: 44px 0 14px 0;
    border-bottom: 2px solid #1a1a2e;
    padding-bottom: 6px;
  }
  h3 {
    font-family: Georgia, serif;
    font-size: 17px;
    color: #1a1a2e;
    margin: 28px 0 10px 0;
    font-style: italic;
  }
  .meta {
    font-size: 13px;
    color: #777;
    margin-bottom: 32px;
    font-family: Arial, sans-serif;
  }
  p { margin: 0 0 18px 0; }
  pre {
    background: #f5f5f5;
    border-left: 4px solid #0066cc;
    font-family: &#39;Courier New&#39;, Courier, monospace;
    font-size: 13.5px;
    white-space: pre;
    overflow-x: auto;
    padding: 16px 18px;
    margin: 22px 0;
    line-height: 1.55;
    -webkit-overflow-scrolling: touch;
  }
  code {
    background: #f0f0f0;
    color: #b5432a;
    font-family: &#39;Courier New&#39;, Courier, monospace;
    font-size: 13.5px;
    padding: 2px 5px;
    border-radius: 2px;
  }
  .note {
    background: #fff8e1;
    border-left: 4px solid #f9a825;
    padding: 14px 18px;
    margin: 22px 0;
    font-size: 15px;
  }
  .warn {
    background: #fff3f3;
    border-left: 4px solid #cc2222;
    padding: 14px 18px;
    margin: 22px 0;
    font-size: 15px;
  }
  table {
    width: 100%;
    border-collapse: collapse;
    margin: 24px 0;
    font-size: 14.5px;
  }
  thead tr { background: #1a1a2e; color: #fff; }
  th {
    text-align: left;
    padding: 10px 14px;
    font-family: Arial, sans-serif;
    font-weight: bold;
    font-size: 13px;
    letter-spacing: 0.03em;
  }
  td {
    padding: 9px 14px;
    border-bottom: 1px solid #e0e0e0;
    vertical-align: top;
  }
  tbody tr:nth-child(even) { background: #f7f7f7; }
  .tags {
    margin-top: 52px;
    padding-top: 16px;
    border-top: 1px solid #ddd;
    font-size: 13px;
    color: #666;
    font-family: Arial, sans-serif;
  }
  .sources {
    margin-top: 40px;
    padding: 16px 18px;
    background: #f5f5f5;
    border-left: 4px solid #1a1a2e;
    font-size: 13.5px;
    font-family: Arial, sans-serif;
  }
  .sources p { margin: 0 0 8px 0; line-height: 1.5; }
  .sources a { color: #0066cc; }
  hr.divider {
    border: none;
    border-top: 1px solid #e0e0e0;
    margin: 40px 0;
  }
  .domain-label {
    display: inline-block;
    background: #1a1a2e;
    color: #fff;
    font-family: Arial, sans-serif;
    font-size: 12px;
    font-weight: bold;
    padding: 3px 9px;
    border-radius: 3px;
    letter-spacing: 0.04em;
    margin-bottom: 10px;
  }
  .version-tag {
    display: inline-block;
    background: #e8f0fe;
    color: #0066cc;
    font-family: Arial, sans-serif;
    font-size: 12px;
    padding: 2px 8px;
    border-radius: 3px;
    margin-left: 8px;
    font-weight: bold;
  }
  .correction-tag {
    display: inline-block;
    background: #fff3f3;
    color: #cc2222;
    font-family: Arial, sans-serif;
    font-size: 12px;
    padding: 2px 8px;
    border-radius: 3px;
    margin-left: 8px;
    font-weight: bold;
  }
  sup {
    font-size: 11px;
    color: #0066cc;
  }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;container&quot;&gt;

  &lt;h1&gt;&lt;/h1&gt;

  &lt;p&gt;SDTM IG 3.4 was published by CDISC in July 2022 alongside SDTM v2.0.&lt;sup&gt;[1]&lt;/sup&gt; This post focuses on what actually changes programming and submission behavior — written for SDTM programmers and submission leads. If you have been working from 3.2 or 3.3, several of these changes will require updates to domain routing logic, controlled terminology mappings, Define.xml metadata, and SUPPDS population rules that have been stable in company standards for years. This post examines four areas where working programmers face concrete re-mapping decisions: the SR domain and how the IS scope expansion in 3.4 redraws its boundaries, the OE domain as the post-MO home for ophthalmic data, the restructured LB with confirmed new variables and a substantially narrowed scope, and the SUPPDS assumptions v3.4 quietly rewrote.&lt;/p&gt;

  &lt;p&gt;One terminology correction before we start. Several posts and internal notes reference an &quot;ON&quot; domain in the context of SDTM IG 3.4. There is no domain with the two-letter code ON in any version of the SDTMIG. The ophthalmic domain code is &lt;strong&gt;OE&lt;/strong&gt; — Ophthalmic Examinations — introduced in v3.3. Section 9 of v3.4 introduced OI (Non-Host Organism Identifiers) as a Study Reference dataset, not a clinical observations domain. This post uses OE throughout.&lt;/p&gt;

  &lt;hr class=&quot;divider&quot;&gt;

  &lt;h2&gt;SR — Skin Response Domain&lt;/h2&gt;

  &lt;div class=&quot;domain-label&quot;&gt;SR&lt;/div&gt;
  &lt;span class=&quot;version-tag&quot;&gt;Introduced v3.2&lt;/span&gt;
  &lt;span class=&quot;version-tag&quot;&gt;Routing boundaries defined v3.4&lt;/span&gt;

  &lt;p&gt;SR was introduced in SDTM IG 3.2 as one of eleven new domains in that release.&lt;sup&gt;[2]&lt;/sup&gt; It is a Findings Sub-Class domain — not a general Findings domain and not a Findings About domain.&lt;sup&gt;[3]&lt;/sup&gt; One record per test per visit per subject. It captures dermal responses to antigens typically assessed from skin-prick or intradermal challenge: wheal diameter, erythema diameter, induration size. The structure did not change in v3.4. What changed is the precision of the boundary condition that determines whether data belongs in SR at all.&lt;/p&gt;

  &lt;h3&gt;The Three-Way Routing Decision Formalized in v3.4&lt;/h3&gt;

  &lt;p&gt;The IS scope expansion in v3.4 is the driver here. Under v3.2 and v3.3, the IS domain was scoped narrowly to data from assessments describing whether a study therapy provoked an immune response. Specimen-based immune testing in other contexts ended up in LB or MB depending on version. In v3.4, IS is redefined to cover all specimen-based assessments that measure the presence, magnitude, and scale of an immune response upon any antigen stimulation or encounter — not restricted to study therapy.&lt;sup&gt;[4]&lt;/sup&gt;&lt;/p&gt;

  &lt;p&gt;That expansion creates a three-way routing that v3.4 defines explicitly for allergy and vaccine programs.&lt;sup&gt;[4]&lt;/sup&gt; First split: is the immune response specimen-based or surface-based? Specimen-based data — anything measured from a collected sample: serum IgE levels, antibody titers from blood or plasma, cellular immune assays from PBMCs — goes to IS. Surface-based responses split further on intent. A wanted, expected localized dermal response to a substance administered to provoke that response goes to SR. A tuberculin PPD skin test wheal is SR. An allergen skin prick test wheal-and-flare is SR. An unwanted, symptomatic allergic reaction — injection-site erythema coded as an adverse event, vaccine reactogenicity — goes to AE or CE.&lt;/p&gt;

  &lt;div class=&quot;note&quot;&gt;
    &lt;strong&gt;Routing decision for dermal and immune data under v3.4&lt;/strong&gt; [Source: CDISC KB Article, IS Domain Scope Update]&lt;br&gt;&lt;br&gt;
    Specimen-based immune response (serum IgE, antibody titers, ELISPOT, neutralization assays) → &lt;strong&gt;IS&lt;/strong&gt;&lt;br&gt;
    Localized surface response, wanted and expected (PPD induration, allergen prick wheal) → &lt;strong&gt;SR&lt;/strong&gt;&lt;br&gt;
    Localized surface response, unwanted or symptomatic → &lt;strong&gt;AE&lt;/strong&gt; or &lt;strong&gt;CE&lt;/strong&gt;
  &lt;/div&gt;

  &lt;h3&gt;SR Domain Structure&lt;/h3&gt;

  &lt;p&gt;The variables that programmers most often underuse or misuse in SR: &lt;code&gt;SRANTREG&lt;/code&gt; captures the anatomical region of the test application site — not the general body area. &lt;code&gt;SRLAT&lt;/code&gt; (laterality) must be populated for bilateral comparisons. &lt;code&gt;SRCAT&lt;/code&gt; captures test category (ALLERGEN PANEL, TUBERCULIN) and &lt;code&gt;SRSCAT&lt;/code&gt; the subcategory. When a protocol tests multiple antigen concentrations on the same visit, each concentration generates a separate record. The structure below shows a standard bilateral allergy panel with one NOT DONE record handled correctly:&lt;/p&gt;

  &lt;pre&gt;/* SR — Bilateral allergen panel, one NOT DONE record */

STUDYID  DOMAIN  USUBJID         SRSEQ  SRTESTCD  SRTEST             SRORRES  SRSTRESC  SRSTRESN  SRSTRESU
-------- ------  --------------- -----  --------  -----------------  -------  --------  --------  --------
ABC-001  SR      ABC-001-001-01  1      WHEAL     Wheal Diameter     12       12        12        mm
ABC-001  SR      ABC-001-001-01  2      ERYTHEMA  Erythema Diameter  25       25        25        mm
ABC-001  SR      ABC-001-001-01  3      WHEAL     Wheal Diameter     (null)   (null)    (null)    (null)

         SRSTAT    SRREASND        SRANTREG      SRLAT   SRDTC        SRDY  VISIT
         --------  --------------  ------------  ------  -----------  ----  ------
         (null)    (null)          LEFT FOREARM  LEFT    2023-03-15   8     WEEK 4
         (null)    (null)          LEFT FOREARM  LEFT    2023-03-15   8     WEEK 4
         NOT DONE  SUBJECT REFUSED RIGHT FOREARM RIGHT   2023-03-15   8     WEEK 4&lt;/pre&gt;

  &lt;h3&gt;What v3.4 Changed for SR in Practice&lt;/h3&gt;

  &lt;p&gt;If your program was routing anti-allergen IgE antibody titers into LB — which was correct under v3.2 and v3.3 for pre-exposure baseline data — those records move to IS under v3.4.&lt;sup&gt;[4]&lt;/sup&gt; SR itself is structurally unchanged, but its boundary with IS is now formally defined in the IG rather than left to interpretation. FDA reviewers are expected to confirm appropriate domain selection when allergy or vaccine data is present in a submission, so your Reviewer&#39;s Guide should document the routing decision explicitly.&lt;/p&gt;

  &lt;div class=&quot;warn&quot;&gt;
    &lt;strong&gt;Baseline split problem:&lt;/strong&gt; Under v3.2/v3.3, a common pattern was to put pre-treatment baseline antibody measurements in LB (or MB under 3.3) and post-exposure measurements in IS, because IS was restricted to therapy-induced responses. This creates a baseline/post split across domains that makes ADaM baseline flagging and change-from-baseline derivation fragile. Under v3.4, all antigen-induced antibody data — including pre-exposure baseline if the antigen in question is the study treatment or allergen — belongs in IS. Baseline records should be anchored by VISITNUM and EPOCH context within IS, not by a separate domain. Programs transitioning from 3.3 to 3.4 must document this split explicitly in their Reviewer&#39;s Guide.
  &lt;/div&gt;

  &lt;hr class=&quot;divider&quot;&gt;

  &lt;h2&gt;OE — Ophthalmic Examinations Domain&lt;/h2&gt;

  &lt;div class=&quot;domain-label&quot;&gt;OE&lt;/div&gt;
  &lt;span class=&quot;version-tag&quot;&gt;Introduced v3.3&lt;/span&gt;
  &lt;span class=&quot;version-tag&quot;&gt;MO decommissioned v3.4&lt;/span&gt;
  &lt;span class=&quot;correction-tag&quot;&gt;Code is OE, not ON&lt;/span&gt;

  &lt;p&gt;OE was introduced in SDTM IG 3.3 as one of several body-system Findings domains developed through TAUG work.&lt;sup&gt;[5]&lt;/sup&gt; It was not new in v3.4. What changed in v3.4 is that the MO (Morphology) domain was formally decommissioned, and the IG explicitly directs sponsors to use body-system domains — OE among them — rather than MO for morphological findings data.&lt;sup&gt;[1]&lt;/sup&gt; For ophthalmology programs, this means OE is now the only compliant home for both functional and morphological eye data under v3.4.&lt;/p&gt;

  &lt;h3&gt;What Goes in OE&lt;/h3&gt;

  &lt;p&gt;OE captures structured findings from ophthalmic assessments: visual acuity by Snellen chart or ETDRS letter score, intraocular pressure by Goldmann applanation tonometry or non-contact methods, slit-lamp biomicroscopy findings, fundoscopy results, optical coherence tomography retinal thickness measurements, visual field parameters, color vision test results, and corneal topography. Quantitative and categorical results from any structured ophthalmic examination go in OE.&lt;/p&gt;

  &lt;h3&gt;The Laterality Requirement&lt;/h3&gt;

  &lt;p&gt;This is the most consistent error in OE datasets at submission. &lt;code&gt;OELAT&lt;/code&gt; is Expected, not Permissible. Every record must document whether the finding applies to the LEFT eye, RIGHT eye, or BILATERAL. When an assessment is bilateral and results are collected per eye, two records are required — one per laterality value. Reviewers use &lt;code&gt;OELAT&lt;/code&gt; to reconstruct the patient-eye-visit trajectory across timepoints. Automated review tools cannot do this when &lt;code&gt;OELAT&lt;/code&gt; is missing or inconsistently populated. The example below shows a correctly structured bilateral baseline assessment:&lt;/p&gt;

  &lt;pre&gt;/* OE — Bilateral baseline: visual acuity and IOP, one eye per record */

STUDYID  DOMAIN  USUBJID         OESEQ  OETESTCD  OETEST                 OELAT   OELOC
-------- ------  --------------- -----  --------  ---------------------  ------  -----
XYZ-002  OE      XYZ-002-005-03  1      VATOTSC   Visual Acuity Total    LEFT    EYE
XYZ-002  OE      XYZ-002-005-03  2      VATOTSC   Visual Acuity Total    RIGHT   EYE
XYZ-002  OE      XYZ-002-005-03  3      IOP       Intraocular Pressure   LEFT    EYE
XYZ-002  OE      XYZ-002-005-03  4      IOP       Intraocular Pressure   RIGHT   EYE

         OEORRES  OESTRESC  OESTRESN  OESTRESU  OEMETHOD  OEDTC        VISIT
         -------  --------  --------  --------  --------  -----------  --------
         72       72        72        letters   ETDRS     2023-06-01   BASELINE
         68       68        68        letters   ETDRS     2023-06-01   BASELINE
         14       14        14        mmHg      GAT       2023-06-01   BASELINE
         16       16        16        mmHg      GAT       2023-06-01   BASELINE&lt;/pre&gt;

  &lt;p&gt;&lt;code&gt;OELOC&lt;/code&gt; captures the anatomical location within the eye — CORNEA, RETINA, MACULA, OPTIC DISC — and becomes essential when multiple findings from different eye structures are collected at a single visit. &lt;code&gt;OEMETHOD&lt;/code&gt; distinguishes assessment methods, which matters for IOP where Goldmann applanation, non-contact tonometry, and iCare rebound produce systematically different values with different reference ranges.&lt;/p&gt;

  &lt;h3&gt;ETDRS vs Snellen and the STRESC Problem&lt;/h3&gt;

  &lt;p&gt;Ophthalmic trials frequently collect Snellen notation on the CRF while the protocol specifies ETDRS letter equivalents as the analysis variable. These are not interchangeable. &lt;code&gt;OEORRES&lt;/code&gt; should capture what the CRF collected — the Snellen fraction if that is what was entered. &lt;code&gt;OESTRESC&lt;/code&gt; and &lt;code&gt;OESTRESN&lt;/code&gt; hold the standardized numeric result. If the CRF collected 20/40 Snellen and you are putting 50 in &lt;code&gt;OESTRESN&lt;/code&gt;, that conversion must be documented in the Define.xml Comments column and explained in the Reviewer&#39;s Guide, including which reference conversion chart was used. &lt;code&gt;OETESTCD&lt;/code&gt; must also distinguish method: VATOTSC with &lt;code&gt;OEMETHOD = ETDRS&lt;/code&gt; is a different concept from VATOTSC with &lt;code&gt;OEMETHOD = SNELLEN&lt;/code&gt;. These should not share a single TESTCD if their results are not interchangeable for analysis.&lt;/p&gt;

  &lt;h3&gt;MO Decommissioning and Backward Compatibility&lt;/h3&gt;

  &lt;p&gt;The IG recommends that sponsors submitting under v3.4 use body-system domains and leave MO behind entirely — even if earlier studies in the same program mapped to MO.&lt;sup&gt;[1]&lt;/sup&gt; For programs with ophthalmology data across multiple studies where some were submitted under v3.3 (OE) and earlier studies used MO, the Reviewer&#39;s Guide must document this version-based domain difference. The ADaM programmer needs to know the source domain for each study when tracing derivations back to tabulation data.&lt;/p&gt;

  &lt;div class=&quot;note&quot;&gt;
    &lt;strong&gt;Note on OE in v3.4:&lt;/strong&gt; OE has no new variables added in v3.4 itself. It entered the SDTMIG through v3.3. What v3.4 changed is the formal decommissioning of MO, removing the alternative that some sponsors were still using for morphological findings. Under v3.4, OE is the only compliant domain for ophthalmic observation data.
  &lt;/div&gt;

  &lt;hr class=&quot;divider&quot;&gt;

  &lt;h2&gt;LB — Laboratory Test Results: Confirmed New Variables and Narrowed Scope&lt;/h2&gt;

  &lt;div class=&quot;domain-label&quot;&gt;LB&lt;/div&gt;
  &lt;span class=&quot;version-tag&quot;&gt;New variables in v3.4&lt;/span&gt;
  &lt;span class=&quot;version-tag&quot;&gt;~400 CT terms migrate to IS&lt;/span&gt;

  &lt;p&gt;LB in 3.4 changed in two directions at once: it gained new variables designed to decompose complex assay metadata, and it lost a large category of data to IS. The CDISC IG documentation states that LB was updated to include 10 new variables in v3.4.&lt;sup&gt;[1]&lt;/sup&gt; The complete list requires CDISC Library access. The variables below are confirmed from publicly available CDISC sources.&lt;sup&gt;[1][4][6]&lt;/sup&gt;&lt;/p&gt;

  &lt;h3&gt;Confirmed New Variables in LB for v3.4&lt;/h3&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Root Variable&lt;/th&gt;
        &lt;th&gt;LB-Prefixed Name&lt;/th&gt;
        &lt;th&gt;Label&lt;/th&gt;
        &lt;th&gt;Role&lt;/th&gt;
        &lt;th&gt;Shared With&lt;/th&gt;
        &lt;th&gt;Primary Purpose&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;TSTCND&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code&gt;LBTSTCND&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Test Condition&lt;/td&gt;
        &lt;td&gt;Variable Qualifier&lt;/td&gt;
        &lt;td&gt;IS, CP&lt;/td&gt;
        &lt;td&gt;Stimulus condition under which the test was performed (e.g., EX VIVO STIMULATION, UNSTIMULATED)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;CNDAGT&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code&gt;LBCNDAGT&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Test Condition Agent&lt;/td&gt;
        &lt;td&gt;Variable Qualifier&lt;/td&gt;
        &lt;td&gt;IS, CP&lt;/td&gt;
        &lt;td&gt;Specific agent used to create the test condition (e.g., LPS, PHA-M, PHYTOHAEMAGGLUTININ)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;BDAGNT&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code&gt;LBBDAGNT&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Binding Agent&lt;/td&gt;
        &lt;td&gt;Variable Qualifier&lt;/td&gt;
        &lt;td&gt;IS, CP&lt;/td&gt;
        &lt;td&gt;Binding target or detection agent (antibody, probe) used in the assay — separates analyte from detection method&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;TSTOPO&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code&gt;LBTSTOPO&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Test Operational Objective&lt;/td&gt;
        &lt;td&gt;Variable Qualifier&lt;/td&gt;
        &lt;td&gt;IS&lt;/td&gt;
        &lt;td&gt;What the test is operationally designed to accomplish: DETECTION, QUANTIFICATION, CHARACTERIZATION&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;TSTDTL&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;code&gt;LBTSTDTL&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;Test Detail&lt;/td&gt;
        &lt;td&gt;Variable Qualifier&lt;/td&gt;
        &lt;td&gt;IS&lt;/td&gt;
        &lt;td&gt;Additional granularity beyond --TEST — distinguishes assay variants that share a TESTCD (e.g., NT50, NT80, PRNT50)&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;LBCOLSRT&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;em&gt;domain-specific&lt;/em&gt;&lt;/td&gt;
        &lt;td&gt;Collection Sort Order&lt;/td&gt;
        &lt;td&gt;Variable Qualifier*&lt;/td&gt;
        &lt;td&gt;LB only&lt;/td&gt;
        &lt;td&gt;Ordering of collection records when multiple tubes are taken at a single timepoint; role corrected by errata&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;LBLOINC&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;&lt;em&gt;domain-specific&lt;/em&gt;&lt;/td&gt;
        &lt;td&gt;LOINC Code&lt;/td&gt;
        &lt;td&gt;Record Qualifier†&lt;/td&gt;
        &lt;td&gt;CP, MB, MS (parallel)&lt;/td&gt;
        &lt;td&gt;Formal LOINC mapping for the test — role corrected by errata from Synonym Qualifier to Record Qualifier&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;p style=&quot;font-size:13.5px; color:#555;&quot;&gt;* &lt;code&gt;LBCOLSRT&lt;/code&gt; was published with role &quot;Record Qualifier&quot; and corrected by errata to &quot;Variable Qualifier.&quot;&lt;sup&gt;[1-errata]&lt;/sup&gt; &amp;nbsp;&amp;nbsp; † &lt;code&gt;LBLOINC&lt;/code&gt; was published with role &quot;Synonym Qualifier&quot; and corrected by errata to &quot;Record Qualifier.&quot;&lt;sup&gt;[1-errata]&lt;/sup&gt;&lt;/p&gt;

  &lt;h3&gt;Why These Variables Were Added: The TESTCD Overloading Problem&lt;/h3&gt;

  &lt;p&gt;Under v3.2 and v3.3, a complex immunogenicity assay had to compress all meaningful metadata into &lt;code&gt;LBTESTCD&lt;/code&gt; (max 8 characters) and &lt;code&gt;LBTEST&lt;/code&gt; (max 40 characters) — resulting in NCI C-codes substituted for readable TESTCDs, truncated TEST values, and supplemental qualifiers created to carry context that had no standard home.&lt;sup&gt;[6]&lt;/sup&gt; v3.4 post-coordinates this into structured variables. The same test now looks like this:&lt;/p&gt;

  &lt;pre&gt;/* v3.2/3.3 — pre-coordinated, truncated, supplemental qualifier required */
LBTESTCD = NRSVIGG            /* NCI C-code used because human-readable name exceeds 8 chars */
LBTEST   = Neut. Respirat. Syncytial Virus IgG NT50*  /* truncated to fit 40-char limit */
/* SUPPRS: QNAM = &quot;50% NEUTRALIZATION TITER&quot;, QVAL = &quot;PRNT&quot; */

/* v3.4 — post-coordinated across structured variables, IS domain */
ISTESTCD = MBIGGNAB           /* Neutralizing Microbial-induced IgG Antibody */
ISTEST   = Neutralizing Microbial-induced IgG Antibody
ISBDAGNT = RESPIRATORY SYNCYTIAL VIRUS
ISTSTDTL = 50% NEUTRALIZATION TITER
/* No supplemental qualifiers needed */&lt;/pre&gt;

  &lt;p&gt;LBTESTCD remains human-readable under v3.4. Context that was pre-coordinated into compound test names now has its own standard variable home, and SUPP-- qualifiers created to carry BINDING AGENT, CONDITION, or ASSAY VARIANT information can be retired.&lt;/p&gt;

  &lt;h3&gt;The LBLOINC Errata: Define.xml Impact&lt;/h3&gt;

  &lt;p&gt;This errata entry has a direct consequence in Define.xml that is easy to miss. &lt;code&gt;LBLOINC&lt;/code&gt; was published in the original v3.4 release with the role of Synonym Qualifier.&lt;sup&gt;[1-errata]&lt;/sup&gt; The errata corrects it to Record Qualifier. In Define.xml, Synonym Qualifier variables are treated as alternate labels for the topic variable — they do not carry independent origin, method, or codelist metadata. Record Qualifiers do. If your Define.xml for LB was templated against the originally published role assignment, the metadata for LBLOINC is wrong. FDA review tools validate against the model metadata. Fix it before submission. The same errata applies to &lt;code&gt;CPLOINC&lt;/code&gt;, &lt;code&gt;MBLOINC&lt;/code&gt;, and &lt;code&gt;MSLOINC&lt;/code&gt; — all had the same role error and the same correction.&lt;/p&gt;

  &lt;h3&gt;The Scope Contraction: ~400 CT Terms Leave LB for IS&lt;/h3&gt;

  &lt;p&gt;This is the part that breaks existing lab standards programs. Under v3.4, LB no longer contains most immune response assessments or non-host organism tests.&lt;sup&gt;[6]&lt;/sup&gt; Approximately 400 antibody-related TESTCD and TEST controlled terminology values are deprecated from LB (and MB) and remodeled in IS using IS domain standard variables including &lt;code&gt;ISTESTCD&lt;/code&gt;, &lt;code&gt;ISBDAGNT&lt;/code&gt;, and &lt;code&gt;ISTSTDTL&lt;/code&gt;.&lt;sup&gt;[6]&lt;/sup&gt; CDISC publishes a mapping file updated quarterly to help sponsors map deprecated concepts to their new post-coordinated IS equivalents.&lt;/p&gt;

  &lt;p&gt;What LB retains: clinical chemistry, hematology, urinalysis, coagulation, PK-supporting bioassays, and autoantibodies driven by pre-existing conditions not related to antigen stimulation. The boundary test is: is this measuring an immune response to an antigen? If yes, IS. If it is a general biochemical or hematological measurement, LB.&lt;/p&gt;

  &lt;div class=&quot;warn&quot;&gt;
    &lt;strong&gt;SAS standards impact:&lt;/strong&gt; Any master LBTESTCD library that was built against v3.2 or v3.3 controlled terminology includes test codes that no longer belong in LB under v3.4. If your routing macro assigns domain based on LBTESTCD match against that library, it will continue to put immune response data in lb.xpt incorrectly. The library needs to be audited against the CDISC deprecation mapping file. Test codes flagged for migration need to be removed from the LB library and remapped to IS controlled terminology. Any SUPP-- qualifiers that were created to carry binding agent or test condition context for those records can be retired if the data moves to IS standard variables.
  &lt;/div&gt;

  &lt;hr class=&quot;divider&quot;&gt;

  &lt;h2&gt;SUPPDS — Three Revised Assumptions in v3.4&lt;/h2&gt;

  &lt;div class=&quot;domain-label&quot;&gt;SUPPDS&lt;/div&gt;
  &lt;span class=&quot;version-tag&quot;&gt;Assumptions revised v3.4&lt;/span&gt;

  &lt;p&gt;Three changes in v3.4 directly affect what goes in SUPPDS and what does not. Two of them prohibit things that were common practice under v3.2 and v3.3. One removes a restriction that was forcing inaccurate DS modeling.&lt;/p&gt;

  &lt;h3&gt;Population Flags Are No Longer SDTM Data&lt;/h3&gt;

  &lt;p&gt;This is stated explicitly in v3.4 DM domain assumptions: population flags — &lt;code&gt;COMPLT&lt;/code&gt;, &lt;code&gt;FULLSET&lt;/code&gt;, &lt;code&gt;ITT&lt;/code&gt;, &lt;code&gt;PPROT&lt;/code&gt;, and &lt;code&gt;SAFETY&lt;/code&gt; — should not be included in SDTM data.&lt;sup&gt;[7]&lt;/sup&gt; Under v3.2 and v3.3 guidance, many sponsors included these in SUPPDM, on the reasoning that they were subject-level qualifiers derivable from disposition and protocol data. v3.4 closes that. These values are ADaM population derivation outputs. When they appear in both SDTM and ADaM, reviewers cannot establish the direction of derivation — whether the flag drove the analysis or was derived from it. The circular traceability dependency is the problem. If your SUPPDM template includes population flags, that template needs to change for any v3.4 submission.&lt;/p&gt;

  &lt;h3&gt;EPOCH Restriction for PROTOCOL MILESTONE Records Removed&lt;/h3&gt;

  &lt;p&gt;Under earlier guidance, the DS domain assumption was that EPOCH should not be populated when &lt;code&gt;DSCAT = &quot;PROTOCOL MILESTONE&quot;&lt;/code&gt;.&lt;sup&gt;[7]&lt;/sup&gt; The logic was that milestones like Informed Consent and Screen Failure are not tied to a treatment epoch. In practice this prevented accurate representation of programs with multiple consent events — re-consent procedures, optional substudy consent, adaptive design consent updates — where the EPOCH context was needed to distinguish which record represented which consent event within which trial phase. v3.4 removes this restriction. EPOCH may now be populated for PROTOCOL MILESTONE records. If you use this capability, your SE and TV domains must define and include the EPOCH values you reference in DS.&lt;/p&gt;

  &lt;h3&gt;DSSCAT: Formalizing the Treatment vs Participation Split&lt;/h3&gt;

  &lt;p&gt;v3.3 formalized the use of &lt;code&gt;DSSCAT&lt;/code&gt; to distinguish study treatment disposition from study participation disposition. v3.4 reinforces this structure and clarifies the SUPPDS boundary that results from it.&lt;sup&gt;[7]&lt;/sup&gt; The correct architecture is: &lt;code&gt;DSCAT&lt;/code&gt; holds the high-level category (DISPOSITION EVENT, PROTOCOL MILESTONE). &lt;code&gt;DSSCAT&lt;/code&gt; distinguishes study treatment disposition from study participation disposition within each DSCAT category. When a subject discontinues treatment but continues in follow-up, that is two DS records — one with &lt;code&gt;DSSCAT = &quot;STUDY TREATMENT DISPOSITION&quot;&lt;/code&gt; and one with &lt;code&gt;DSSCAT = &quot;STUDY PARTICIPATION DISPOSITION&quot;&lt;/code&gt;.&lt;/p&gt;

  &lt;p&gt;SUPPDS is appropriate when additional context cannot be captured in standard DS variables — a free-text withdrawal reason when DSDECOD controlled terminology is insufficient, or a sponsor-specific sub-reason below the level of standard coding. It is not appropriate for data that could go in DSCAT, DSSCAT, or DSDECOD with the correct controlled terminology applied. The more common audit finding is sponsors using SUPPDS for data that belongs in DSSCAT or as a DSDECOD value.&lt;/p&gt;

  &lt;div class=&quot;note&quot;&gt;
    &lt;strong&gt;Define.xml VLM implication:&lt;/strong&gt; If DSSCAT splits treatment and participation disposition, the Value Level Metadata for DSDECOD should reflect different CDISC controlled terminology codelists for each DSSCAT value. The DS controlled terminology codelist has separate value sets for study treatment outcomes and study participation outcomes. Applying the general DSDECOD codelist without VLM differentiation by DSSCAT is a common P21 finding in Define.xml review. Build the VLM correctly from the start — do not treat DSDECOD as having a single codelist applicable to all DS records.
  &lt;/div&gt;

  &lt;h3&gt;What Still Belongs in SUPPDS&lt;/h3&gt;

  &lt;p&gt;With population flags prohibited and DSSCAT formalized, the legitimate use cases for SUPPDS narrow considerably. SUPPDS is appropriate for: protocol deviation sub-reason text that does not map to standard DSDECOD values, sponsor-specific categorization of withdrawal reason at a level below CDISC controlled terminology, and date-level detail for milestones where a second date variable is needed and no standard variable exists. It is not appropriate for data that has a standard DS variable — including &lt;code&gt;DSSCAT&lt;/code&gt;, &lt;code&gt;EPOCH&lt;/code&gt;, and &lt;code&gt;DSCAT&lt;/code&gt; — even if those variables have not been used historically in your company standards.&lt;/p&gt;

  &lt;hr class=&quot;divider&quot;&gt;

  &lt;h2&gt;Transition Checklist for v3.4&lt;/h2&gt;

  &lt;p&gt;For each of the areas covered, the practical re-mapping work is specific and auditable.&lt;/p&gt;

  &lt;p&gt;For SR: audit any allergy or vaccine program where antibody titer data was routed to LB at baseline and IS post-exposure. Under v3.4, antigen-induced antibody records should all be in IS regardless of collection timing relative to study product exposure. Update or retire any SUPP-- qualifiers that were carrying immune response context that now has IS standard variable homes. Document the routing decision in the Reviewer&#39;s Guide explicitly.&lt;/p&gt;

  &lt;p&gt;For OE: if any prior studies in the same program mapped ophthalmic data to MO, document the version-based domain difference in the Reviewer&#39;s Guide. Audit OELAT population across all OE datasets — Expected variables with missing values are a P21 finding. Confirm that OETESTCD values distinguish assessment method when different methods produce non-interchangeable results. Verify that any Snellen-to-ETDRS conversions are documented in Define.xml Comments and the Reviewer&#39;s Guide.&lt;/p&gt;

  &lt;p&gt;For LB: run your master LBTESTCD library against the CDISC deprecation mapping file to identify the test codes that must migrate to IS. Remove those codes from LB routing logic and add them to IS controlled terminology mappings. Fix the LBLOINC role in your Define.xml metadata template from Synonym Qualifier to Record Qualifier. Also apply the same fix for CPLOINC, MBLOINC, and MSLOINC if those domains are in your submission. Evaluate the confirmed new variables — LBTSTCND, LBCNDAGT, LBBDAGNT, LBTSTOPO, LBTSTDTL — against your therapeutic area&#39;s existing SUPP-- qualifiers to determine whether any SUPPQUAL content can be retired in favor of standard variables.&lt;/p&gt;

  &lt;p&gt;For SUPPDS: remove population flags from any SUPPDM or SUPPDS template. Update VLM for DSDECOD to reflect separate controlled terminology codelists by DSSCAT value. Confirm that EPOCH is populated for PROTOCOL MILESTONE records where epoch context is meaningful for the study design. Audit SUPPDS content to confirm that each QNAM cannot be mapped to a standard DS variable under v3.4 assumptions.&lt;/p&gt;

  &lt;p&gt;None of this is optional for studies submitted under v3.4. FDA&#39;s Data Standards Catalog lists v3.4 as the current supported version. P21 Enterprise validation runs against v3.4 conformance rules. The time to update the standards is before the study starts, not during submission preparation. If your standards still reflect 3.2 or 3.3 assumptions, these are the areas that will surface first in review.&lt;/p&gt;

  &lt;hr class=&quot;divider&quot;&gt;

  &lt;div class=&quot;sources&quot;&gt;
    &lt;p&gt;&lt;strong&gt;Sources and Verification&lt;/strong&gt;&lt;/p&gt;
    &lt;p&gt;[1] CDISC. &lt;em&gt;Study Data Tabulation Model Implementation Guide: Human Clinical Trials v3.4 (Final)&lt;/em&gt;. July 2022. &lt;a href=&quot;https://www.cdisc.org/standards/foundational/sdtmig/sdtmig-v3-4&quot; target=&quot;_blank&quot;&gt;cdisc.org/standards/foundational/sdtmig/sdtmig-v3-4&lt;/a&gt; — Primary source for all v3.4 domain specifications, errata (LBLOINC role, LBCOLSRT role, CPLOINC/MBLOINC/MSLOINC role corrections), and SUPPDS assumption changes.&lt;/p&gt;
    &lt;p&gt;[2] CDISC. &lt;em&gt;SDTMIG v3.2&lt;/em&gt;. 2013. &lt;a href=&quot;https://www.cdisc.org/standards/foundational/sdtmig/sdtmig-v3-2&quot; target=&quot;_blank&quot;&gt;cdisc.org/standards/foundational/sdtmig/sdtmig-v3-2&lt;/a&gt; — Source confirming SR introduced in v3.2 (with EC, PR, HO, DD, IS, MI, MO, RP, SS, TD); SR errata confirming Findings Sub-Class classification.&lt;/p&gt;
    &lt;p&gt;[3] PharmaSUG 2016, Paper DS04. Wittle et al. &lt;em&gt;Moving up! — SDTM v3.2 — What is new and how to use it&lt;/em&gt;. — Confirms SR structure: one record per test per visit per subject; dermal responses to antigens from skin-prick assessments.&lt;/p&gt;
    &lt;p&gt;[4] CDISC Knowledge Base. &lt;em&gt;IS Domain Scope Update for the SDTMIG v3.4: A Development History and the Difficulties of Standardizing Complicated Biological Processes&lt;/em&gt;. &lt;a href=&quot;https://www.cdisc.org/kb/articles/domain-scope-update-sdtmig-v3-4-development-history-and-difficulties-standardizing&quot; target=&quot;_blank&quot;&gt;cdisc.org/kb/articles&lt;/a&gt; — Source for three-way routing decision (SR vs IS vs AE/CE), IS scope redefinition, and antigen definition in v3.4.&lt;/p&gt;
    &lt;p&gt;[5] CDISC 2024 China Interchange. Fan Yang. &lt;em&gt;An In-Depth Analysis of the Updates and Challenges in SDTM IG 3.3 and 3.4&lt;/em&gt;. &lt;a href=&quot;https://www.cdisc.org/sites/default/files/2024-09/2024_CDISC_An%20In-Depth%20Analysis%20of%20the%20Updates%20and%20Challenges%20in%20SDTM%20IG%203.3%20and%203.4%20_Fan%20Yang.pdf&quot; target=&quot;_blank&quot;&gt;cdisc.org&lt;/a&gt; — Confirms OE (Ophthalmic Examinations) introduced in v3.3, not v3.4; MO decommissioned in v3.4.&lt;/p&gt;
    &lt;p&gt;[6] CDISC Webinar. Li et al. &lt;em&gt;LB, MB &amp;amp; IS Domain Scope Changes for the SDTMIG v3.4 and Impact on Controlled Terminology&lt;/em&gt;. June 2023. &lt;a href=&quot;https://www.cdisc.org/sites/default/files/pdf/Education%20Webinar_LB-MB-IS%20Scope%20Change%20and%20CT%20Imapact_2023-06-22_updated.pdf&quot; target=&quot;_blank&quot;&gt;cdisc.org (PDF)&lt;/a&gt; — Primary source for: confirmed new LB/IS/CP variables (BDAGNT, TSTCND, CNDAGT, TSTOPO, TSTDTL), TESTCD overloading rationale, ~400 CT term deprecations from LB/MB to IS, LB scope definition under v3.4.&lt;/p&gt;
    &lt;p&gt;[7] PHUSE-US 2024. Bheemagani et al. &lt;em&gt;What&#39;s New in the SDTMIG v3.4 and the SDTM v2.0&lt;/em&gt;. &lt;a href=&quot;https://www.lexjansen.com/phuse-us/2024/ds/PAP_DS10.pdf&quot; target=&quot;_blank&quot;&gt;lexjansen.com&lt;/a&gt; — Source for: population flags prohibition in SDTM (DM domain assumption), EPOCH restriction removal for PROTOCOL MILESTONE records, DSSCAT treatment vs participation split.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;tags&quot;&gt;
    Tags: SDTM IG 3.4, SR domain, OE domain, LB domain, SUPPDS, CDISC, IS domain, immunogenicity, Define.xml, VLM, SDTM programming, regulatory submissions, FDA, controlled terminology, P21 validation, BDAGNT, TSTCND, LBLOINC errata, MO decommissioning
  &lt;/div&gt;

&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/4172477588518113258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/4172477588518113258'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/04/sdtm-ig-34-sr-oe-lb-domain-expansion.html' title='SDTM IG 3.4: SR, OE, LB Domain Expansion, and Revised SUPPDS Assumptions'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-968227084245683161</id><published>2026-04-07T10:49:00.002-04:00</published><updated>2026-04-24T07:21:11.481-04:00</updated><title type='text'>PMDA SDTM Submission Requirements vs FDA: Where They Actually Diverge</title><content type='html'>&lt;div style=&quot;max-width:860px;margin:0 auto;font-family:Georgia, &#39;Times New Roman&#39;, serif;font-size:17px;line-height:1.8;color:#222;&quot;&gt;

  &lt;h1 style=&quot;font-size:34px;line-height:1.3;margin:0 0 10px 0;color:#1a1a2e;&quot;&gt;
  &lt;/h1&gt;

  &lt;p&gt;
    Global teams often say, &quot;PMDA and FDA both take SDTM, so one package should work for both.&quot;
    That is only half true.
  &lt;/p&gt;

  &lt;p&gt;
    At the model level, the overlap is real. Both agencies expect CDISC-based submissions,
    SAS XPT v5 transport files, define.xml, and reviewer-facing documentation.
    But the real question is not whether your SDTM is CDISC-compliant.
    The real question is this: will the same study package survive both agencies&#39; rule engines,
    review workflows, and local review habits without late rework?
  &lt;/p&gt;

  &lt;p&gt;
    For teams that build for FDA first, the answer is often no, at least not without adjustment.
    The differences that matter most are not random. They cluster around standards catalog timing,
    PMDA pre-submission consultation, Japanese text handling, clinical pharmacology traceability,
    validation behavior, and Japanese date and time conventions.
  &lt;/p&gt;

  &lt;div style=&quot;background:#fff8e1;border-left:4px solid #f0ad00;padding:14px 16px;margin:24px 0;&quot;&gt;
    &lt;strong&gt;Note:&lt;/strong&gt; Before any real submission, always recheck the active PMDA Technical Conformance Guide,
    validation rules version, and accepted standards catalog on the PMDA site. These can change over time.
  &lt;/div&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    1. The common ground is real, but it is not the hard part
  &lt;/h2&gt;

  &lt;p&gt;
    Both FDA and PMDA anchor clinical study data expectations in CDISC standards.
    Both expect SDTM and ADaM datasets in SAS XPORT Version 5 format.
    Both expect define.xml.
    Both expect reviewer-facing documentation.
  &lt;/p&gt;

  &lt;p&gt;
    That shared base is real, but it does not remove the operational differences.
    The trouble starts in the last mile, where agencies differ in validation behavior,
    local documentation expectations, accepted standards timing, and handling of Japanese source content.
  &lt;/p&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    2. Data standards catalog timing is not handled the same way
  &lt;/h2&gt;

  &lt;p&gt;
    FDA and PMDA both publish accepted standards catalogs, but teams should not assume the timing logic is identical.
    FDA allows older supported standards in ways that are tied to study timing and catalog support windows.
    PMDA is more tightly anchored to what is accepted at the time of submission.
  &lt;/p&gt;

  &lt;p&gt;
    In practice, this means a study that is still acceptable to FDA under an older SDTMIG version may need a closer
    check for PMDA if the PMDA catalog in force at filing no longer lists that version.
    For pooled analyses built from studies that used different versions, PMDA also expects the differences and their
    effect on the integrated package to be explained clearly in the reviewer&#39;s guide.
  &lt;/p&gt;

  &lt;div style=&quot;background:#f7f7f7;border-left:4px solid #2d6cdf;padding:14px 16px;margin:24px 0;&quot;&gt;
    &lt;strong&gt;Programming takeaway:&lt;/strong&gt; Do not lock standards once at study start and assume the question is closed.
    Recheck PMDA standards close to filing.
  &lt;/div&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    3. PMDA pre-submission consultation is a real operational gate
  &lt;/h2&gt;

  &lt;p&gt;
    FDA has meeting options, but PMDA&#39;s data-focused consultation process plays a much bigger role in how the package
    is prepared. In practice, sponsors are expected to go through formal PMDA data consultation before filing.
    This is where dataset structure, validation findings, and unresolved submission issues are discussed before the
    NDA reaches the gateway.
  &lt;/p&gt;

  &lt;p&gt;
    Form A and related consultation materials are not just paperwork.
    They force the sponsor to show what datasets will be submitted, what findings remain, and how each issue will be handled.
    That changes behavior upstream. Teams preparing a PMDA package cannot treat this as an FDA package with a regional note added at the end.
  &lt;/p&gt;

  &lt;div style=&quot;background:#fff3f3;border-left:4px solid #cc2222;padding:14px 16px;margin:24px 0;&quot;&gt;
    &lt;strong&gt;Warning:&lt;/strong&gt; PMDA treats serious validation findings much more aggressively in practice.
    Reject-level findings are generally treated as blocking issues and usually must be fixed before review moves forward.
  &lt;/div&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    4. Japanese text handling is one of the biggest real differences
  &lt;/h2&gt;

  &lt;p&gt;
    This is where many FDA-first teams get caught.
    PMDA allows Japanese data in submission datasets when translation would lose meaning, but it does not do this casually.
    It uses a paired dataset model.
  &lt;/p&gt;

  &lt;p&gt;
    When Japanese text must be preserved, the sponsor may need:
  &lt;/p&gt;

  &lt;ul style=&quot;margin-top:0;padding-left:24px;&quot;&gt;
    &lt;li&gt;a standard alphanumeric dataset in &lt;code&gt;sdtm&lt;/code&gt; or &lt;code&gt;adam&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;a Japanese dataset in &lt;code&gt;sdtm_j&lt;/code&gt; or &lt;code&gt;adam_j&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;the same structure, same variables, same record order, and same record count in both&lt;/li&gt;
    &lt;li&gt;clear explanation in the reviewer&#39;s guide&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;
    The alphanumeric version may use a placeholder such as
    &lt;code&gt;JAPANESE TEXT IN SOURCE DATABASE&lt;/code&gt; where the source value is carried in the Japanese dataset.
    The encoding used for the Japanese dataset also needs to be documented.
  &lt;/p&gt;

  &lt;p&gt;
    FDA has no parallel dataset folder model like this.
    That is one reason a single global SDTM package is often not really single.
  &lt;/p&gt;

  &lt;pre style=&quot;background:#f5f5f5;border-left:4px solid #2d6cdf;padding:14px 16px;overflow:auto;font-size:14px;line-height:1.6;&quot;&gt;
/* Example: basic check before PMDA XPT export */
proc contents data=sdtm.ae;
run;

/* Review character variables and dataset encoding.
   If Japanese text is present and cannot be translated safely,
   plan paired submission datasets and document the handling. */
  &lt;/pre&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    5. Clinical pharmacology submission expectations are tighter
  &lt;/h2&gt;

  &lt;p&gt;
    For clinical pharmacology studies, PMDA expects stronger traceability between concentration data, derived parameters,
    and the analysis path used to produce them.
    In practice, this means the &lt;code&gt;PP&lt;/code&gt; domain is expected alongside &lt;code&gt;PC&lt;/code&gt; for clinical pharmacology work,
    and missing PP content is likely to raise conformance questions.
  &lt;/p&gt;

  &lt;p&gt;
    PMDA also expects clear linkage between PC and PP, typically through RELREC or equivalent documented traceability.
    If RELREC is not used, the reviewer guide should explain how individual parameters can be traced back to the source profile.
  &lt;/p&gt;

  &lt;pre style=&quot;background:#f5f5f5;border-left:4px solid #2d6cdf;padding:14px 16px;overflow:auto;font-size:14px;line-height:1.6;&quot;&gt;
/* Illustrative RELREC concept linking PP back to PC */
/* RDOMAIN   USUBJID   IDVAR   IDVARVAL   RELTYPE   RELID */
/* PP        001-001   PPSEQ   1          ONE       PK01  */
/* PC        001-001   PCSEQ   1 2 3 4    MANY      PK01  */
  &lt;/pre&gt;

  &lt;p&gt;
    For PK and PK/PD work, PMDA also puts more weight on analysis metadata and reproducibility than many FDA-first teams expect.
    This becomes even more visible when population PK or PBPK materials are involved.
  &lt;/p&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    6. PMDA puts more weight on submitted programs and reproducibility
  &lt;/h2&gt;

  &lt;p&gt;
    FDA strongly values SDRG, ADRG, and clean metadata.
    PMDA wants that too, but often goes further on executable traceability.
    The expectation is not just to describe the analysis well.
    The expectation is to make it reproducible enough for review.
  &lt;/p&gt;

  &lt;p&gt;
    For confirmatory studies, PMDA expects the primary analysis program in principle, along with supporting programs
    for ADaM creation and key efficacy, safety, or dose-setting outputs where relevant.
    If the exact program cannot be submitted, the fallback is still a detailed algorithm description, not silence.
  &lt;/p&gt;

  &lt;p&gt;
    This changes how statisticians and programmers should prepare the package.
    A package that feels well documented for FDA can still be weak for PMDA if the derivation chain is hard to reconstruct.
  &lt;/p&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    7. MedDRA/J matters, even though the PT code stays the anchor
  &lt;/h2&gt;

  &lt;p&gt;
    MedDRA/J is the Japanese localization of MedDRA.
    The key point for SDTM work is that the code remains stable, while the label surface may be Japanese.
    That means the safest join point across Japanese and English safety content is the code, not the term label.
  &lt;/p&gt;

  &lt;p&gt;
    For PMDA SDTM submission, variables such as &lt;code&gt;AEDECOD&lt;/code&gt;, &lt;code&gt;AESOC&lt;/code&gt;, &lt;code&gt;AEHLT&lt;/code&gt;,
    and related coded fields should still align with standard MedDRA concepts expected by SDTM.
    If the source or coding activity used Japanese labels, that Japanese content belongs in the paired Japanese dataset
    or related documented handling path.
  &lt;/p&gt;

  &lt;p&gt;
    PMDA is also stricter in wording around controlled terminology use.
    It expects accepted standards, terminology, and dictionaries to be used without changing spelling, notation, or capitalization.
  &lt;/p&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    8. JADER is not an SDTM target, but it still matters
  &lt;/h2&gt;

  &lt;p&gt;
    JADER is PMDA&#39;s post-marketing adverse drug reaction database.
    It is not a clinical SDTM submission target.
    That point needs to stay clean, because people often blur these two ideas.
  &lt;/p&gt;

  &lt;p&gt;
    JADER still matters for advanced programmers and statisticians because teams sometimes need to align or compare
    JADER safety data with internal clinical trial safety data.
    When that happens, the Japanese labeling, MedDRA/J usage, and local safety conventions become part of the mapping problem.
  &lt;/p&gt;

  &lt;table style=&quot;width:100%;border-collapse:collapse;margin:24px 0;font-size:15px;&quot;&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th style=&quot;border:1px solid #ddd;padding:10px;background:#1a1a2e;color:#fff;text-align:left;&quot;&gt;JADER Table&lt;/th&gt;
        &lt;th style=&quot;border:1px solid #ddd;padding:10px;background:#1a1a2e;color:#fff;text-align:left;&quot;&gt;Content&lt;/th&gt;
        &lt;th style=&quot;border:1px solid #ddd;padding:10px;background:#1a1a2e;color:#fff;text-align:left;&quot;&gt;Nearest SDTM Analog&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;DEMO&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Patient demographics, outcome, report details&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;DM, DS&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;DRUG&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Suspected and concomitant drugs&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;CM, EX&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;REAC&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Adverse reactions coded with MedDRA/J&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;AE&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;HIST&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;History / background disease information&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;MH&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;p&gt;
    One practical limitation is age granularity.
    JADER often carries age in grouped bins, not exact age.
    That matters if a team tries to compare JADER signals directly with FAERS or trial data without adjusting the analysis plan.
  &lt;/p&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    9. Japanese date and time handling can quietly break traceability
  &lt;/h2&gt;

  &lt;p&gt;
    SDTM &lt;code&gt;--DTC&lt;/code&gt; variables must still be ISO 8601 for both FDA and PMDA.
    The issue is not the SDTM output format.
    The issue is the source data.
  &lt;/p&gt;

  &lt;p&gt;
    Japanese source systems may contain era-based dates rather than plain Gregorian dates.
    The current era is &lt;strong&gt;Reiwa&lt;/strong&gt; (令和), which began on May 1, 2019.
    The previous era was &lt;strong&gt;Heisei&lt;/strong&gt; (平成), which ran from 1989 to April 30, 2019.
    Before that was &lt;strong&gt;Showa&lt;/strong&gt; (昭和).
  &lt;/p&gt;

  &lt;p&gt;
    So a source date like &lt;code&gt;令和6年3月15日&lt;/code&gt; needs conversion to &lt;code&gt;2024-03-15&lt;/code&gt;.
    A date like &lt;code&gt;平成31年4月30日&lt;/code&gt; converts to &lt;code&gt;2019-04-30&lt;/code&gt;.
    This is not just formatting.
    It is source interpretation and QC.
  &lt;/p&gt;

  &lt;pre style=&quot;background:#f5f5f5;border-left:4px solid #2d6cdf;padding:14px 16px;overflow:auto;font-size:14px;line-height:1.6;&quot;&gt;
/* Era conversion reference */
/* Showa  : 1926-12-25 to 1989-01-07 */
/* Heisei : 1989-01-08 to 2019-04-30 */
/* Reiwa  : 2019-05-01 onward        */

/* Reiwa Year N  = Gregorian Year (2018 + N)  */
/* Heisei Year N = Gregorian Year (1988 + N)  */

/* Example:
   令和6  -&gt; 2024
   平成31 -&gt; 2019
*/
  &lt;/pre&gt;

  &lt;p&gt;
    The 2019 transition window needs extra QC.
    Any site data around the Heisei-to-Reiwa change should be checked carefully before conversion and SDTM derivation.
  &lt;/p&gt;

  &lt;p&gt;
    Time zone also matters.
    Japan Standard Time is UTC+9 and does not use daylight saving time.
    In mixed-region studies, local source time, normalized analysis time, and SDTM submission time should not be treated as the same thing by default.
  &lt;/p&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    10. Validation is not just &quot;run P21 once&quot;
  &lt;/h2&gt;

  &lt;p&gt;
    This is one of the biggest mistakes in dual submissions.
    PMDA uses its own validation rule set within Pinnacle 21 Enterprise.
    FDA-facing validation and PMDA-facing validation are not interchangeable.
  &lt;/p&gt;

  &lt;p&gt;
    The same dataset can behave differently depending on:
  &lt;/p&gt;

  &lt;ul style=&quot;margin-top:0;padding-left:24px;&quot;&gt;
    &lt;li&gt;the rule set in use&lt;/li&gt;
    &lt;li&gt;the engine selected&lt;/li&gt;
    &lt;li&gt;the accepted standards version at filing&lt;/li&gt;
    &lt;li&gt;how each agency handles severity and reviewer explanation&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;
    So &quot;we ran P21&quot; is not enough.
    The real question is, &quot;Which rules, which engine, and for which authority?&quot;
  &lt;/p&gt;

  &lt;div style=&quot;background:#fff3f3;border-left:4px solid #cc2222;padding:14px 16px;margin:24px 0;&quot;&gt;
    &lt;strong&gt;Warning:&lt;/strong&gt; Do not assume an FDA-clean validation report predicts PMDA acceptance.
    PMDA validation planning should be treated as its own workstream.
  &lt;/div&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    11. Controlled terminology drift is handled more tightly on the PMDA side
  &lt;/h2&gt;

  &lt;p&gt;
    Both agencies depend on CDISC controlled terminology, but PMDA&#39;s wording is stricter around exact notation.
    It expects accepted terminology and dictionaries to be used without changing spelling, notation, or capitalization.
  &lt;/p&gt;

  &lt;p&gt;
    This matters in real programming work.
    Old sponsor terms, local lab carryover values, and slightly edited codelist values that may survive longer in FDA-focused workflows
    are more likely to become PMDA review points.
  &lt;/p&gt;

  &lt;p&gt;
    Another practical difference is laboratory terminology.
    FDA reviewers may ask more questions around LOINC alignment.
    PMDA does not place the same visible weight on that point in its SDTM conformance posture.
  &lt;/p&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    12. SEND is still a scope difference
  &lt;/h2&gt;

  &lt;p&gt;
    FDA requires SEND for applicable nonclinical submissions.
    PMDA does not currently require SEND in the same way.
    That is a plain scope difference teams should keep separate from the SDTM conversation.
  &lt;/p&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    Summary table
  &lt;/h2&gt;

  &lt;table style=&quot;width:100%;border-collapse:collapse;margin:24px 0;font-size:15px;&quot;&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th style=&quot;border:1px solid #ddd;padding:10px;background:#1a1a2e;color:#fff;text-align:left;&quot;&gt;Area&lt;/th&gt;
        &lt;th style=&quot;border:1px solid #ddd;padding:10px;background:#1a1a2e;color:#fff;text-align:left;&quot;&gt;FDA&lt;/th&gt;
        &lt;th style=&quot;border:1px solid #ddd;padding:10px;background:#1a1a2e;color:#fff;text-align:left;&quot;&gt;PMDA&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Standards timing&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Tied to supported catalog windows and study timing&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;More tightly tied to standards accepted at submission&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Pre-submission data consultation&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;No direct equivalent gate&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Formal consultation plays a major role before filing&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Japanese text handling&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;English-only submission model&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Paired Japanese and alphanumeric dataset model when needed&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Clinical pharmacology traceability&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Strongly expected, often explained through metadata&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Tighter expectation around PP, linkage, and reproducibility&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Programs and reproducibility&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Reviewer docs emphasized&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Programs and algorithm traceability weigh more heavily&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Validation behavior&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Authority-specific review posture&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Authority-specific rule set with stricter blocking behavior in practice&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Japanese era dates&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Usually not a source issue&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Can require source interpretation and dedicated QC&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;MedDRA localization&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;International MedDRA workflow&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;MedDRA/J context with the code as the stable bridge&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;Post-marketing safety database&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;FAERS&lt;/td&gt;
        &lt;td style=&quot;border:1px solid #ddd;padding:10px;&quot;&gt;JADER&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;h2 style=&quot;font-size:26px;color:#1a1a2e;margin-top:38px;margin-bottom:10px;border-bottom:1px solid #ddd;padding-bottom:6px;&quot;&gt;
    Final point
  &lt;/h2&gt;

  &lt;p&gt;
    FDA and PMDA both accept SDTM.
    That is the easy part.
  &lt;/p&gt;

  &lt;p&gt;
    The hard part is how each agency expects the package to behave in review.
    PMDA is not just FDA with Japanese labels on top.
    It is a different operating environment, with different pressure points.
  &lt;/p&gt;

  &lt;p&gt;
    Teams that do well with PMDA usually make those decisions early, not a few weeks before filing.
  &lt;/p&gt;

  &lt;div style=&quot;margin-top:32px;font-size:13px;color:#666;font-family:Arial, sans-serif;&quot;&gt;
    Tags: PMDA, FDA, SDTM, Define.xml, MedDRA/J, JADER, Clinical Pharmacology, Pinnacle 21, Regulatory Submissions
  &lt;/div&gt;

&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/968227084245683161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/968227084245683161'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/04/pmda-sdtm-submission-requirements-vs.html' title='PMDA SDTM Submission Requirements vs FDA: Where They Actually Diverge'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-7149458382487958212</id><published>2026-04-03T21:18:00.002-04:00</published><updated>2026-04-03T21:18:38.790-04:00</updated><title type='text'>Define.xml for SUPPQUAL — Getting QNAM-Level Metadata Right</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
&lt;style&gt;
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

  body {
    font-family: Georgia, &#39;Times New Roman&#39;, serif;
    font-size: 16px;
    line-height: 1.8;
    color: #2c2c2c;
    background: #fafaf8;
    padding: 40px 20px 80px;
  }

  .container {
    max-width: 820px;
    margin: 0 auto;
  }

  .meta-line {
    font-family: &#39;Courier New&#39;, monospace;
    font-size: 12px;
    color: #888;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    margin-bottom: 28px;
    border-bottom: 1px solid #e0e0e0;
    padding-bottom: 12px;
  }

  h1 {
    font-family: Georgia, serif;
    font-size: 2rem;
    color: #1a1a2e;
    line-height: 1.3;
    margin-bottom: 10px;
    font-weight: bold;
  }

  .subtitle {
    font-size: 1.05rem;
    color: #555;
    margin-bottom: 6px;
    font-style: italic;
  }

  .date {
    font-size: 13px;
    color: #999;
    font-family: &#39;Courier New&#39;, monospace;
    margin-bottom: 36px;
  }

  h2 {
    font-family: Georgia, serif;
    font-size: 1.4rem;
    color: #1a1a2e;
    margin-top: 48px;
    margin-bottom: 14px;
    border-left: 4px solid #0066cc;
    padding-left: 12px;
    font-weight: bold;
  }

  h3 {
    font-family: Georgia, serif;
    font-size: 1.15rem;
    color: #1a1a2e;
    margin-top: 32px;
    margin-bottom: 10px;
    font-weight: bold;
  }

  h4 {
    font-size: 1rem;
    color: #333;
    margin-top: 24px;
    margin-bottom: 8px;
    font-weight: bold;
    font-style: italic;
  }

  p {
    margin-bottom: 18px;
  }

  pre {
    background: #f5f5f5;
    border-left: 4px solid #0066cc;
    padding: 16px 18px;
    font-family: &#39;Courier New&#39;, monospace;
    font-size: 13.5px;
    line-height: 1.55;
    overflow-x: auto;
    white-space: pre-wrap;
    word-break: break-word;
    margin: 22px 0;
    color: #1a1a1a;
  }

  code {
    font-family: &#39;Courier New&#39;, monospace;
    font-size: 13.5px;
    background: #f0f0f0;
    color: #b5432a;
    padding: 1px 5px;
    border-radius: 2px;
  }

  pre code {
    background: none;
    color: inherit;
    padding: 0;
    font-size: inherit;
  }

  .note {
    background: #fff8e1;
    border-left: 4px solid #f9a825;
    padding: 14px 18px;
    margin: 22px 0;
    font-size: 15px;
  }

  .warn {
    background: #fff3f3;
    border-left: 4px solid #cc2222;
    padding: 14px 18px;
    margin: 22px 0;
    font-size: 15px;
  }

  table {
    width: 100%;
    border-collapse: collapse;
    margin: 24px 0;
    font-size: 14.5px;
  }

  thead tr {
    background: #1a1a2e;
    color: #fff;
  }

  thead th {
    padding: 10px 14px;
    text-align: left;
    font-weight: normal;
    letter-spacing: 0.02em;
  }

  tbody tr:nth-child(even) {
    background: #f4f4f4;
  }

  tbody td {
    padding: 9px 14px;
    border-bottom: 1px solid #e0e0e0;
    vertical-align: top;
  }

  .tags {
    margin-top: 60px;
    padding-top: 16px;
    border-top: 1px solid #e0e0e0;
    font-family: &#39;Courier New&#39;, monospace;
    font-size: 12px;
    color: #888;
  }

  .tags span {
    display: inline-block;
    background: #e8edf5;
    color: #1a1a2e;
    padding: 3px 8px;
    margin: 3px 4px 3px 0;
    border-radius: 2px;
  }

  .toc {
    background: #f0f4fb;
    border: 1px solid #c5d3e8;
    padding: 20px 24px;
    margin: 28px 0 40px;
    font-size: 14.5px;
  }

  .toc p {
    font-weight: bold;
    color: #1a1a2e;
    margin-bottom: 10px;
    font-size: 15px;
  }

  .toc ol {
    padding-left: 20px;
    margin-bottom: 0;
  }

  .toc li {
    margin-bottom: 4px;
    line-height: 1.6;
  }

  .toc a {
    color: #0066cc;
    text-decoration: none;
  }

  .toc a:hover {
    text-decoration: underline;
  }

  .rejection-box {
    background: #fff3f3;
    border: 1px solid #e0a0a0;
    padding: 18px 20px;
    margin: 20px 0;
  }

  .rejection-box strong {
    color: #cc2222;
    display: block;
    margin-bottom: 6px;
    font-size: 15px;
  }

  .section-divider {
    border: none;
    border-top: 2px solid #e0e0e0;
    margin: 48px 0 0;
  }

  .xml-comment { color: #669966; }
  .xml-tag     { color: #004080; }
  .xml-attr    { color: #7d3c00; }
  .xml-val     { color: #cc2222; }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;div class=&quot;container&quot;&gt;

  &lt;p&gt;If you have worked on SDTM submissions long enough, you know SUPPQUAL define.xml is where packages start to break down. Not because the data is wrong, but because the metadata does not fully explain what the data represents.&lt;/p&gt;

  &lt;p&gt;This is not a recap of SUPPQUAL structure. This is about how define.xml actually fails in submission and how to fix it before a reviewer points it out.&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;SUPPQUAL is not difficult because of structure. It is difficult because the meaning of the data exists only in define.xml.&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;toc&quot;&gt;
    &lt;p&gt;Table of Contents&lt;/p&gt;
    &lt;ol&gt;
      &lt;li&gt;&lt;a href=&quot;#structure-recap&quot;&gt;The SUPPQUAL ItemGroupDef — What the Spec Actually Requires&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#vlm-concept&quot;&gt;Value-Level Metadata — Why SUPPQUAL Demands It&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#qnam-vlm&quot;&gt;Building QNAM-Level VLM Entries Correctly&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#whereclause&quot;&gt;WhereClauseDef Construction — Mechanics and Traps&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#origin&quot;&gt;Origin Tracing for SUPPQUAL Variables&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#controlled-terms&quot;&gt;Controlled Terminology in SUPPQUAL QVAL — Who Owns the Codelist?&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#rejection-patterns&quot;&gt;Common Submission Rejection Patterns&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#pmda&quot;&gt;PMDA-Specific Considerations&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#sas&quot;&gt;SAS Utility: Generating VLM Entries Programmatically&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#checklist&quot;&gt;Pre-Submission Checklist&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#idvar&quot;&gt;IDVAR / IDVARVAL — The Hidden Failure Point&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#design-decision&quot;&gt;SUPPQUAL vs Custom Domain — Design Decision&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#p21-limits&quot;&gt;What Pinnacle 21 Will NOT Catch&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#scale&quot;&gt;Scaling Problems in Large SUPPQUAL Domains&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#v21&quot;&gt;Define.xml v2.0 vs v2.1 — What Changes for SUPPQUAL&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#edge-cases&quot;&gt;Edge Cases You Will Hit&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#reviewer-model&quot;&gt;How Reviewers Actually Read SUPPQUAL&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#cross-domain&quot;&gt;Cross-Domain Consistency — The Silent Check&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#automation&quot;&gt;Levels of Automation — Maturity Model&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;#bad-good&quot;&gt;Bad vs Good — Full Picture&lt;/a&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/div&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;structure-recap&quot;&gt;1. The SUPPQUAL ItemGroupDef — What the Spec Actually Requires&lt;/h2&gt;

  &lt;p&gt;Start with the foundation. A SUPPQUAL dataset in CDISC SDTM is a special-purpose structure with a fixed set of variables: &lt;code&gt;STUDYID&lt;/code&gt;, &lt;code&gt;RDOMAIN&lt;/code&gt;, &lt;code&gt;USUBJID&lt;/code&gt;, &lt;code&gt;IDVAR&lt;/code&gt;, &lt;code&gt;IDVARVAL&lt;/code&gt;, &lt;code&gt;QNAM&lt;/code&gt;, &lt;code&gt;QLABEL&lt;/code&gt;, and &lt;code&gt;QVAL&lt;/code&gt;. Every SUPPQUAL dataset carries these same column names regardless of what domain it hangs off. That fixed structure is what makes define.xml hard — the column names tell you nothing about what any given row contains.&lt;/p&gt;

  &lt;p&gt;In define.xml (Define-XML v2.0 and v2.1), a SUPPQUAL domain is represented as an &lt;code&gt;ItemGroupDef&lt;/code&gt; whose &lt;code&gt;OID&lt;/code&gt; typically follows &lt;code&gt;IG.SUPPXX&lt;/code&gt; convention. Inside that ItemGroupDef, you declare ItemRefs for the eight structural columns. That part is routine. The complexity begins with &lt;code&gt;QNAM&lt;/code&gt; and &lt;code&gt;QVAL&lt;/code&gt;.&lt;/p&gt;

  &lt;p&gt;The FDA Technical Conformance Guide (TCG), the CDISC Define-XML 2.0 specification, and the CDISC SDTM IG all converge on the same expectation: every distinct QNAM value that appears in the dataset must have a corresponding Value-Level Metadata entry in define.xml. Not a collective entry. Not a reference to the QNAM column generally. Each QNAM individually, with its own label, data type, origin, and — where applicable — codelist or controlled terminology reference.&lt;/p&gt;

  &lt;div class=&quot;warn&quot;&gt;
    &lt;strong&gt;This is the single most common gap in SUPPQUAL define packages.&lt;/strong&gt; Programmers correctly document the column-level metadata for QNAM (type=text, origin=Predecessor, etc.) but never create the value-level entries that tell reviewers what QNAM=&quot;AESLIFE&quot; or QNAM=&quot;LBMETHOD&quot; actually means in context. FDA reviewers are specifically checking for VLM completeness in SUPP-- domains.
  &lt;/div&gt;

  &lt;p&gt;Here is the minimal correct ItemGroupDef structure for a SUPPAE domain:&lt;/p&gt;

&lt;pre&gt;&amp;lt;!-- ItemGroupDef for SUPPAE --&amp;gt;
&amp;lt;def:ItemGroupDef OID=&quot;IG.SUPPAE&quot;
                  Name=&quot;SUPPAE&quot;
                  Repeating=&quot;Yes&quot;
                  IsReferenceData=&quot;No&quot;
                  SASDatasetName=&quot;SUPPAE&quot;
                  def:Structure=&quot;Supplemental Qualifiers for AE&quot;
                  def:Purpose=&quot;Tabulation&quot;
                  def:StandardOID=&quot;STD.SDTMIG.3.3&quot;
                  def:ArchiveLocationID=&quot;LF.SUPPAE&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Supplemental Qualifiers for Adverse Events
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.STUDYID&quot;  OrderNumber=&quot;1&quot;  Mandatory=&quot;Yes&quot;/&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.RDOMAIN&quot;  OrderNumber=&quot;2&quot;  Mandatory=&quot;Yes&quot;/&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.USUBJID&quot;  OrderNumber=&quot;3&quot;  Mandatory=&quot;Yes&quot;/&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.IDVAR&quot;    OrderNumber=&quot;4&quot;  Mandatory=&quot;Yes&quot;/&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.IDVARVAL&quot; OrderNumber=&quot;5&quot;  Mandatory=&quot;Yes&quot;/&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.QNAM&quot;     OrderNumber=&quot;6&quot;  Mandatory=&quot;Yes&quot;
           def:KeySequence=&quot;1&quot;/&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.QLABEL&quot;   OrderNumber=&quot;7&quot;  Mandatory=&quot;Yes&quot;/&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.QVAL&quot;     OrderNumber=&quot;8&quot;  Mandatory=&quot;Yes&quot;/&amp;gt;
  &amp;lt;def:leaf ID=&quot;LF.SUPPAE&quot; xlink:href=&quot;suppae.xpt&quot;&amp;gt;
    &amp;lt;def:title&amp;gt;suppae.xpt&amp;lt;/def:title&amp;gt;
  &amp;lt;/def:leaf&amp;gt;
&amp;lt;/def:ItemGroupDef&amp;gt;&lt;/pre&gt;

  &lt;p&gt;Note &lt;code&gt;def:KeySequence=&quot;1&quot;&lt;/code&gt; on the QNAM ItemRef. This is required to signal to the define viewer that QNAM functions as the discriminator key within this row structure. Some older define packages omit it. Reviewers notice.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;vlm-concept&quot;&gt;2. Value-Level Metadata — Why SUPPQUAL Demands It&lt;/h2&gt;

  &lt;p&gt;Value-Level Metadata (VLM) in define.xml exists to document variables whose meaning is row-dependent. In most SDTM datasets, a column has one meaning. &lt;code&gt;AETERM&lt;/code&gt; always means adverse event term. You document it once at the column level and you are done.&lt;/p&gt;

  &lt;p&gt;SUPPQUAL breaks this. &lt;code&gt;QVAL&lt;/code&gt; can contain a free-text description in one row, a numeric value in another, a controlled term from a codelist in a third. The column-level metadata for QVAL — because it must accommodate everything — is necessarily generic. It cannot tell the reviewer whether &lt;code&gt;QVAL&lt;/code&gt; for &lt;code&gt;QNAM=&quot;AESLIFE&quot;&lt;/code&gt; should be Y/N, whether &lt;code&gt;QVAL&lt;/code&gt; for &lt;code&gt;QNAM=&quot;LBMETHOD&quot;&lt;/code&gt; maps to a codelist, or whether &lt;code&gt;QVAL&lt;/code&gt; for &lt;code&gt;QNAM=&quot;AOCCIFL&quot;&lt;/code&gt; is a character flag with a specific set of permissible values.&lt;/p&gt;

  &lt;p&gt;VLM fixes this. It is the mechanism by which you attach row-specific metadata to a column. In define.xml v2.0/v2.1, VLM is implemented using &lt;code&gt;def:ValueListDef&lt;/code&gt; elements referenced from a &lt;code&gt;def:ValueListRef&lt;/code&gt; attribute on the QVAL ItemDef. Each entry inside the ValueListDef is a separate &lt;code&gt;ItemRef&lt;/code&gt;, constrained by a &lt;code&gt;WhereClauseRef&lt;/code&gt; that scopes it to a specific QNAM value.&lt;/p&gt;

  &lt;div class=&quot;note&quot;&gt;
    &lt;strong&gt;SUPPQUAL Interpretation Flow:&lt;/strong&gt;&lt;br&gt;
    QNAM &amp;nbsp;→&amp;nbsp; WhereClause &amp;nbsp;→&amp;nbsp; VLM ItemDef &amp;nbsp;→&amp;nbsp; Origin / Codelist &amp;nbsp;→&amp;nbsp; Reviewer Understanding&lt;br&gt;&lt;br&gt;
    Every link in this chain must be explicit and correct. A break at any point means the reviewer cannot interpret the variable — and will write a query instead.
  &lt;/div&gt;

  &lt;p&gt;Think of it as a lookup table stitched into the define.xml structure itself. The reviewer opens the define viewer, clicks on QVAL in SUPPAE, and instead of seeing a single generic description, they see a structured list of every QNAM with its own label, type, origin, and optionally a codelist link.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;qnam-vlm&quot;&gt;3. Building QNAM-Level VLM Entries Correctly&lt;/h2&gt;

  &lt;p&gt;The complete VLM implementation for SUPPQUAL requires four interconnected XML components working together. Get any one wrong and the define viewer renders garbage or the validator throws errors.&lt;/p&gt;

  &lt;h3&gt;3.1 The ValueListDef Block&lt;/h3&gt;

  &lt;p&gt;You declare one &lt;code&gt;def:ValueListDef&lt;/code&gt; per SUPPQUAL dataset. Its OID is referenced from the QVAL ItemDef. Inside it, one ItemRef per distinct QNAM value in your dataset.&lt;/p&gt;

&lt;pre&gt;&amp;lt;def:ValueListDef OID=&quot;VL.SUPPAE.QVAL&quot;&amp;gt;

  &amp;lt;!-- Entry for QNAM = AESLIFE --&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.QVAL.AESLIFE&quot;
           OrderNumber=&quot;1&quot;
           Mandatory=&quot;Yes&quot;&amp;gt;
    &amp;lt;def:WhereClauseRef WhereClauseOID=&quot;WC.SUPPAE.QNAM.AESLIFE&quot;/&amp;gt;
  &amp;lt;/ItemRef&amp;gt;

  &amp;lt;!-- Entry for QNAM = AECONTRT --&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.QVAL.AECONTRT&quot;
           OrderNumber=&quot;2&quot;
           Mandatory=&quot;Yes&quot;&amp;gt;
    &amp;lt;def:WhereClauseRef WhereClauseOID=&quot;WC.SUPPAE.QNAM.AECONTRT&quot;/&amp;gt;
  &amp;lt;/ItemRef&amp;gt;

  &amp;lt;!-- Entry for QNAM = AOCCIFL --&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.QVAL.AOCCIFL&quot;
           OrderNumber=&quot;3&quot;
           Mandatory=&quot;No&quot;&amp;gt;
    &amp;lt;def:WhereClauseRef WhereClauseOID=&quot;WC.SUPPAE.QNAM.AOCCIFL&quot;/&amp;gt;
  &amp;lt;/ItemRef&amp;gt;

  &amp;lt;!-- Entry for QNAM = AERELNST --&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.QVAL.AERELNST&quot;
           OrderNumber=&quot;4&quot;
           Mandatory=&quot;No&quot;&amp;gt;
    &amp;lt;def:WhereClauseRef WhereClauseOID=&quot;WC.SUPPAE.QNAM.AERELNST&quot;/&amp;gt;
  &amp;lt;/ItemRef&amp;gt;

&amp;lt;/def:ValueListDef&amp;gt;&lt;/pre&gt;

  &lt;p&gt;The &lt;code&gt;Mandatory&lt;/code&gt; attribute here reflects whether every subject/record that has a parent AE record must have this QNAM populated. This is a clinical judgment, not a programming one. Get input from your data manager.&lt;/p&gt;

  &lt;h3&gt;3.2 The QVAL ItemDef with ValueListRef&lt;/h3&gt;

  &lt;p&gt;The QVAL ItemDef at column level must carry a &lt;code&gt;def:ValueListRef&lt;/code&gt; pointing to your ValueListDef. This is the hook that connects column metadata to value-level metadata.&lt;/p&gt;

&lt;pre&gt;&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL&quot;
         Name=&quot;QVAL&quot;
         DataType=&quot;text&quot;
         Length=&quot;200&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Result Value for the Supplemental Qualifier
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;!-- This is the critical link to VLM --&amp;gt;
  &amp;lt;def:ValueListRef ValueListOID=&quot;VL.SUPPAE.QVAL&quot;/&amp;gt;
&amp;lt;/ItemDef&amp;gt;&lt;/pre&gt;

  &lt;div class=&quot;note&quot;&gt;
    The &lt;code&gt;Length&lt;/code&gt; on the column-level QVAL ItemDef should match the actual XPT variable length. The VLM-level ItemDefs for each QNAM can specify shorter lengths that reflect the actual maximum length for that specific qualifier. FDA reviewers check for length consistency.
  &lt;/div&gt;

  &lt;h3&gt;3.3 The VLM-Level ItemDefs&lt;/h3&gt;

  &lt;p&gt;Each QNAM gets its own ItemDef. This is where the clinical meaning, data type, codelist reference, and origin go. This is the piece that most define packages either skip entirely or populate with placeholder text.&lt;/p&gt;

&lt;pre&gt;&amp;lt;!-- AESLIFE: Life Threatening --&amp;gt;
&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL.AESLIFE&quot;
         Name=&quot;AESLIFE&quot;
         DataType=&quot;text&quot;
         Length=&quot;1&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Indicator of whether the adverse event was life-threatening.
      Populated from the Life-Threatening field on the SAE page.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;CodeListRef CodeListOID=&quot;CL.NY&quot;/&amp;gt;
  &amp;lt;def:Origin Type=&quot;CRF&quot;&amp;gt;
    &amp;lt;def:DocumentRef leafID=&quot;LF.CRF&quot;&amp;gt;
      &amp;lt;def:PDFPageRef Type=&quot;NamedDestination&quot;
                      PageRefs=&quot;AE_SAE_PAGE&quot;/&amp;gt;
    &amp;lt;/def:DocumentRef&amp;gt;
  &amp;lt;/def:Origin&amp;gt;
&amp;lt;/ItemDef&amp;gt;

&amp;lt;!-- AECONTRT: Concomitant Treatment Given --&amp;gt;
&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL.AECONTRT&quot;
         Name=&quot;AECONTRT&quot;
         DataType=&quot;text&quot;
         Length=&quot;1&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Indicator of whether concomitant treatment was given for the AE.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;CodeListRef CodeListOID=&quot;CL.NY&quot;/&amp;gt;
  &amp;lt;def:Origin Type=&quot;CRF&quot;&amp;gt;
    &amp;lt;def:DocumentRef leafID=&quot;LF.CRF&quot;&amp;gt;
      &amp;lt;def:PDFPageRef Type=&quot;NamedDestination&quot;
                      PageRefs=&quot;AE_DETAILS_PAGE&quot;/&amp;gt;
    &amp;lt;/def:DocumentRef&amp;gt;
  &amp;lt;/def:Origin&amp;gt;
&amp;lt;/ItemDef&amp;gt;

&amp;lt;!-- AOCCIFL: Any Occurrence Indicator Flag --&amp;gt;
&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL.AOCCIFL&quot;
         Name=&quot;AOCCIFL&quot;
         DataType=&quot;text&quot;
         Length=&quot;1&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Flag indicating the first occurrence of an AE with the same
      preferred term. Derived based on chronological order within subject.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;CodeListRef CodeListOID=&quot;CL.NY&quot;/&amp;gt;
  &amp;lt;def:Origin Type=&quot;Derived&quot;&amp;gt;
    &amp;lt;def:DocumentRef leafID=&quot;LF.SUPPAE_SPECS&quot;&amp;gt;
      &amp;lt;def:PDFPageRef Type=&quot;NamedDestination&quot;
                      PageRefs=&quot;SUPPAE_DERIVATION&quot;/&amp;gt;
    &amp;lt;/def:DocumentRef&amp;gt;
  &amp;lt;/def:Origin&amp;gt;
&amp;lt;/ItemDef&amp;gt;

&amp;lt;!-- AERELNST: Relationship to Non-Study Treatment --&amp;gt;
&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL.AERELNST&quot;
         Name=&quot;AERELNST&quot;
         DataType=&quot;text&quot;
         Length=&quot;50&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Relationship of the adverse event to a non-study treatment.
      Free text captured on the AE CRF.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;!-- No CodeListRef — free text field --&amp;gt;
  &amp;lt;def:Origin Type=&quot;CRF&quot;&amp;gt;
    &amp;lt;def:DocumentRef leafID=&quot;LF.CRF&quot;&amp;gt;
      &amp;lt;def:PDFPageRef Type=&quot;NamedDestination&quot;
                      PageRefs=&quot;AE_RELATIONSHIP_PAGE&quot;/&amp;gt;
    &amp;lt;/def:DocumentRef&amp;gt;
  &amp;lt;/def:Origin&amp;gt;
&amp;lt;/ItemDef&amp;gt;&lt;/pre&gt;

  &lt;p&gt;Several things to notice here. First, &lt;code&gt;SASFieldName=&quot;QVAL&quot;&lt;/code&gt; on every VLM-level ItemDef. This is correct — the actual XPT variable being described is QVAL regardless of which QNAM you are documenting. Second, the &lt;code&gt;Length&lt;/code&gt; at VLM level reflects the actual maximum length for that qualifier&#39;s values, not the dataset-level QVAL length. Third, the &lt;code&gt;CodeListRef&lt;/code&gt; is present only when the QNAM has controlled values. Free-text QNAMs get no CodeListRef. This distinction matters — a reviewer who sees a codelist reference for a free-text field will flag it.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;whereclause&quot;&gt;4. WhereClauseDef Construction — Mechanics and Traps&lt;/h2&gt;

  &lt;p&gt;The &lt;code&gt;def:WhereClauseDef&lt;/code&gt; is what scopes each VLM entry to its QNAM. It defines the condition &quot;this metadata applies when QNAM equals this value.&quot; Getting WhereClauseDef wrong is the second most common source of define validation errors in SUPPQUAL packages.&lt;/p&gt;

  &lt;h3&gt;4.1 Standard WhereClauseDef Structure&lt;/h3&gt;

&lt;pre&gt;&amp;lt;!-- WhereClause for QNAM = AESLIFE --&amp;gt;
&amp;lt;def:WhereClauseDef OID=&quot;WC.SUPPAE.QNAM.AESLIFE&quot;&amp;gt;
  &amp;lt;RangeCheck Comparator=&quot;EQ&quot;
              SoftHard=&quot;Soft&quot;
              def:ItemOID=&quot;IT.SUPPAE.QNAM&quot;&amp;gt;
    &amp;lt;CheckValue&amp;gt;AESLIFE&amp;lt;/CheckValue&amp;gt;
  &amp;lt;/RangeCheck&amp;gt;
&amp;lt;/def:WhereClauseDef&amp;gt;

&amp;lt;!-- WhereClause for QNAM = AECONTRT --&amp;gt;
&amp;lt;def:WhereClauseDef OID=&quot;WC.SUPPAE.QNAM.AECONTRT&quot;&amp;gt;
  &amp;lt;RangeCheck Comparator=&quot;EQ&quot;
              SoftHard=&quot;Soft&quot;
              def:ItemOID=&quot;IT.SUPPAE.QNAM&quot;&amp;gt;
    &amp;lt;CheckValue&amp;gt;AECONTRT&amp;lt;/CheckValue&amp;gt;
  &amp;lt;/RangeCheck&amp;gt;
&amp;lt;/def:WhereClauseDef&amp;gt;

&amp;lt;!-- WhereClause for QNAM = AOCCIFL --&amp;gt;
&amp;lt;def:WhereClauseDef OID=&quot;WC.SUPPAE.QNAM.AOCCIFL&quot;&amp;gt;
  &amp;lt;RangeCheck Comparator=&quot;EQ&quot;
              SoftHard=&quot;Soft&quot;
              def:ItemOID=&quot;IT.SUPPAE.QNAM&quot;&amp;gt;
    &amp;lt;CheckValue&amp;gt;AOCCIFL&amp;lt;/CheckValue&amp;gt;
  &amp;lt;/RangeCheck&amp;gt;
&amp;lt;/def:WhereClauseDef&amp;gt;&lt;/pre&gt;

  &lt;p&gt;The &lt;code&gt;def:ItemOID&lt;/code&gt; attribute on the RangeCheck must point to the ItemDef for QNAM within the same SUPPQUAL dataset — specifically &lt;code&gt;IT.SUPPAE.QNAM&lt;/code&gt; in this example. Not a generic QNAM OID. Not a cross-domain reference. The OID must resolve to the QNAM column definition within this specific SUPPQUAL domain.&lt;/p&gt;

  &lt;div class=&quot;warn&quot;&gt;
    &lt;strong&gt;Common mistake: reusing WhereClauseDef OIDs across SUPPQUAL domains.&lt;/strong&gt; If you build SUPPAE and SUPPLB and give both the same WC OIDs for shared QNAM names (like QNAM=FAST or QNAM=SPEC), validators will throw duplicate OID errors or silently cross-link the wrong ItemOID references. Every domain needs its own WhereClauseDef set with domain-scoped OIDs and domain-specific ItemOID references.
  &lt;/div&gt;

  &lt;h3&gt;4.2 The SoftHard Attribute&lt;/h3&gt;

  &lt;p&gt;Use &lt;code&gt;SoftHard=&quot;Soft&quot;&lt;/code&gt; for SUPPQUAL WhereClause entries. A &lt;code&gt;Hard&lt;/code&gt; constraint implies the data should fail a range check if the condition is violated. In a SUPP context the WhereClause is not a validation rule — it is a scoping filter. Soft is correct. Some define generators default to Hard. Check your output.&lt;/p&gt;

  &lt;h3&gt;4.3 Case Sensitivity in CheckValue&lt;/h3&gt;

  &lt;p&gt;The value inside &lt;code&gt;&amp;lt;CheckValue&amp;gt;&lt;/code&gt; must match the actual QNAM values in the XPT exactly, including case. SAS XPT is case-preserving for character values. If your dataset has QNAM=&quot;AESlife&quot; in even one row and your WhereClauseDef has &lt;code&gt;&amp;lt;CheckValue&amp;gt;AESLIFE&amp;lt;/CheckValue&amp;gt;&lt;/code&gt;, the VLM entry will not resolve for those rows and Pinnacle 21 will flag the mismatch. Validate against the actual unique QNAM values in your dataset before finalizing define.xml.&lt;/p&gt;

  &lt;h3&gt;4.4 Multi-Condition WhereClause (Rare but Real)&lt;/h3&gt;

  &lt;p&gt;Occasionally a qualifier&#39;s meaning changes depending on the parent IDVAR. If QNAM=&quot;VISIT&quot; behaves differently when IDVAR=&quot;AESEQ&quot; versus IDVAR=&quot;MHSEQ&quot; — which should not happen in well-designed SDTM but does happen in rescue mapping situations — you can build a multi-condition WhereClause:&lt;/p&gt;

&lt;pre&gt;&amp;lt;def:WhereClauseDef OID=&quot;WC.SUPPAE.QNAM.VISIT.AESEQ&quot;&amp;gt;
  &amp;lt;RangeCheck Comparator=&quot;EQ&quot;
              SoftHard=&quot;Soft&quot;
              def:ItemOID=&quot;IT.SUPPAE.QNAM&quot;&amp;gt;
    &amp;lt;CheckValue&amp;gt;VISIT&amp;lt;/CheckValue&amp;gt;
  &amp;lt;/RangeCheck&amp;gt;
  &amp;lt;RangeCheck Comparator=&quot;EQ&quot;
              SoftHard=&quot;Soft&quot;
              def:ItemOID=&quot;IT.SUPPAE.IDVAR&quot;&amp;gt;
    &amp;lt;CheckValue&amp;gt;AESEQ&amp;lt;/CheckValue&amp;gt;
  &amp;lt;/RangeCheck&amp;gt;
&amp;lt;/def:WhereClauseDef&amp;gt;&lt;/pre&gt;

  &lt;p&gt;Multiple RangeCheck elements inside one WhereClauseDef are evaluated as AND conditions by the Define-XML specification. Use this sparingly. If you find yourself doing this frequently, it is usually a sign that the SUPPQUAL design itself needs revisiting before worrying about the define.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;origin&quot;&gt;5. Origin Tracing for SUPPQUAL Variables&lt;/h2&gt;

  &lt;p&gt;Origin documentation for SUPPQUAL is where the real intellectual work lives. It is also where most packages cut corners. Regulatory reviewers — particularly FDA and PMDA — are increasingly using define.xml as an audit instrument, not just a reference document. The origin chain must be defensible.&lt;/p&gt;

  &lt;h3&gt;5.1 The Define-XML Origin Types and What They Mean in SUPPQUAL Context&lt;/h3&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;Origin Type&lt;/th&gt;
        &lt;th&gt;When to Use in SUPPQUAL&lt;/th&gt;
        &lt;th&gt;What Reviewers Expect&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;CRF&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;QVAL is directly transcribed from a CRF field&lt;/td&gt;
        &lt;td&gt;PDF page reference pointing to the exact CRF question. NamedDestination preferred over page numbers.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;Derived&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;QVAL is computed from other data (flags, first-occurrence logic, duration calculations)&lt;/td&gt;
        &lt;td&gt;Reference to derivation specs or annotated CRF note explaining the logic. Reviewers want to see the method, not just &quot;Derived.&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;Assigned&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;QVAL comes from a sponsor-assigned value not captured on a CRF (study day calculations, batch assignments)&lt;/td&gt;
        &lt;td&gt;Some reference to the assigning entity or protocol specification.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;Predecessor&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;QVAL is carried over or transformed from a prior dataset or CDASH mapping — use with caution in SUPPQUAL&lt;/td&gt;
        &lt;td&gt;The predecessor source should be traceable. Generic &quot;Predecessor&quot; with no document reference is not acceptable in modern submissions.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;code&gt;Protocol&lt;/code&gt;&lt;/td&gt;
        &lt;td&gt;QVAL represents a protocol-defined classification not captured explicitly in the CRF&lt;/td&gt;
        &lt;td&gt;Reference to specific protocol section or amendment.&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;h3&gt;5.2 CRF Origin — Getting the PDFPageRef Right&lt;/h3&gt;

  &lt;p&gt;The most common origin in SUPPQUAL is CRF. The structure requires a DocumentRef pointing to the annotated CRF leaf, with a PDFPageRef specifying where in the CRF the field appears.&lt;/p&gt;

&lt;pre&gt;&amp;lt;def:Origin Type=&quot;CRF&quot;&amp;gt;
  &amp;lt;def:DocumentRef leafID=&quot;LF.ACRF&quot;&amp;gt;
    &amp;lt;def:PDFPageRef
      Type=&quot;NamedDestination&quot;
      PageRefs=&quot;AE_PAGE_SAE_CRITERIA&quot;/&amp;gt;
  &amp;lt;/def:DocumentRef&amp;gt;
&amp;lt;/def:Origin&amp;gt;&lt;/pre&gt;

  &lt;p&gt;The &lt;code&gt;Type&lt;/code&gt; on PDFPageRef should be &lt;code&gt;NamedDestination&lt;/code&gt; if your annotated CRF has named bookmark anchors, or &lt;code&gt;PhysicalPage&lt;/code&gt; if you are using page numbers. Named destinations are more stable across CRF revisions. If your CRF authoring tool supports it, insist on named destinations. Physical page numbers shift whenever a CRF page is added or removed, and a define.xml built against page numbers becomes inaccurate with each CRF version increment.&lt;/p&gt;

  &lt;p&gt;The &lt;code&gt;leafID&lt;/code&gt; must match the &lt;code&gt;ID&lt;/code&gt; attribute of a &lt;code&gt;def:leaf&lt;/code&gt; element declared elsewhere in your define.xml. That leaf must point to a document that actually exists in the submission package. Broken leaf references fail define validation. Cross-check the leaf IDs against your actual eSub folder structure before finalizing.&lt;/p&gt;

  &lt;h3&gt;5.3 Derived Origin — Giving Reviewers Enough Information&lt;/h3&gt;

  &lt;p&gt;Derived QNAMs are the hardest to document well. The spec says to include a DocumentRef, but many programmers point to a general specifications document rather than the specific derivation. This is a missed opportunity.&lt;/p&gt;

  &lt;p&gt;The minimum acceptable Derived origin documentation in 2024+ submissions includes: a reference document that describes the derivation logic, a page or named anchor within that document that shows the specific algorithm, and — where the derivation is non-trivial — a Description element on the ItemDef that explains the method in enough plain language that a reviewer can understand it without opening the spec document.&lt;/p&gt;

&lt;pre&gt;&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL.AOCCIFL&quot;
         Name=&quot;AOCCIFL&quot;
         DataType=&quot;text&quot;
         Length=&quot;1&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Any occurrence indicator flag. Set to &#39;Y&#39; for the first chronological
      occurrence of an AE preferred term within a subject, based on AESTDTC
      ascending, then AESEQ ascending. All subsequent occurrences of the same
      preferred term for the same subject are left blank.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;def:Origin Type=&quot;Derived&quot;&amp;gt;
    &amp;lt;def:DocumentRef leafID=&quot;LF.SDTM_SPECS&quot;&amp;gt;
      &amp;lt;def:PDFPageRef Type=&quot;NamedDestination&quot;
                      PageRefs=&quot;SUPPAE_AOCCIFL_DERIVATION&quot;/&amp;gt;
    &amp;lt;/def:DocumentRef&amp;gt;
  &amp;lt;/def:Origin&amp;gt;
&amp;lt;/ItemDef&amp;gt;&lt;/pre&gt;

  &lt;p&gt;Notice that the Description element does the work. The DocumentRef points a reviewer to the formal specs. But the description alone is enough for a reviewer to validate the derivation without opening anything. That is the standard to aim for.&lt;/p&gt;

  &lt;h3&gt;5.4 The Structural Variable Origin Problem&lt;/h3&gt;

  &lt;p&gt;RDOMAIN, IDVAR, IDVARVAL, QLABEL — these structural SUPPQUAL variables trip up many define packages. Their origin is technically Assigned or Derived in most implementations, because they are constructed by the programmer rather than collected on a CRF. But they are not user-facing clinical data in the same way QVAL is. Many programmers leave them as Predecessor or assign them a generic &quot;Assigned&quot; without further documentation.&lt;/p&gt;

  &lt;p&gt;The FDA TCG expectation is that IDVAR and IDVARVAL have clear origin documentation that explains which variable in the parent domain they reference. A note in the Description element for IDVAR stating &quot;Contains the name of the key variable in the parent AE domain used to link supplemental records. Populated with &#39;AESEQ&#39;&quot; is significantly better than a bare Assigned origin.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;controlled-terms&quot;&gt;6. Controlled Terminology in SUPPQUAL QVAL — Who Owns the Codelist?&lt;/h2&gt;

  &lt;p&gt;When a QNAM takes values from a controlled terminology, the VLM-level ItemDef for that QNAM should carry a &lt;code&gt;CodeListRef&lt;/code&gt;. The question is: which codelist, and where is it defined?&lt;/p&gt;

  &lt;h3&gt;6.1 CDISC Standard Codelists&lt;/h3&gt;

  &lt;p&gt;Most Y/N flags in SUPPQUAL map to the CDISC NY codelist. Reference it exactly as you would from any other domain. The CodeListDef for NY goes in the global CodeLists section of your define.xml, not inside the SUPPQUAL section.&lt;/p&gt;

&lt;pre&gt;&amp;lt;!-- In the CodeLists section of define.xml --&amp;gt;
&amp;lt;CodeList OID=&quot;CL.NY&quot;
          Name=&quot;No Yes Response&quot;
          DataType=&quot;text&quot;
          def:StandardOID=&quot;STD.CT.2024-09-27&quot;&amp;gt;
  &amp;lt;ExternalCodeList
    Dictionary=&quot;NCI&quot;
    Version=&quot;2024-09-27&quot;
    ref=&quot;C66742&quot;/&amp;gt;
&amp;lt;/CodeList&amp;gt;&lt;/pre&gt;

&lt;pre&gt;&amp;lt;!-- In the VLM ItemDef --&amp;gt;
&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL.AESLIFE&quot; ...&amp;gt;
  ...
  &amp;lt;CodeListRef CodeListOID=&quot;CL.NY&quot;/&amp;gt;
&amp;lt;/ItemDef&amp;gt;&lt;/pre&gt;

  &lt;h3&gt;6.2 Sponsor-Defined Codelists for SUPPQUAL&lt;/h3&gt;

  &lt;p&gt;Some QNAMs have permissible values that are sponsor-defined — not from CDISC terminology. A common example is a dose escalation category or a protocol-specific severity classification that appears as a supplemental qualifier. For these, you define a local CodeList with a clear naming convention and mark it appropriately.&lt;/p&gt;

&lt;pre&gt;&amp;lt;CodeList OID=&quot;CL.SUPPAE.AESCATYP&quot;
          Name=&quot;AE Categorization Type&quot;
          DataType=&quot;text&quot;&amp;gt;
  &amp;lt;EnumeratedItem CodedValue=&quot;INFUSION RELATED&quot;
                  def:ExtendedValue=&quot;No&quot;/&amp;gt;
  &amp;lt;EnumeratedItem CodedValue=&quot;HYPERSENSITIVITY&quot;
                  def:ExtendedValue=&quot;No&quot;/&amp;gt;
  &amp;lt;EnumeratedItem CodedValue=&quot;CRS&quot;
                  def:ExtendedValue=&quot;No&quot;/&amp;gt;
&amp;lt;/CodeList&amp;gt;&lt;/pre&gt;

  &lt;div class=&quot;note&quot;&gt;
    For sponsor-defined codelists, use &lt;code&gt;def:ExtendedValue=&quot;No&quot;&lt;/code&gt; on each EnumeratedItem to indicate these are the complete permissible values and not extensions of an external dictionary. If your codelist extends a CDISC codelist by adding sponsor-specific terms, use &lt;code&gt;def:ExtendedValue=&quot;Yes&quot;&lt;/code&gt; on the added items and reference the parent standard codelist via ExternalCodeList.
  &lt;/div&gt;

  &lt;h3&gt;6.3 QNAMs That Should Not Have a Codelist&lt;/h3&gt;

  &lt;p&gt;Free-text QNAMs — verbatim descriptions, reason fields, comment fields — must not carry a CodeListRef. This sounds obvious, but a common error occurs when a programmer builds a template from an existing QNAM that does have a codelist and forgets to strip the CodeListRef when adding a free-text QNAM. The result is a define.xml that claims a free-text field has controlled permissible values, which Pinnacle 21 will flag as a terminology inconsistency and which FDA reviewers will question.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;rejection-patterns&quot;&gt;7. Common Submission Rejection Patterns&lt;/h2&gt;

  &lt;p&gt;These are patterns drawn from actual FDA and EMEA reviewer feedback letters and study data validation report (SDVR) findings. They cluster into five categories.&lt;/p&gt;

  &lt;h3&gt;7.1 Missing VLM for One or More QNAMs&lt;/h3&gt;

  &lt;div class=&quot;rejection-box&quot;&gt;
    &lt;strong&gt;Rejection Pattern: &quot;Value-level metadata not provided for QNAM values [list]. Each unique QNAM in SUPP-- datasets must have corresponding VLM entries in define.xml.&quot;&lt;/strong&gt;
    This is the most frequent finding. It usually happens when a QNAM is added late in the study lifecycle — a new flag requested by biostatistics after the define package was already built — and the VLM entry is either forgotten or added only to the dataset without updating define.xml.
  &lt;/div&gt;

  &lt;p&gt;Prevention: Your define.xml build process should include a programmatic check that compares the unique QNAM values in each production SUPP XPT against the WhereClauseDef CheckValues in the corresponding ValueListDef. Any QNAM in the dataset with no matching WhereClause is a define gap. Run this check as part of your define QC program, not as a manual step.&lt;/p&gt;

&lt;pre&gt;/* SAS: Check for QNAMs missing from VLM */
/* Assumes you have parsed define.xml WhereClause values into
   a dataset called vlm_qnams with fields: domain, qnam_value */

proc sql;
  create table missing_vlm as
  select distinct a.rdomain,
                  a.qnam,
                  &quot;No VLM entry in define.xml&quot; as issue
  from suppae a
  left join vlm_qnams b
    on upcase(a.qnam) = upcase(b.qnam_value)
    and b.domain = &#39;SUPPAE&#39;
  where b.qnam_value is null;
quit;

proc print data=missing_vlm noobs; run;&lt;/pre&gt;

  &lt;h3&gt;7.2 QNAM Values in Dataset Do Not Match CheckValue in WhereClauseDef&lt;/h3&gt;

  &lt;div class=&quot;rejection-box&quot;&gt;
    &lt;strong&gt;Rejection Pattern: &quot;WhereClause condition for [DOMAIN].QNAM EQ [value] does not match observed QNAM values in dataset. Observed: [AEOSPTA], WhereClause: [AEOSTPA].&quot;&lt;/strong&gt;
    This is a typo problem, pure and simple. The QNAM name in the CheckValue element is not identical to the QNAM string in the XPT. Usually a transposition error or a case mismatch discovered after the fact.
  &lt;/div&gt;

  &lt;p&gt;Prevention: Never hand-type QNAM values into WhereClauseDef CheckValue elements. Generate them programmatically from the dataset itself, or at minimum diff your define.xml CheckValues against a proc freq output of the actual dataset QNAMs.&lt;/p&gt;

  &lt;h3&gt;7.3 Origin Type &quot;CRF&quot; with No PDFPageRef or Broken LeafID&lt;/h3&gt;

  &lt;div class=&quot;rejection-box&quot;&gt;
    &lt;strong&gt;Rejection Pattern: &quot;Origin Type=CRF specified for [QNAM] but no CRF page reference provided. Unable to locate source question in annotated CRF.&quot;&lt;/strong&gt;
    The origin says CRF but either the DocumentRef is missing, the leafID does not resolve, or the PDFPageRef points to a named destination that does not exist in the annotated CRF PDF.
  &lt;/div&gt;

  &lt;p&gt;Prevention: Validate all leafIDs against actual files present in the submission package. Validate all NamedDestination values against the bookmarks/destinations actually present in the CRF PDF. Both are scriptable checks — PDF bookmark extraction via Python or a SAS DDE/shell call is straightforward and should be part of your define QC process.&lt;/p&gt;

  &lt;h3&gt;7.4 Derived QNAMs with No Explanation of Derivation Logic&lt;/h3&gt;

  &lt;div class=&quot;rejection-box&quot;&gt;
    &lt;strong&gt;Rejection Pattern: &quot;Origin Type=Derived specified for [QNAM] but derivation logic not documented in define.xml or referenced specifications. Please provide the algorithm used to derive this variable.&quot;&lt;/strong&gt;
    The define says Derived, the DocumentRef points to a general specs document, but there is no specific derivation description anywhere accessible to the reviewer.
  &lt;/div&gt;

  &lt;p&gt;Prevention: For every Derived QNAM, the Description element on the VLM ItemDef should contain enough information that a reviewer can understand the derivation method without opening a separate document. The DocumentRef is supplementary, not a replacement for the in-line description.&lt;/p&gt;

  &lt;h3&gt;7.5 Inconsistent Length Between Column-Level and VLM-Level ItemDef&lt;/h3&gt;

  &lt;div class=&quot;rejection-box&quot;&gt;
    &lt;strong&gt;Rejection Pattern: &quot;VLM-level Length for QNAM=[value] exceeds column-level Length for QVAL. VLM Length should not exceed parent column length.&quot;&lt;/strong&gt;
    The column-level QVAL ItemDef declares Length=200, but a specific VLM ItemDef for one QNAM declares Length=250. This is internally inconsistent — a VLM entry cannot describe data that is longer than the column that contains it.
  &lt;/div&gt;

  &lt;p&gt;Prevention: VLM-level lengths should always be less than or equal to the column-level length for QVAL. In practice, column-level QVAL length should match the XPT variable length, and VLM lengths should reflect the actual maximum observed length for each QNAM&#39;s values. Run &lt;code&gt;proc contents&lt;/code&gt; and &lt;code&gt;proc means maxdec=0&lt;/code&gt; on QVAL grouped by QNAM to determine appropriate VLM lengths.&lt;/p&gt;

&lt;pre&gt;/* Get max QVAL length by QNAM for length documentation */
proc sql;
  create table qval_lengths as
  select rdomain,
         qnam,
         max(length(strip(qval))) as max_qval_length
  from suppae
  group by rdomain, qnam
  order by rdomain, qnam;
quit;

proc print data=qval_lengths noobs label;
  label max_qval_length = &quot;Max QVAL Length&quot;;
run;&lt;/pre&gt;

  &lt;h3&gt;7.6 QLABEL in Define.xml Does Not Match Actual QLABEL Values in Dataset&lt;/h3&gt;

  &lt;div class=&quot;rejection-box&quot;&gt;
    &lt;strong&gt;Rejection Pattern: &quot;Label documented in define.xml Description element for QNAM=[value] does not match QLABEL observed in dataset. Define: &#39;Life Threatening Event&#39;, Dataset: &#39;Life-Threatening&#39;.&quot;&lt;/strong&gt;
    QLABEL is a character variable in the SUPPQUAL dataset. Its value must be consistent across all rows for a given QNAM, and the Description on the corresponding VLM ItemDef must reflect this label accurately.
  &lt;/div&gt;

  &lt;p&gt;The QLABEL in your dataset is the authoritative source. Your define.xml Description element for each QNAM VLM entry should use the same phrasing. If QLABEL=&quot;Life-Threatening&quot; in the dataset, the VLM Description should say &quot;Life-Threatening&quot; in its label description, not a longer or differently punctuated form. FDA reviewers do exact text comparisons between define.xml and dataset values in SDVR tooling.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;pmda&quot;&gt;8. PMDA-Specific Considerations&lt;/h2&gt;

  &lt;p&gt;PMDA submissions add layers beyond FDA requirements. If you are delivering a Japan package, several SUPPQUAL define.xml behaviors require specific attention.&lt;/p&gt;

  &lt;h3&gt;8.1 Bilingual Descriptions&lt;/h3&gt;

  &lt;p&gt;PMDA increasingly expects Japanese-language TranslatedText elements alongside English descriptions, particularly for VLM ItemDefs in SUPPQUAL. This applies to the Description element. Using a single &lt;code&gt;xml:lang=&quot;en&quot;&lt;/code&gt; element is technically valid per the schema but draws reviewer queries in Japan submissions. The correct pattern:&lt;/p&gt;

&lt;pre&gt;&amp;lt;Description&amp;gt;
  &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
    Indicator of whether the adverse event was life-threatening.
  &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;TranslatedText xml:lang=&quot;ja&quot;&amp;gt;
    有害事象が生命を脅かすものであったかどうかを示す指標。
  &amp;lt;/TranslatedText&amp;gt;
&amp;lt;/Description&amp;gt;&lt;/pre&gt;

  &lt;p&gt;If you do not have translation resources, at minimum ensure the English description is precise enough that a Japanese reviewer using machine translation can derive accurate meaning. Ambiguous English descriptions compounded by imperfect machine translation is a known source of PMDA reviewer queries.&lt;/p&gt;

  &lt;h3&gt;8.2 PMDA Requires QNAM-Level Variable Metadata in the Data Definition Document&lt;/h3&gt;

  &lt;p&gt;PMDA validation checklists specifically call out that SUPPQUAL QNAM values should be documented as variables in the data definition document (essentially define.xml) with labels and derivation rules equivalent to how named variables are documented in non-SUPP domains. Their reviewers check this against the SDTM datasets using their own tooling.&lt;/p&gt;

  &lt;h3&gt;8.3 Encoding and Character Width in QLABEL&lt;/h3&gt;

  &lt;p&gt;PMDA submissions often involve Japanese character data in non-SUPP domains but QLABEL in SUPPQUAL is almost always ASCII English. However, if your submission includes Japanese QLABEL values, verify that the XPT character encoding documentation in define.xml (via the &lt;code&gt;def:CommentDef&lt;/code&gt; mechanism or a dedicated annotation) explicitly acknowledges the encoding. PMDA has flagged submissions where the define.xml implied ASCII-only encoding but the dataset contained multi-byte characters.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;sas&quot;&gt;9. SAS Utility: Generating VLM Entries Programmatically&lt;/h2&gt;

  &lt;p&gt;Manually authoring VLM entries for large SUPPQUAL domains — SUPPCM with 20+ QNAMs, SUPPLB with method and specimen qualifiers — is error-prone and time-consuming. Build a generation utility that takes a metadata specs dataset as input and outputs the XML fragments for ValueListDef, WhereClauseDef, and ItemDef elements.&lt;/p&gt;

  &lt;h3&gt;9.1 Input Metadata Dataset Structure&lt;/h3&gt;

&lt;pre&gt;/* Define the metadata specs dataset for SUPPQUAL VLM generation */
/* One row per unique QNAM per SUPPQUAL domain */

data suppqual_vlm_specs;
  length domain    $8
         qnam      $8
         qlabel    $40
         datatype  $10
         length_    8
         origin    $20
         codelist  $40
         crf_dest  $80
         derivation_text $500;
  infile cards dsd;
  input domain $ qnam $ qlabel $ datatype $ length_
        origin $ codelist $ crf_dest $ derivation_text $;
cards;
SUPPAE,AESLIFE,Life-Threatening,text,1,CRF,CL.NY,AE_SAE_PAGE,.
SUPPAE,AECONTRT,Concomitant Treatment Given,text,1,CRF,CL.NY,AE_DETAILS_PAGE,.
SUPPAE,AOCCIFL,Any Occurrence Indicator Flag,text,1,Derived,CL.NY,.,Flag for first occurrence by PT within subject based on AESTDTC ascending
SUPPAE,AERELNST,Relationship to Non-Study Therapy,text,50,CRF,..,AE_RELATIONSHIP_PAGE,.
;
run;&lt;/pre&gt;

  &lt;h3&gt;9.2 XML Generation Macro&lt;/h3&gt;

&lt;pre&gt;%macro gen_supp_vlm(domain=, specs_ds=, outfile=);

  /* Step 1: Get unique QNAMs ordered by sequence */
  proc sort data=&amp;amp;specs_ds.(where=(domain=&quot;&amp;amp;domain.&quot;))
            out=_specs;
    by domain qnam;
  run;

  filename vlm_out &quot;&amp;amp;outfile.&quot;;
  data _null_;
    file vlm_out lrecl=32767;

    /* ValueListDef opening tag */
    put &quot;&amp;lt;def:ValueListDef OID=&quot;&quot;VL.&amp;amp;domain..QVAL&quot;&quot;&amp;gt;&quot;;

    set _specs end=last;
    by domain;

    seq + 1;

    /* ItemRef within ValueListDef */
    put &#39;  &amp;lt;ItemRef ItemOID=&quot;IT.&#39; domain +(-1) &#39;.QVAL.&#39; qnam +(-1) &#39;&quot;&#39;;
    put &#39;           OrderNumber=&quot;&#39; seq +(-1) &#39;&quot;&#39;;
    put &#39;           Mandatory=&quot;Yes&quot;&amp;gt;&#39;;
    put &#39;    &amp;lt;def:WhereClauseRef WhereClauseOID=&quot;WC.&#39; domain +(-1) &#39;.QNAM.&#39; qnam +(-1) &#39;&quot;/&amp;gt;&#39;;
    put &#39;  &amp;lt;/ItemRef&amp;gt;&#39;;

    if last then put &quot;&amp;lt;/def:ValueListDef&amp;gt;&quot;;
  run;

  /* Step 2: WhereClauseDefs */
  data _null_;
    file vlm_out lrecl=32767 mod;
    set _specs;

    put &#39;&amp;lt;def:WhereClauseDef OID=&quot;WC.&#39; domain +(-1) &#39;.QNAM.&#39; qnam +(-1) &#39;&quot;&amp;gt;&#39;;
    put &#39;  &amp;lt;RangeCheck Comparator=&quot;EQ&quot; SoftHard=&quot;Soft&quot;&#39;;
    put &#39;              def:ItemOID=&quot;IT.&#39; domain +(-1) &#39;.QNAM&quot;&amp;gt;&#39;;
    put &#39;    &amp;lt;CheckValue&amp;gt;&#39; qnam +(-1) &#39;&amp;lt;/CheckValue&amp;gt;&#39;;
    put &#39;  &amp;lt;/RangeCheck&amp;gt;&#39;;
    put &#39;&amp;lt;/def:WhereClauseDef&amp;gt;&#39;;
  run;

  /* Step 3: VLM-level ItemDefs */
  data _null_;
    file vlm_out lrecl=32767 mod;
    set _specs;

    put &#39;&amp;lt;ItemDef OID=&quot;IT.&#39; domain +(-1) &#39;.QVAL.&#39; qnam +(-1) &#39;&quot;&#39;;
    put &#39;         Name=&quot;&#39; qnam +(-1) &#39;&quot;&#39;;
    put &#39;         DataType=&quot;&#39; datatype +(-1) &#39;&quot;&#39;;
    put &#39;         Length=&quot;&#39; length_ +(-1) &#39;&quot;&#39;;
    put &#39;         SASFieldName=&quot;QVAL&quot;&amp;gt;&#39;;
    put &#39;  &amp;lt;Description&amp;gt;&#39;;
    put &#39;    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;&#39; qlabel +(-1) &#39;&amp;lt;/TranslatedText&amp;gt;&#39;;
    put &#39;  &amp;lt;/Description&amp;gt;&#39;;

    if codelist ne &#39;.&#39; then
      put &#39;  &amp;lt;CodeListRef CodeListOID=&quot;&#39; codelist +(-1) &#39;&quot;/&amp;gt;&#39;;

    if origin = &#39;CRF&#39; then do;
      put &#39;  &amp;lt;def:Origin Type=&quot;CRF&quot;&amp;gt;&#39;;
      put &#39;    &amp;lt;def:DocumentRef leafID=&quot;LF.ACRF&quot;&amp;gt;&#39;;
      put &#39;      &amp;lt;def:PDFPageRef Type=&quot;NamedDestination&quot; PageRefs=&quot;&#39;
          crf_dest +(-1) &#39;&quot;/&amp;gt;&#39;;
      put &#39;    &amp;lt;/def:DocumentRef&amp;gt;&#39;;
      put &#39;  &amp;lt;/def:Origin&amp;gt;&#39;;
    end;
    else if origin = &#39;Derived&#39; then do;
      put &#39;  &amp;lt;def:Origin Type=&quot;Derived&quot;&amp;gt;&#39;;
      put &#39;    &amp;lt;def:DocumentRef leafID=&quot;LF.SDTM_SPECS&quot;/&amp;gt;&#39;;
      put &#39;  &amp;lt;/def:Origin&amp;gt;&#39;;
    end;

    put &#39;&amp;lt;/ItemDef&amp;gt;&#39;;
  run;

  filename vlm_out clear;
%mend gen_supp_vlm;

/* Usage */
%gen_supp_vlm(
  domain   = SUPPAE,
  specs_ds = suppqual_vlm_specs,
  outfile  = /path/to/suppae_vlm_fragments.xml
);&lt;/pre&gt;

  &lt;p&gt;This is a skeleton macro. In production, extend it to handle: multi-part derivation text with proper XML escaping, structured DocumentRef with PDFPageRef per QNAM rather than a generic leaf, and character escaping for XML special characters in description text (&lt;code&gt;&amp;amp;&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, &lt;code&gt;&amp;gt;&lt;/code&gt;). Use &lt;code&gt;tranwrd()&lt;/code&gt; chains or a dedicated XML-escape function before writing to file.&lt;/p&gt;

  &lt;h3&gt;9.3 Validating the Output&lt;/h3&gt;

  &lt;p&gt;After generating XML fragments and integrating them into your define.xml, validate using at minimum two tools: Pinnacle 21 Community Edition (or Enterprise if your organization has it) and the CDISC Define-XML validator at define.cdisc.org. These tools catch different classes of errors. Pinnacle 21 focuses on clinical data consistency; the CDISC validator focuses on schema conformance. Run both before any submission.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;checklist&quot;&gt;10. Pre-Submission Checklist for SUPPQUAL Define.xml&lt;/h2&gt;

  &lt;p&gt;Before any define package leaves your desk for submission, verify each of the following. This is not a generic checklist — every item here maps directly to a rejection pattern seen in actual submissions.&lt;/p&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th style=&quot;width:5%&quot;&gt;#&lt;/th&gt;
        &lt;th style=&quot;width:55%&quot;&gt;Check&lt;/th&gt;
        &lt;th style=&quot;width:40%&quot;&gt;How to Verify&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;1&lt;/td&gt;
        &lt;td&gt;Every unique QNAM in the XPT has a corresponding WhereClauseDef with matching CheckValue (exact case, exact string)&lt;/td&gt;
        &lt;td&gt;Programmatic diff of proc freq(QNAM) vs CheckValue elements in define.xml&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;2&lt;/td&gt;
        &lt;td&gt;Every QNAM WhereClauseRef resolves to a defined WhereClauseDef OID&lt;/td&gt;
        &lt;td&gt;XML validation; Pinnacle 21 will flag unresolved OIDs&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;3&lt;/td&gt;
        &lt;td&gt;VLM QVAL ItemDef length ≤ column-level QVAL ItemDef length ≤ XPT QVAL variable length&lt;/td&gt;
        &lt;td&gt;Compare proc contents length output against define lengths&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;4&lt;/td&gt;
        &lt;td&gt;All CRF-origin QNAM entries have PDFPageRef with a NamedDestination that exists in the annotated CRF PDF&lt;/td&gt;
        &lt;td&gt;Extract PDF named destinations programmatically and cross-check&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;5&lt;/td&gt;
        &lt;td&gt;All Derived QNAM entries have a Description that explains the derivation in plain language&lt;/td&gt;
        &lt;td&gt;Manual review of each Derived VLM ItemDef Description element&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;6&lt;/td&gt;
        &lt;td&gt;No CodeListRef on free-text QNAM entries&lt;/td&gt;
        &lt;td&gt;Review all VLM ItemDefs; confirm CodeListRef absent for free-text QNAMs&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;7&lt;/td&gt;
        &lt;td&gt;Description text for each QNAM matches the QLABEL value used in the dataset&lt;/td&gt;
        &lt;td&gt;Compare proc freq QLABEL output against VLM Description TranslatedText values&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;8&lt;/td&gt;
        &lt;td&gt;All leaf IDs referenced in DocumentRef elements resolve to actual files in the submission package&lt;/td&gt;
        &lt;td&gt;Cross-reference all leafID attributes against submission folder contents&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;9&lt;/td&gt;
        &lt;td&gt;SoftHard=&quot;Soft&quot; on all SUPPQUAL WhereClause RangeCheck elements&lt;/td&gt;
        &lt;td&gt;grep or XPath search for SoftHard in define.xml&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;10&lt;/td&gt;
        &lt;td&gt;WhereClauseDef OIDs are domain-scoped (no shared OIDs across SUPPQUAL domains)&lt;/td&gt;
        &lt;td&gt;Confirm OID naming convention includes domain prefix; check for duplicate OIDs in full define.xml&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;11&lt;/td&gt;
        &lt;td&gt;QVAL column-level ItemDef has def:ValueListRef attribute pointing to the correct ValueListDef OID&lt;/td&gt;
        &lt;td&gt;Direct inspection of QVAL ItemDef element in define.xml XML source&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;12&lt;/td&gt;
        &lt;td&gt;def:KeySequence=&quot;1&quot; on the QNAM ItemRef within the SUPPQUAL ItemGroupDef&lt;/td&gt;
        &lt;td&gt;Direct inspection of ItemGroupDef structure in define.xml XML source&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;13&lt;/td&gt;
        &lt;td&gt;Cross-domain consistency checks implemented (SUPP vs parent domain) — e.g., AESLIFE=Y where AESER=N&lt;/td&gt;
        &lt;td&gt;Custom SAS QC program — not covered by Pinnacle 21&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;p&gt;Run Pinnacle 21 after completing every item on this list, not before. Pinnacle 21 is a final gate, not a substitute for structured pre-review. It catches some things this list misses and misses some things this list catches. Both layers are necessary.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;idvar&quot;&gt;11. IDVAR / IDVARVAL — The Hidden Failure Point&lt;/h2&gt;

  &lt;p&gt;Most define.xml discussions focus on QNAM and QVAL. Reviewers do not. They struggle just as much with linkage. SUPPQUAL is only interpretable if the reviewer can answer one question: &lt;em&gt;which parent record does this qualifier belong to?&lt;/em&gt; That answer depends entirely on RDOMAIN, IDVAR, and IDVARVAL working together — and all three need explicit metadata support in define.xml.&lt;/p&gt;

  &lt;h3&gt;11.1 What IDVAR Actually Represents&lt;/h3&gt;

  &lt;p&gt;IDVAR is not just a variable name string. It defines the linking key into the parent domain. When RDOMAIN=AE, IDVAR=AESEQ, and IDVARVAL=12, the SUPPAE record links to the AE record where AESEQ=12 for the same USUBJID. That linkage must be unambiguous. If a reviewer cannot confirm uniqueness of the parent record — because AESEQ is not unique, or because IDVAR points to a variable that admits duplicates — the entire SUPPQUAL interpretation collapses.&lt;/p&gt;

  &lt;h3&gt;11.2 Why Ambiguity Here Breaks Review&lt;/h3&gt;

  &lt;p&gt;Consider a package where IDVAR=AESEQ and IDVARVAL=12 appears in a SUPPAE record. On the surface this is correct. But if the reviewer looks at the AE domain and finds three records with AESEQ=12 — a well-known error pattern in datasets with improper sequence numbering — they cannot resolve which parent record the qualifier belongs to. No validator catches this. The SUPPQUAL structure is internally consistent. The linkage is semantically broken.&lt;/p&gt;

  &lt;div class=&quot;warn&quot;&gt;
    &lt;strong&gt;If a reviewer cannot trace a SUPPQUAL row to exactly one parent record in under ten seconds, your define.xml is incomplete.&lt;/strong&gt; The metadata should pre-empt the question, not leave the reviewer reverse-engineering your data.
  &lt;/div&gt;

  &lt;div class=&quot;rejection-box&quot;&gt;
    &lt;strong&gt;Real Review Failure:&lt;/strong&gt;
    &quot;Multiple AE records share AESEQ=12 for subject 101-001. Unable to determine which AE record the SUPPAE qualifier applies to. Please confirm whether AESEQ is unique within USUBJID and provide corrected linkage documentation.&quot;
  &lt;/div&gt;

  &lt;h3&gt;11.3 What Define.xml Should Make Clear&lt;/h3&gt;

  &lt;p&gt;The Description elements for IDVAR and IDVARVAL are almost always boilerplate or blank in real submissions. They should not be. At minimum:&lt;/p&gt;

&lt;pre&gt;&amp;lt;!-- IDVAR ItemDef description --&amp;gt;
&amp;lt;Description&amp;gt;
  &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
    Identifies the key variable in the parent AE domain used to link
    supplemental qualifier records. Populated with AESEQ. The combination
    of USUBJID and IDVARVAL uniquely identifies one AE record.
  &amp;lt;/TranslatedText&amp;gt;
&amp;lt;/Description&amp;gt;

&amp;lt;!-- IDVARVAL ItemDef description --&amp;gt;
&amp;lt;Description&amp;gt;
  &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
    Value of AESEQ identifying the parent AE record for this qualifier.
    1:1 correspondence with AE.AESEQ; no parent record has more than one
    SUPPAE record per QNAM.
  &amp;lt;/TranslatedText&amp;gt;
&amp;lt;/Description&amp;gt;&lt;/pre&gt;

  &lt;p&gt;The phrase &quot;uniquely identifies one AE record&quot; is doing real work here. It tells the reviewer the mapping is deterministic and they do not need to investigate further. That is what good metadata does — it removes the reviewer&#39;s doubt before the doubt forms.&lt;/p&gt;

  &lt;h3&gt;11.4 When Linkage Is Non-Standard&lt;/h3&gt;

  &lt;p&gt;Non-standard linkage arises in rescue mapping, merged domain scenarios, and certain oncology or endpoint-heavy programs. If IDVARVAL is derived from a concatenation, a hash, or a composite of multiple parent variables, you must say so explicitly — both in the IDVARVAL Description element and, if the derivation is complex, in a referenced specifications document.&lt;/p&gt;

&lt;pre&gt;&amp;lt;!-- Non-standard linkage: composite key --&amp;gt;
&amp;lt;Description&amp;gt;
  &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
    IDVARVAL derived from concatenation of AESEQ (zero-padded to 4 digits)
    and VISITNUM to ensure uniqueness across repeated events at the same
    visit. Format: AESEQ_VISITNUM (e.g., &quot;0012_3&quot;). This composite key
    resolves to exactly one AE record per USUBJID.
  &amp;lt;/TranslatedText&amp;gt;
&amp;lt;/Description&amp;gt;&lt;/pre&gt;

  &lt;p&gt;If you cannot write a clear derivation description for IDVARVAL, that is a signal the linkage design itself needs to be revisited before the define.xml is written.&lt;/p&gt;

  &lt;h4&gt;Quick Validation Check&lt;/h4&gt;

  &lt;p&gt;Before documenting IDVARVAL linkage as 1:1, verify it programmatically. This check should run as part of your standard define QC program — not as a one-off manual step.&lt;/p&gt;

&lt;pre&gt;/* Check uniqueness of parent linkage key within USUBJID */
/* Run against the parent domain BEFORE writing IDVAR metadata */
proc sql;
  select usubjid,
         aeseq,
         count(*) as n
  from ae
  group by usubjid, aeseq
  having calculated n &gt; 1;
quit;

/* If any rows return: your IDVARVAL linkage is non-unique.
   Do NOT document as 1:1 in define.xml until this is resolved.
   Investigate whether AESEQ was reset across visits or periods. */&lt;/pre&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;design-decision&quot;&gt;12. SUPPQUAL vs Custom Domain — Design Decision&lt;/h2&gt;

  &lt;p&gt;Every section so far assumes the decision to use SUPPQUAL has already been made. That assumption is dangerous. Using SUPPQUAL for data that belongs in a named domain — or in a custom domain — creates bloated define.xml, unreadable VLM, and reviewer confusion that define.xml cannot fix after the fact. The metadata problem is downstream of a design problem.&lt;/p&gt;

  &lt;h3&gt;12.1 The Decision Framework&lt;/h3&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;&lt;th&gt;Situation&lt;/th&gt;&lt;th&gt;Better Choice&lt;/th&gt;&lt;th&gt;Why&lt;/th&gt;&lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Qualifier repeats across records in a structured way (multiple specimens, multiple methods)&lt;/td&gt;
        &lt;td&gt;New SDTM domain or RELREC-linked structure&lt;/td&gt;
        &lt;td&gt;Repeated structure in SUPPQUAL creates parallel rows with no obvious grouping anchor&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Variable is critical to analysis or is referenced in TFLs&lt;/td&gt;
        &lt;td&gt;Named variable in the parent domain&lt;/td&gt;
        &lt;td&gt;Analysis variables buried in SUPPQUAL require merging before use; reviewers expect key variables accessible directly&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Genuinely one-off qualifier, not repeated, not critical to analysis&lt;/td&gt;
        &lt;td&gt;SUPPQUAL&lt;/td&gt;
        &lt;td&gt;This is the use case SUPPQUAL was designed for&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Qualifier is sponsor-defined and used only for internal tracking&lt;/td&gt;
        &lt;td&gt;SUPPQUAL with clear Assigned origin&lt;/td&gt;
        &lt;td&gt;Acceptable if clearly documented; do not conflate with analysis variables&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;h3&gt;12.2 Warning Signs You Chose Wrong&lt;/h3&gt;

  &lt;p&gt;If any of the following are true for your SUPPQUAL domain, the design decision deserves a second look before you invest time in VLM construction:&lt;/p&gt;

  &lt;p&gt;QNAM count above 25 to 30 in a single SUPPQUAL dataset. The same concept split across multiple QNAMs with a numeric suffix (FLAG1, FLAG2, FLAG3). Heavy derivation logic inside SUPPQUAL that would be simpler to express as a named derived variable. Reviewers routinely needing to merge SUPPQUAL back to the parent domain to understand the parent domain records.&lt;/p&gt;

  &lt;div class=&quot;note&quot;&gt;
    When SUPPQUAL is acting like a domain, it should be a domain. The define.xml burden of a 40-QNAM SUPPLB is an order of magnitude higher than a clean 10-variable LB extension domain, and the reviewer experience is worse in every dimension.
  &lt;/div&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;p21-limits&quot;&gt;13. What Pinnacle 21 Will NOT Catch&lt;/h2&gt;

  &lt;p&gt;Pinnacle 21 validates structure. Reviewers validate meaning. These are not the same activity, and conflating them is one of the most expensive mistakes a define.xml team can make.&lt;/p&gt;

  &lt;h3&gt;13.1 The Gap Between Structural Validity and Review Readiness&lt;/h3&gt;

  &lt;p&gt;A define.xml can pass every Pinnacle 21 rule and still be useless to a reviewer. Here is the category of failures P21 cannot detect:&lt;/p&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;&lt;th&gt;Failure Type&lt;/th&gt;&lt;th&gt;P21 Response&lt;/th&gt;&lt;th&gt;Reviewer Response&lt;/th&gt;&lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;Vague Description element (&quot;Flag&quot; as the entire description of AOCCIFL)&lt;/td&gt;
        &lt;td&gt;✅ Pass — Description element is present&lt;/td&gt;
        &lt;td&gt;❌ Query — &quot;Please provide the derivation algorithm for this flag&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;CRF origin with a valid leafID that points to the wrong CRF page&lt;/td&gt;
        &lt;td&gt;✅ Pass — leafID resolves, PDFPageRef is syntactically valid&lt;/td&gt;
        &lt;td&gt;❌ Query — &quot;CRF page referenced does not contain the field described&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;QNAM name that is cryptic or non-intuitive (e.g., QNAM=XCFL3)&lt;/td&gt;
        &lt;td&gt;✅ Pass — QNAM ≤ 8 characters, conforms to naming rules&lt;/td&gt;
        &lt;td&gt;❌ Query — &quot;Please clarify the meaning of XCFL3 and confirm CDISC naming convention compliance&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;Derived origin with no derivation description&lt;/td&gt;
        &lt;td&gt;✅ Pass — Origin Type=Derived is valid&lt;/td&gt;
        &lt;td&gt;❌ Query — &quot;Derivation method not documented in define.xml or referenced specifications&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;QVAL values inconsistent with parent domain variables (AESLIFE=Y where AESER=N)&lt;/td&gt;
        &lt;td&gt;✅ Pass — No cross-domain logic checks in P21 at this level&lt;/td&gt;
        &lt;td&gt;❌ Query — &quot;Logical inconsistency between SUPPAE.AESLIFE and AE.AESER for subject [ID]&quot;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;h3&gt;13.2 Practical Cross-Domain Checks&lt;/h3&gt;

  &lt;p&gt;These are checks Pinnacle 21 does not perform but reviewers routinely validate manually. Automating them before submission eliminates a major class of queries.&lt;/p&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;SUPPQUAL Signal&lt;/th&gt;
        &lt;th&gt;Parent Domain Check&lt;/th&gt;
        &lt;th&gt;Failure Pattern&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;AESLIFE = &#39;Y&#39;&lt;/td&gt;
        &lt;td&gt;AE.AESER should be &#39;Y&#39;&lt;/td&gt;
        &lt;td&gt;Life-threatening event marked non-serious&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;AECONTRT = &#39;Y&#39;&lt;/td&gt;
        &lt;td&gt;AE.AEREL = &#39;NOT RELATED&#39;&lt;/td&gt;
        &lt;td&gt;Treatment given but event marked unrelated&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;AOCCIFL = &#39;Y&#39;&lt;/td&gt;
        &lt;td&gt;Check earlier AESTDTC for same PT&lt;/td&gt;
        &lt;td&gt;Incorrect first-occurrence flag&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;SUPPLB.LBMETHOD present&lt;/td&gt;
        &lt;td&gt;LB.LBSPEC consistent&lt;/td&gt;
        &lt;td&gt;Method/specimen mismatch&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;SUPPAE.VISIT&lt;/td&gt;
        &lt;td&gt;SV / TV alignment&lt;/td&gt;
        &lt;td&gt;Visit naming inconsistencies&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;h4&gt;Example SAS Check: SUPPAE vs AE Consistency&lt;/h4&gt;

&lt;pre&gt;/* Cross-domain QC: flag AESLIFE=Y where AE.AESER ne Y */
/* Run this before define.xml finalization — P21 will not catch it */
proc sql;
  create table ae_mismatch as
  select a.usubjid,
         a.idvarval    as aeseq,
         a.qval        as aeslife,
         b.aeser
  from suppae a
  left join ae b
    on  a.usubjid = b.usubjid
    and input(a.idvarval, best.) = b.aeseq
  where a.qnam   = &#39;AESLIFE&#39;
    and a.qval   = &#39;Y&#39;
    and b.aeser ne &#39;Y&#39;;
quit;

/* If ae_mismatch has rows: data error or documentation gap.
   Resolve before submission. Document exceptions in the
   Data Reviewer&#39;s Guide if clinically justified. */&lt;/pre&gt;

  &lt;h3&gt;13.3 The Practical Rule&lt;/h3&gt;

  &lt;p&gt;Passing Pinnacle 21 means your data is structurally acceptable for submission intake. It does not mean your metadata is review-ready. The two gates are sequential, not equivalent. Run P21 to clear the first gate. Then review your define.xml as if you are an FDA data reviewer who has never seen this study and has 20 minutes to understand what SUPPAE contains. If you would have questions, so will the reviewer.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;scale&quot;&gt;14. Scaling Problems in Large SUPPQUAL Domains&lt;/h2&gt;

  &lt;p&gt;In real studies, SUPPLB with 40-plus QNAMs and SUPPCM with 60-plus QNAMs are not unusual. At that scale, define.xml stops being a reference document and starts being a navigation problem. This is a design failure that manifests as a metadata failure, and VLM construction alone cannot solve it.&lt;/p&gt;

  &lt;h3&gt;14.1 What Goes Wrong at Scale&lt;/h3&gt;

  &lt;p&gt;A ValueListDef block with 50 ItemRef entries renders slowly in define viewers and is cognitively unnavigable. QNAM names become abbreviated to the point of opacity. VLM entries that repeat the same boilerplate description across dozens of Y/N flags become indistinguishable to a reviewer scanning for meaning. The define.xml becomes accurate but useless.&lt;/p&gt;

  &lt;p&gt;The specific failure pattern in SUPPLB is worth naming. Laboratory method, specimen type, and result units are often implemented as separate QNAMs per test code — SPECBLOOD, SPECURINE, METHCHEM, METHHEMA — rather than as a single QNAM with controlled terminology. This explodes the QNAM count for no semantic gain and makes the VLM block look like noise.&lt;/p&gt;

  &lt;h3&gt;14.2 What Experienced Teams Do&lt;/h3&gt;

  &lt;p&gt;Before building VLM for a large SUPPQUAL domain, conduct a QNAM audit. Group all QNAMs by semantic category. If multiple QNAMs represent the same concept with different scope (specimen type by test, method by test), evaluate whether a single QNAM with controlled values covers all cases. The goal is the smallest QNAM count that captures all necessary information without ambiguity.&lt;/p&gt;

  &lt;p&gt;Keep QNAM names human-readable within the 8-character constraint. SPECTYP is better than SPCTX3. METHCD is better than MTHCD2. Reviewers read QNAM values directly in the dataset — they should not need to reference define.xml to understand what category of information a QNAM represents.&lt;/p&gt;

  &lt;div class=&quot;note&quot;&gt;
    Hard truth: if your SUPPQUAL domain requires scrolling to navigate in a define viewer, it is already too complex. The define.xml is a symptom. The design is the problem.
  &lt;/div&gt;

  &lt;h3&gt;14.3 Re-Evaluating Domain Design When Scale Grows&lt;/h3&gt;

  &lt;p&gt;A SUPPCM with 60 QNAMs representing concomitant medication classification attributes is not a well-designed SUPPQUAL. It is an unstated custom domain. If the study team cannot justify why these qualifiers could not be represented as named variables in CM or a CM extension domain, that is the conversation to have before the submission package is built — not after define.xml review comes back with 30 metadata queries.&lt;/p&gt;

  &lt;div class=&quot;warn&quot;&gt;
    &lt;strong&gt;If your SUPPQUAL cannot be understood without scrolling, filtering, or cross-referencing multiple sections of define.xml, it is already too complex for efficient review.&lt;/strong&gt; At that point you are not solving a metadata problem. You are managing the consequences of a design decision that should have been made differently.
  &lt;/div&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;v21&quot;&gt;15. Define.xml v2.0 vs v2.1 — What Changes for SUPPQUAL&lt;/h2&gt;

  &lt;p&gt;Most teams treat v2.0 and v2.1 as interchangeable for SUPPQUAL work. They are not, and the differences cluster precisely around the VLM and WhereClause features that are central to SUPPQUAL metadata.&lt;/p&gt;

  &lt;h3&gt;15.1 WhereClause Handling&lt;/h3&gt;

  &lt;p&gt;In Define-XML v2.1, WhereClause handling is more formally specified, particularly for multi-condition expressions. The &lt;code&gt;def:WhereClauseDef&lt;/code&gt; element in v2.1 supports cleaner namespacing and has better-defined behavior for AND semantics across multiple RangeCheck elements. If you are building complex multi-condition WhereClause entries — scoping VLM by both QNAM and IDVAR simultaneously — v2.1 is more predictable in how validators and viewers interpret the expression.&lt;/p&gt;

  &lt;h3&gt;15.2 ExternalCodeList and Controlled Terminology Linkage&lt;/h3&gt;

  &lt;p&gt;v2.1 introduces cleaner linkage mechanisms for external controlled terminology dictionaries, including support for NCI Thesaurus version pinning in the &lt;code&gt;StandardOID&lt;/code&gt; attribute chain. For SUPPQUAL QNAMs that reference MedDRA, SNOMED, or LOINC values — which appears in specialized domains like SUPPDS or SUPPFA — v2.1 provides more precise and validator-checkable external codelist references.&lt;/p&gt;

  &lt;h3&gt;15.3 Reviewer Tooling Compatibility&lt;/h3&gt;

  &lt;p&gt;Modern FDA review tooling (JMP Clinical, the Agency&#39;s internal viewers, and the CDISC Define-XML viewer) handle v2.1 correctly. Legacy sponsor define viewers may not render v2.1 features correctly, particularly the improved WhereClause rendering. Validate your output in both the CDISC Define-XML viewer and Pinnacle 21 regardless of which version you target. If your submission standards allow v2.1, use it — but confirm with your regulatory affairs team that the target agency accepts v2.1 for the specific submission type.&lt;/p&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;&lt;th&gt;Feature&lt;/th&gt;&lt;th&gt;v2.0 Behavior&lt;/th&gt;&lt;th&gt;v2.1 Behavior&lt;/th&gt;&lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;&lt;td&gt;Multi-condition WhereClause&lt;/td&gt;&lt;td&gt;Supported but ambiguously specified&lt;/td&gt;&lt;td&gt;Formally specified AND semantics&lt;/td&gt;&lt;/tr&gt;
      &lt;tr&gt;&lt;td&gt;ExternalCodeList&lt;/td&gt;&lt;td&gt;Basic dictionary reference&lt;/td&gt;&lt;td&gt;Version-pinned, StandardOID-linked&lt;/td&gt;&lt;/tr&gt;
      &lt;tr&gt;&lt;td&gt;ValueListDef scoping&lt;/td&gt;&lt;td&gt;Functional but verbose&lt;/td&gt;&lt;td&gt;Same structure, better validator support&lt;/td&gt;&lt;/tr&gt;
      &lt;tr&gt;&lt;td&gt;FDA tooling acceptance&lt;/td&gt;&lt;td&gt;Fully accepted&lt;/td&gt;&lt;td&gt;Accepted; preferred for new submissions&lt;/td&gt;&lt;/tr&gt;
      &lt;tr&gt;&lt;td&gt;PMDA tooling acceptance&lt;/td&gt;&lt;td&gt;Fully accepted&lt;/td&gt;&lt;td&gt;Accepted; confirm per submission type&lt;/td&gt;&lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;edge-cases&quot;&gt;16. Edge Cases You Will Hit&lt;/h2&gt;

  &lt;p&gt;These are not hypotheticals. Every experienced SDTM programmer encounters all of them eventually. Knowing the right define.xml response in advance saves a revision cycle.&lt;/p&gt;

  &lt;h3&gt;Case 1: Same QNAM Name, Different Meaning Across Studies&lt;/h3&gt;

  &lt;p&gt;Not a problem within one dataset — it is a problem when you reuse a define.xml template across studies without auditing QNAM semantics. QNAM=FAST might mean &quot;fasting status confirmed&quot; in one study and &quot;hours of fasting prior to sample&quot; in another. The former is Y/N with a NY codelist. The latter is numeric stored as text with no codelist. If you port the VLM entry without reviewing the clinical meaning in the new study context, you will have a define.xml that says the wrong thing about your data.&lt;/p&gt;

  &lt;h3&gt;Case 2: Numeric QVAL Stored as Text&lt;/h3&gt;

  &lt;p&gt;This is extremely common. QVAL is always character in the XPT — SAS character variable, always. But some QNAMs store what is functionally a numeric value: a score, a count, a duration in hours. In define.xml, the DataType for these VLM entries should still be &lt;code&gt;text&lt;/code&gt; to match the XPT variable type, but the Description must explicitly state that the content is numeric and document the units and expected range. Without that note, a reviewer seeing QVAL=&quot;72&quot; has no frame of reference.&lt;/p&gt;

&lt;pre&gt;&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL.AEDURH&quot;
         Name=&quot;AEDURH&quot;
         DataType=&quot;text&quot;
         Length=&quot;5&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Duration of adverse event in hours. Numeric value stored as character.
      Derived from (AEENDTC - AESTDTC) in hours, rounded to nearest integer.
      Range: 0 to 8760 (one year). Units: hours.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;def:Origin Type=&quot;Derived&quot;/&amp;gt;
&amp;lt;/ItemDef&amp;gt;&lt;/pre&gt;

  &lt;h3&gt;Case 3: Blank vs Missing QVAL&lt;/h3&gt;

  &lt;p&gt;A blank QVAL and a missing QVAL mean different things clinically. Blank can mean the question was asked and the answer was empty or not applicable. Missing in SDTM terms typically means the record should not exist. In SUPPQUAL, a row with a blank QVAL should almost never exist — if there is nothing to report for a qualifier, the row should not be created. If your dataset contains rows with blank QVAL, your VLM Description should explicitly state whether blank is a permissible value and what it signifies. Otherwise reviewers will query every blank QVAL as a potential data quality issue.&lt;/p&gt;

  &lt;h3&gt;Case 4: Multiple QNAMs Representing One Concept&lt;/h3&gt;

  &lt;p&gt;This arises from CRF mapping where multiple checkboxes each become their own QNAM. A concomitant medication reason-for-use form with 10 checkboxes should not produce 10 QNAMs (REASCARD, REASDIAB, REASHYP…). It should produce one QNAM (REAS) with controlled terminology values, or at most two QNAMs if the reason structure is genuinely multi-level. Each additional QNAM multiplies your VLM burden and dilutes the reviewer&#39;s ability to understand the data conceptually. Consolidation before SDTM mapping is far easier than VLM cleanup after the fact.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;reviewer-model&quot;&gt;17. How Reviewers Actually Read SUPPQUAL&lt;/h2&gt;

  &lt;p&gt;Reviewers do not read SUPPQUAL sequentially. They follow a chain: QNAM → WhereClause → VLM entry → Origin → parent domain. If any step in that chain is unclear, the result is a query.&lt;/p&gt;

  &lt;p&gt;Understanding that path is the single most useful frame for designing SUPPQUAL define.xml well. Design for it and the metadata almost writes itself.&lt;/p&gt;

  &lt;h3&gt;17.1 The Reviewer Flow&lt;/h3&gt;

  &lt;p&gt;A reviewer opens the SUPPQUAL dataset. They see a QNAM value — say, AESLIFE. They have one of two reactions: they know what it means immediately, or they go to define.xml. If they go to define.xml, they look at the VLM entry for AESLIFE in sequence: the Description, the Origin, the CodelistRef if present, and the PDFPageRef if the origin is CRF. They reconstruct the meaning of the variable from those four elements.&lt;/p&gt;

  &lt;p&gt;If any element is missing or vague, they stop reconstructing and start writing a query. The threshold is roughly five to ten seconds. If the meaning is not clear in that window, it becomes a formal question.&lt;/p&gt;

  &lt;h3&gt;17.2 What This Means for Your Metadata&lt;/h3&gt;

  &lt;p&gt;Description first. It is the primary artifact. Everything else is supporting documentation. A Description that fully explains the variable — its clinical meaning, its derivation if Derived, its permissible values if not codelist-controlled — means the reviewer may never need to open the CRF or the specs document. That is the standard to target.&lt;/p&gt;

  &lt;p&gt;Origin second. A clear, specific origin with a resolvable document reference tells the reviewer they could verify the source if they chose to. The fact that they could verify it is often enough that they do not need to.&lt;/p&gt;

  &lt;p&gt;Codelist third. If a codelist is present, the reviewer expects the data to conform to it exactly. Do not reference a codelist for a variable with values that are not in the codelist. That is worse than having no codelist reference.&lt;/p&gt;

  &lt;div class=&quot;note&quot;&gt;
    Design for the reviewer who is reading your SUPPQUAL at 4 PM on a Friday after reviewing six other domains. They are not going to ask clarifying questions mentally. They are going to write queries. Every piece of define.xml that removes a potential query is time saved on both sides of the submission.
  &lt;/div&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;cross-domain&quot;&gt;18. Cross-Domain Consistency — The Silent Check&lt;/h2&gt;

  &lt;p&gt;Reviewers do not look at SUPPQUAL in isolation. They compare it against the parent domain systematically, and they compare SUPPQUAL-derived flags against analysis datasets. Logical inconsistencies between SUPPQUAL and parent domain variables are one of the most common sources of late-stage submission queries — because they require investigation to determine whether the inconsistency reflects a data error, a derivation error, or a documentation error.&lt;/p&gt;

  &lt;h3&gt;18.1 Practical Cross-Domain Checks&lt;/h3&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;
        &lt;th&gt;SUPPQUAL Signal&lt;/th&gt;
        &lt;th&gt;Parent Domain Check&lt;/th&gt;
        &lt;th&gt;Failure Pattern&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;AESLIFE = &#39;Y&#39;&lt;/td&gt;
        &lt;td&gt;AE.AESER should be &#39;Y&#39;&lt;/td&gt;
        &lt;td&gt;Life-threatening event marked non-serious&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;AECONTRT = &#39;Y&#39;&lt;/td&gt;
        &lt;td&gt;AE.AEREL = &#39;NOT RELATED&#39;&lt;/td&gt;
        &lt;td&gt;Treatment given but event marked unrelated&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;AOCCIFL = &#39;Y&#39;&lt;/td&gt;
        &lt;td&gt;Check earlier AESTDTC for same PT&lt;/td&gt;
        &lt;td&gt;Incorrect first-occurrence flag&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;SUPPLB.LBMETHOD present&lt;/td&gt;
        &lt;td&gt;LB.LBSPEC consistent&lt;/td&gt;
        &lt;td&gt;Method-specimen mismatch&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;VISIT in SUPP&lt;/td&gt;
        &lt;td&gt;SV / TV alignment&lt;/td&gt;
        &lt;td&gt;Visit naming inconsistencies&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;h3&gt;18.2 Reviewer Query Patterns&lt;/h3&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;&lt;th&gt;SUPPQUAL QNAM / Value&lt;/th&gt;&lt;th&gt;Parent Domain Variable / Expectation&lt;/th&gt;&lt;th&gt;Query Pattern&lt;/th&gt;&lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;SUPPAE.AESLIFE = Y&lt;/td&gt;
        &lt;td&gt;AE.AESER should = Y (life-threatening implies serious)&lt;/td&gt;
        &lt;td&gt;&quot;Subject [ID] has AESLIFE=Y in SUPPAE but AESER=N in AE. Please reconcile.&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;SUPPAE.AECONTRT = Y&lt;/td&gt;
        &lt;td&gt;A CM record for the AE treatment period should exist&lt;/td&gt;
        &lt;td&gt;&quot;Concomitant treatment flagged in SUPPAE but no corresponding CM record found for subject [ID].&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;SUPPLB.FAST = Y&lt;/td&gt;
        &lt;td&gt;LB.LBTPT or LB.LBTPTNUM should reflect fasting timepoint&lt;/td&gt;
        &lt;td&gt;&quot;Fasting flag present in SUPPLB but LBTPT does not indicate fasting condition.&quot;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;SUPPDS.DSSREAS (discontinuation reason)&lt;/td&gt;
        &lt;td&gt;DS.DSDECOD controlled term should align&lt;/td&gt;
        &lt;td&gt;&quot;SUPPDS freetext reason inconsistent with DS.DSDECOD for subject [ID].&quot;&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;h3&gt;18.2 What Define.xml Can and Cannot Do Here&lt;/h3&gt;

  &lt;p&gt;Define.xml cannot prevent cross-domain logical inconsistencies — those are data quality issues. But define.xml can make the reviewer&#39;s investigation faster and less adversarial. If your SUPPAE VLM entry for AESLIFE includes a Description note stating &quot;Expected to be consistent with AE.AESER; exceptions documented in the data reviewer&#39;s guide,&quot; you have pre-answered the question. The reviewer knows you thought about the relationship. That changes the tone of the review interaction significantly.&lt;/p&gt;

  &lt;p&gt;Add cross-domain consistency notes to VLM Descriptions for any qualifier that has a logical dependency on a parent domain variable. It adds two sentences to your metadata and removes a potential two-week query-response cycle.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;automation&quot;&gt;19. Levels of Automation — Maturity Model&lt;/h2&gt;

  &lt;p&gt;The SAS generation utility in Section 9 represents one point on a spectrum. Where a team sits on this spectrum determines how many define.xml errors they make per submission, how long define QC takes, and how much rework they absorb when datasets change late in the submission timeline.&lt;/p&gt;

  &lt;table&gt;
    &lt;thead&gt;
      &lt;tr&gt;&lt;th&gt;Level&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;th&gt;Error Rate&lt;/th&gt;&lt;th&gt;Rework Cost When Data Changes&lt;/th&gt;&lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;strong&gt;1 — Manual XML editing&lt;/strong&gt;&lt;/td&gt;
        &lt;td&gt;Define.xml authored or edited by hand in a text editor or define tool UI&lt;/td&gt;
        &lt;td&gt;High — typos, OID mismatches, missed QNAMs&lt;/td&gt;
        &lt;td&gt;Very high — every QNAM change requires manual XML edits&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;strong&gt;2 — Metadata-driven generation&lt;/strong&gt;&lt;/td&gt;
        &lt;td&gt;Define.xml generated from a metadata specs dataset; programmers edit the specs, not the XML&lt;/td&gt;
        &lt;td&gt;Medium — errors in specs propagate consistently; easier to catch and fix&lt;/td&gt;
        &lt;td&gt;Medium — update specs dataset, regenerate&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;strong&gt;3 — Dataset-derived VLM auto-build&lt;/strong&gt;&lt;/td&gt;
        &lt;td&gt;VLM entries generated directly from the production SUPPQUAL XPT; QNAM list and lengths derived programmatically&lt;/td&gt;
        &lt;td&gt;Low — structural metadata always reflects actual data&lt;/td&gt;
        &lt;td&gt;Low — rerun the generation program against updated XPT&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;&lt;strong&gt;4 — Full validation and reconciliation framework&lt;/strong&gt;&lt;/td&gt;
        &lt;td&gt;Automated comparison of define.xml against datasets plus cross-domain consistency checks; discrepancies flagged in a QC report&lt;/td&gt;
        &lt;td&gt;Very low — errors caught before submission regardless of late data changes&lt;/td&gt;
        &lt;td&gt;Very low — reconciliation runs catch drift automatically&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;

  &lt;p&gt;Level 3 is the practical target for any team running more than two to three submissions per year. Level 4 is achievable with investment in the reconciliation tooling and is worth building if your team operates an FSP model across multiple sponsors. The metadata drift problem — where define.xml and datasets diverge after a late protocol amendment — is the most common cause of last-minute submission delays, and it is entirely preventable with Level 3 or 4 automation.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2 id=&quot;bad-good&quot;&gt;20. Bad vs Good — Full Picture&lt;/h2&gt;

  &lt;p&gt;Everything in the preceding sections collapses into this single comparison. This is the difference between a define.xml that passes intake and one that survives review.&lt;/p&gt;

  &lt;h3&gt;❌ The Incomplete Package&lt;/h3&gt;

&lt;pre&gt;&amp;lt;!-- Column-level QVAL — no ValueListRef --&amp;gt;
&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL&quot;
         Name=&quot;QVAL&quot;
         DataType=&quot;text&quot;
         Length=&quot;200&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;Result Value&amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;!-- Missing: def:ValueListRef --&amp;gt;
  &amp;lt;def:Origin Type=&quot;Predecessor&quot;/&amp;gt;
&amp;lt;/ItemDef&amp;gt;

&amp;lt;!-- No ValueListDef block --&amp;gt;
&amp;lt;!-- No WhereClauseDef entries --&amp;gt;
&amp;lt;!-- No VLM-level ItemDefs --&amp;gt;&lt;/pre&gt;

  &lt;p&gt;What a reviewer sees: QVAL with no VLM. Every QNAM in the dataset is undocumented at the value level. The reviewer must interpret AESLIFE, AECONTRT, AOCCIFL, and every other qualifier without metadata support. Origin=Predecessor on a structural column with no predecessor documentation. Queries incoming.&lt;/p&gt;

  &lt;h3&gt;✅ The Complete Package&lt;/h3&gt;

&lt;pre&gt;&amp;lt;!-- Column-level QVAL with ValueListRef --&amp;gt;
&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL&quot;
         Name=&quot;QVAL&quot;
         DataType=&quot;text&quot;
         Length=&quot;200&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Result value for the supplemental qualifier identified by QNAM.
      See value-level metadata for QNAM-specific types, codelists, and origins.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;def:ValueListRef ValueListOID=&quot;VL.SUPPAE.QVAL&quot;/&amp;gt;
&amp;lt;/ItemDef&amp;gt;

&amp;lt;!-- ValueListDef: one entry per QNAM --&amp;gt;
&amp;lt;def:ValueListDef OID=&quot;VL.SUPPAE.QVAL&quot;&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.QVAL.AESLIFE&quot;
           OrderNumber=&quot;1&quot; Mandatory=&quot;Yes&quot;&amp;gt;
    &amp;lt;def:WhereClauseRef WhereClauseOID=&quot;WC.SUPPAE.QNAM.AESLIFE&quot;/&amp;gt;
  &amp;lt;/ItemRef&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.SUPPAE.QVAL.AOCCIFL&quot;
           OrderNumber=&quot;2&quot; Mandatory=&quot;No&quot;&amp;gt;
    &amp;lt;def:WhereClauseRef WhereClauseOID=&quot;WC.SUPPAE.QNAM.AOCCIFL&quot;/&amp;gt;
  &amp;lt;/ItemRef&amp;gt;
&amp;lt;/def:ValueListDef&amp;gt;

&amp;lt;!-- WhereClauseDefs --&amp;gt;
&amp;lt;def:WhereClauseDef OID=&quot;WC.SUPPAE.QNAM.AESLIFE&quot;&amp;gt;
  &amp;lt;RangeCheck Comparator=&quot;EQ&quot; SoftHard=&quot;Soft&quot;
              def:ItemOID=&quot;IT.SUPPAE.QNAM&quot;&amp;gt;
    &amp;lt;CheckValue&amp;gt;AESLIFE&amp;lt;/CheckValue&amp;gt;
  &amp;lt;/RangeCheck&amp;gt;
&amp;lt;/def:WhereClauseDef&amp;gt;

&amp;lt;def:WhereClauseDef OID=&quot;WC.SUPPAE.QNAM.AOCCIFL&quot;&amp;gt;
  &amp;lt;RangeCheck Comparator=&quot;EQ&quot; SoftHard=&quot;Soft&quot;
              def:ItemOID=&quot;IT.SUPPAE.QNAM&quot;&amp;gt;
    &amp;lt;CheckValue&amp;gt;AOCCIFL&amp;lt;/CheckValue&amp;gt;
  &amp;lt;/RangeCheck&amp;gt;
&amp;lt;/def:WhereClauseDef&amp;gt;

&amp;lt;!-- VLM-level ItemDefs: AESLIFE --&amp;gt;
&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL.AESLIFE&quot;
         Name=&quot;AESLIFE&quot;
         DataType=&quot;text&quot;
         Length=&quot;1&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Indicator of whether the adverse event was life-threatening at the
      time of occurrence. Expected to be consistent with AE.AESER=Y;
      exceptions documented in the Data Reviewer&#39;s Guide Section 4.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;CodeListRef CodeListOID=&quot;CL.NY&quot;/&amp;gt;
  &amp;lt;def:Origin Type=&quot;CRF&quot;&amp;gt;
    &amp;lt;def:DocumentRef leafID=&quot;LF.ACRF&quot;&amp;gt;
      &amp;lt;def:PDFPageRef Type=&quot;NamedDestination&quot; PageRefs=&quot;AE_SAE_PAGE&quot;/&amp;gt;
    &amp;lt;/def:DocumentRef&amp;gt;
  &amp;lt;/def:Origin&amp;gt;
&amp;lt;/ItemDef&amp;gt;

&amp;lt;!-- VLM-level ItemDefs: AOCCIFL --&amp;gt;
&amp;lt;ItemDef OID=&quot;IT.SUPPAE.QVAL.AOCCIFL&quot;
         Name=&quot;AOCCIFL&quot;
         DataType=&quot;text&quot;
         Length=&quot;1&quot;
         SASFieldName=&quot;QVAL&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText xml:lang=&quot;en&quot;&amp;gt;
      Flag indicating the first chronological occurrence of an AE preferred
      term within a subject. Set to &#39;Y&#39; for the first record by AESTDTC
      ascending, then AESEQ ascending. Subsequent occurrences left blank.
      Derived — no CRF source.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
  &amp;lt;CodeListRef CodeListOID=&quot;CL.NY&quot;/&amp;gt;
  &amp;lt;def:Origin Type=&quot;Derived&quot;&amp;gt;
    &amp;lt;def:DocumentRef leafID=&quot;LF.SDTM_SPECS&quot;&amp;gt;
      &amp;lt;def:PDFPageRef Type=&quot;NamedDestination&quot;
                      PageRefs=&quot;SUPPAE_AOCCIFL_ALGO&quot;/&amp;gt;
    &amp;lt;/def:DocumentRef&amp;gt;
  &amp;lt;/def:Origin&amp;gt;
&amp;lt;/ItemDef&amp;gt;&lt;/pre&gt;

  &lt;p&gt;The difference is not volume. The complete version has more XML, but every element is doing specific work. The incomplete version has almost no XML and none of it is useful. A reviewer reading the complete version can understand AESLIFE and AOCCIFL in under ten seconds each. A reviewer reading the incomplete version has to write queries to get that same information. That is the operational definition of a well-built SUPPQUAL define package versus a broken one.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2&gt;Quick Reference Mental Model&lt;/h2&gt;

  &lt;p&gt;Every SUPPQUAL VLM entry follows this chain. If any link is broken or missing, the reviewer cannot interpret the variable.&lt;/p&gt;

  &lt;pre style=&quot;background:#1a1a2e; color:#e8e8f0; border-left:4px solid #4a90d9; font-size:13px; line-height:2;&quot;&gt;
  QNAM value in dataset
       │
       ▼
  WhereClauseDef  ──── scopes the VLM entry to this QNAM
       │
       ▼
  VLM ItemDef (IT.SUPPXX.QVAL.QNAMNAME)
       ├── Description    ◄── clinical meaning + derivation note
       ├── DataType/Length◄── actual data characteristics
       ├── CodeListRef    ◄── controlled values (if applicable)
       └── Origin         ◄── CRF page / Derived method / Assigned source
  &lt;/pre&gt;

  &lt;p&gt;Build this chain for every QNAM in every SUPPQUAL domain, make each link explicit, and the define.xml review writes itself.&lt;/p&gt;

  &lt;!-- ============================================================ --&gt;
  &lt;hr class=&quot;section-divider&quot;&gt;
  &lt;h2&gt;Final Thought&lt;/h2&gt;

  &lt;p&gt;SUPPQUAL define.xml complexity is a direct reflection of the architectural tradeoff CDISC made when they designed the supplemental qualifier model. A fixed eight-column structure that can carry arbitrary qualifiers is elegant for dataset design. For metadata, it is a nightmare — because the metadata burden that you would normally spread across named variables all collapses into one column (QVAL) and one discriminator (QNAM), and define.xml has to reconstruct that variable-level meaning through VLM machinery that most programmers interact with infrequently enough to make mistakes every time.&lt;/p&gt;

  &lt;p&gt;The way to get good at this is to build it wrong once, get the rejection letter, understand exactly which element was missing or malformed, and then build the QC scaffolding that prevents that specific error from ever occurring again. The checklist above is the aggregate of those failures across multiple programs. It saves you from learning each one the hard way.&lt;/p&gt;

  &lt;p&gt;&lt;strong&gt;SUPPQUAL is not documentation of data. It is reconstruction of variables. If define.xml does not make those variables obvious, the reviewer will stop and ask you to explain them.&lt;/strong&gt;&lt;/p&gt;

  &lt;div class=&quot;tags&quot;&gt;
    Tags:
    &lt;span&gt;define.xml&lt;/span&gt;
    &lt;span&gt;SUPPQUAL&lt;/span&gt;
    &lt;span&gt;value-level metadata&lt;/span&gt;
    &lt;span&gt;VLM&lt;/span&gt;
    &lt;span&gt;SDTM&lt;/span&gt;
    &lt;span&gt;FDA submission&lt;/span&gt;
    &lt;span&gt;PMDA&lt;/span&gt;
    &lt;span&gt;WhereClauseDef&lt;/span&gt;
    &lt;span&gt;QNAM&lt;/span&gt;
    &lt;span&gt;IDVAR&lt;/span&gt;
    &lt;span&gt;reviewer alignment&lt;/span&gt;
    &lt;span&gt;Pinnacle 21&lt;/span&gt;
    &lt;span&gt;automation&lt;/span&gt;
    &lt;span&gt;cross-domain&lt;/span&gt;
    &lt;span&gt;regulatory&lt;/span&gt;
    &lt;span&gt;SAS&lt;/span&gt;
  &lt;/div&gt;

&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7149458382487958212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7149458382487958212'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/04/definexml-for-suppqual-getting-qnam.html' title='Define.xml for SUPPQUAL — Getting QNAM-Level Metadata Right'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-8138307078881198116</id><published>2026-04-03T13:15:00.007-04:00</published><updated>2026-04-03T13:22:44.840-04:00</updated><title type='text'>Dynamic SUPPQUAL Generation Using Metadata-Driven SAS Macros</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;title&gt;&lt;/title&gt;
&lt;meta name=&quot;description&quot; content=&quot;Automate SUPPQUAL generation across AE, CM, LB, DM and other parent domains from one control dataset. Metadata-driven SAS macros with validation, IDVAR type detection, and submission-ready sort order.&quot;&gt;
&lt;meta name=&quot;keywords&quot; content=&quot;SDTM, SUPPQUAL, SAS macros, metadata-driven programming, define.xml, Pinnacle 21, SDTMIG, regulatory submissions, CDISC&quot;&gt;
&lt;style&gt;
  body {
    font-family: Georgia, serif;
    font-size: 16px;
    line-height: 1.75;
    color: #2b2b2b;
    max-width: 1200px;
    margin: 40px auto;
    padding: 0 24px;
    background: #ffffff;
  }
  h1 {
    font-size: 30px;
    color: #1a1a2e;
    line-height: 1.3;
    margin-bottom: 8px;
  }
  h2 {
    font-size: 21px;
    color: #1a1a2e;
    margin-top: 44px;
    border-bottom: 2px solid #e0e0e0;
    padding-bottom: 6px;
  }
  h3 {
    font-size: 17px;
    color: #333333;
    margin-top: 32px;
  }
  p {
    margin: 14px 0;
  }
  pre {
    background: #f5f5f5;
    border-left: 4px solid #0066cc;
    padding: 16px 20px;
    overflow-x: auto;
    font-size: 13.5px;
    line-height: 1.55;
    border-radius: 0 4px 4px 0;
    font-family: &quot;Courier New&quot;, monospace;
    white-space: pre-wrap;
    word-wrap: break-word;
  }
  code {
    font-family: &quot;Courier New&quot;, monospace;
    background: #f0f0f0;
    padding: 1px 5px;
    border-radius: 3px;
    font-size: 14px;
    color: #b5432a;
  }
  .note {
    background: #fff8e1;
    border-left: 4px solid #f9a825;
    padding: 12px 16px;
    margin: 20px 0;
    border-radius: 0 4px 4px 0;
    font-size: 15px;
  }
  .warn {
    background: #fff3f3;
    border-left: 4px solid #cc2222;
    padding: 12px 16px;
    margin: 20px 0;
    border-radius: 0 4px 4px 0;
    font-size: 15px;
  }
  table {
    border-collapse: collapse;
    width: 100%;
    margin: 20px 0;
    font-size: 14px;
  }
  th {
    background: #1a1a2e;
    color: #ffffff;
    text-align: left;
    padding: 8px 12px;
  }
  td {
    padding: 7px 12px;
    border-bottom: 1px solid #dddddd;
    vertical-align: top;
  }
  tr:nth-child(even) td {
    background: #f9f9f9;
  }
  .meta {
    color: #666666;
    font-size: 14px;
    margin-bottom: 28px;
  }
  .tags {
    font-size: 13px;
    color: #777777;
  }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;


&lt;p&gt;
If you have managed SDTM deliverables across multiple studies at the same time, you already know what happens to SUPPQUAL programs. You start with one clean macro per domain. Then a protocol amendment adds three new supplemental variables to AE. A PMDA query forces a second QNAM into EX. The DMC needs something non-standard from LB. Six months later you have domain-specific programs with no shared logic, no central control, and every change requires manual updates across multiple files.
&lt;/p&gt;

&lt;p&gt;
The metadata-driven approach fixes that. One control dataset. One macro family. All SUPP domains generated in a single call. This post walks through the full design, control dataset structure, macro architecture, the edge cases that cause real production issues, and the validation checks you should run before submission.
&lt;/p&gt;

&lt;h2&gt;The Problem with Hard-Coded SUPPQUAL Programs&lt;/h2&gt;

&lt;p&gt;
Hard-coded programs break in predictable ways. A QNAM gets added mid-study, someone has to find the right program, understand its structure, add the variable, and QC the whole thing again. An amendment renames a CRF field, IDVARVAL logic breaks silently because the source variable changed. A programmer unfamiliar with the original design adds a duplicate QNAM to a different SUPP domain by mistake. None of these are dramatic failures. They are the slow buildup of technical debt across a submission package.
&lt;/p&gt;

&lt;p&gt;
The deeper issue is that SUPPQUAL generation is structurally the same across parent domains. For every QNAM, you are doing the same thing, pulling a variable from a source dataset, converting it to character, attaching the right RDOMAIN, linking it back to the parent record through IDVAR and IDVARVAL, and writing it in long form with the correct QNAM, QLABEL, QORIG, and QEVAL assignments. The logic does not change. Only the metadata does.
&lt;/p&gt;

&lt;h2&gt;SUPPQUAL Structure, The Part That Trips People&lt;/h2&gt;

&lt;p&gt;
Most experienced programmers know the basic structure. But a few details still cause submission defects and are worth stating clearly before getting into the macro design.
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;IDVARVAL is always character.&lt;/strong&gt; Sequence variables in parent domains such as AESEQ, CMSEQ, LBSEQ, and EXSEQ are numeric in the parent dataset. IDVARVAL in the SUPP dataset must be the character version of that value. This conversion is straightforward, &lt;code&gt;put(AESEQ, best32.)&lt;/code&gt; gives you &quot;1&quot;, &quot;2&quot;, &quot;3&quot;, but it must be handled explicitly. If the source dataset uses a custom format on the sequence variable, you want the raw numeric-to-character conversion, not the formatted value. The macro should detect IDVAR type at runtime and apply &lt;code&gt;best32.&lt;/code&gt; for numeric IDVARs.
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;IDVAR and IDVARVAL are blank for one-record-per-subject domains.&lt;/strong&gt; The DM domain has one record per subject. SUPPDM therefore has no meaningful IDVAR, so both IDVAR and IDVARVAL are left blank. Per SDTMIG Section 8.4, this is valid when there is only one record per subject in the related domain.
&lt;/p&gt;

&lt;p&gt;
&lt;strong&gt;Records with missing QVAL must be excluded.&lt;/strong&gt; Supplemental qualifier records with no data value should not be carried into the final SUPP dataset. Missing QVAL is a common validation issue and should be filtered out during generation.
&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Variable&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Length&lt;/th&gt;
      &lt;th&gt;Key Notes&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;STUDYID&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;&amp;le;200&lt;/td&gt;&lt;td&gt;Copied from parent domain&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;RDOMAIN&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;2&lt;/td&gt;&lt;td&gt;Parent domain abbreviation&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;USUBJID&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;&amp;le;200&lt;/td&gt;&lt;td&gt;Copied from parent domain&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;IDVAR&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Sequence variable name, blank for one-record-per-subject domains&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;IDVARVAL&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;&amp;le;200&lt;/td&gt;&lt;td&gt;Always character, blank when IDVAR is blank&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;QNAM&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Must start with a letter, uppercase, alphanumeric, 8 characters or less&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;QLABEL&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;&amp;le;40&lt;/td&gt;&lt;td&gt;Descriptive label for QNAM&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;QVAL&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;&amp;le;200&lt;/td&gt;&lt;td&gt;Always character, records with missing values excluded&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;QORIG&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;&amp;le;200&lt;/td&gt;&lt;td&gt;CRF, Derived, Assigned, and related values per study standard&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;QEVAL&lt;/td&gt;&lt;td&gt;Char&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;td&gt;Usually blank unless evaluator is required&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;div class=&quot;warn&quot;&gt;
&lt;strong&gt;QNAM naming:&lt;/strong&gt; QNAM must be 8 characters or less, start with a letter, and contain only letters and digits. Do not rely on output truncation to save you. Validate QNAM values in the control dataset before generation.
&lt;/div&gt;

&lt;h2&gt;The Control Dataset Design&lt;/h2&gt;

&lt;p&gt;
The control dataset is the single source of truth for SUPPQUAL generation. Every QNAM you want to produce corresponds to one row. The control dataset should be maintained like any other programming spec and version-controlled with the study codebase.
&lt;/p&gt;

&lt;p&gt;
Below is a practical variable structure for &lt;code&gt;SUPPQUAL_META&lt;/code&gt;.
&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Variable&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Purpose&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;&lt;td&gt;RDOMAIN&lt;/td&gt;&lt;td&gt;Char(2)&lt;/td&gt;&lt;td&gt;Parent domain such as AE, CM, LB, EX, DM&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;QNAM&lt;/td&gt;&lt;td&gt;Char(8)&lt;/td&gt;&lt;td&gt;Supplemental qualifier name&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;QLABEL&lt;/td&gt;&lt;td&gt;Char(40)&lt;/td&gt;&lt;td&gt;Label for QNAM&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;SRC_DS&lt;/td&gt;&lt;td&gt;Char(41)&lt;/td&gt;&lt;td&gt;Source dataset, libname.memname or memname&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;SRC_VAR&lt;/td&gt;&lt;td&gt;Char(32)&lt;/td&gt;&lt;td&gt;Source variable in SRC_DS&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;IDVAR&lt;/td&gt;&lt;td&gt;Char(8)&lt;/td&gt;&lt;td&gt;Linking variable in SRC_DS, blank for DM-style domains&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;QORIG&lt;/td&gt;&lt;td&gt;Char(200)&lt;/td&gt;&lt;td&gt;Origin value&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;QEVAL&lt;/td&gt;&lt;td&gt;Char(8)&lt;/td&gt;&lt;td&gt;Evaluator, usually blank&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;SRC_ISNUM&lt;/td&gt;&lt;td&gt;Char(1)&lt;/td&gt;&lt;td&gt;Y if source variable is numeric, N if character&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;SRC_FMT&lt;/td&gt;&lt;td&gt;Char(32)&lt;/td&gt;&lt;td&gt;Optional numeric format for QVAL conversion&lt;/td&gt;&lt;/tr&gt;
    &lt;tr&gt;&lt;td&gt;ACTIVATE&lt;/td&gt;&lt;td&gt;Char(1)&lt;/td&gt;&lt;td&gt;Y to include, N to skip&lt;/td&gt;&lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;
A simple example:
&lt;/p&gt;

&lt;pre&gt;
/* Example: SUPPQUAL_META contents */
data SUPPQUAL_META;
  length rdomain $2 qnam $8 qlabel $40 src_ds $41 src_var $32
         idvar $8 qorig $200 qeval $8 src_isnum $1 src_fmt $32
         activate $1;
  infile datalines dlm=&#39;|&#39; truncover;
  input rdomain $ qnam $ qlabel $ src_ds $ src_var $
        idvar $ qorig $ qeval $ src_isnum $ src_fmt $ activate $;
datalines;
AE|AECNTRY|Country Where Event Occurred|WORK.AE_WORK|AECNTRY|AESEQ|CRF||N||Y
AE|AEREL2|Causality Second Study Drug|WORK.AE_WORK|CAUSDG2|AESEQ|CRF||N||Y
AE|AESLIFE|Resulted in Life Threatening|WORK.AE_WORK|SLIFE|AESEQ|CRF||N||Y
CM|CMDOSU2|Secondary Dose Unit|WORK.CM_WORK|DOSU2|CMSEQ|CRF||N||Y
CM|CMROUTE2|Secondary Route|WORK.CM_WORK|ROUTE2|CMSEQ|CRF||N||Y
DM|DMHISP|Hispanic or Latino|WORK.DM_WORK|HISPANIC||CRF||N||Y
EX|EXLOC|Location of Administration|WORK.EX_WORK|LOCATION|EXSEQ|CRF||N||Y
LB|LBANMETH|Analysis Method|WORK.LB_WORK|ANMETH|LBSEQ|CRF||N||Y
LB|LBDSTRESC|Derived Result Char|WORK.LB_WORK|DSTR|LBSEQ|Derived||N||Y
VS|VSMETHOD|Method of Measurement|WORK.VS_WORK|METHOD|VSSEQ|CRF||N||N
;
run;
&lt;/pre&gt;

&lt;div class=&quot;note&quot;&gt;
&lt;strong&gt;DM handling:&lt;/strong&gt; Because DM has one record per subject, SUPPDM should have blank IDVAR and IDVARVAL. That is valid and should not be treated as missing metadata.
&lt;/div&gt;

&lt;h2&gt;The Macro Architecture&lt;/h2&gt;

&lt;p&gt;
This design uses two macros. A helper macro, &lt;code&gt;%_supp_one&lt;/code&gt;, handles one QNAM row at a time. A driver macro, &lt;code&gt;%gen_suppqual&lt;/code&gt;, reads the control dataset, calls the helper for each active row, stacks the results, and writes one SUPP dataset per parent domain.
&lt;/p&gt;

&lt;p&gt;
That split matters. The helper is easier to test in isolation. The driver handles orchestration without mixing in domain-level data logic.
&lt;/p&gt;

&lt;div class=&quot;note&quot;&gt;
&lt;strong&gt;Assumption:&lt;/strong&gt; Every source dataset listed in &lt;code&gt;SRC_DS&lt;/code&gt; must already contain &lt;code&gt;STUDYID&lt;/code&gt; and &lt;code&gt;USUBJID&lt;/code&gt;. Do not point this macro directly at raw collection datasets that have not been standardized.
&lt;/div&gt;

&lt;div class=&quot;warn&quot;&gt;
&lt;strong&gt;Truncation risk:&lt;/strong&gt; &lt;code&gt;QLABEL&lt;/code&gt; is defined as $40 and &lt;code&gt;QVAL&lt;/code&gt; as $200. SAS truncates silently on assignment when the incoming value is longer. If your source variable can hold long free text, validate lengths before generation.
&lt;/div&gt;

&lt;h3&gt;Helper Macro: %_supp_one&lt;/h3&gt;

&lt;pre&gt;
/* ============================================================
   %_SUPP_ONE
   Internal helper. Processes one row from SUPPQUAL_META.
   Creates WORK._SUPP_&amp;i. as output.
   ============================================================ */
%macro _supp_one(
  i  = ,
  rd = ,
  qn = ,
  ql = ,
  sd = ,
  sv = ,
  iv = ,
  qo = CRF,
  qe = ,
  sn = N,
  sf =
);

  %local _dsid_ _varid_ _ivid_ _ivtype_ _qn_len_;

  /* 1. Validate source dataset exists */
  %let _dsid_ = %sysfunc(open(&amp;sd.));
  %if &amp;_dsid_. = 0 %then %do;
    %put WARNING: [_supp_one] Dataset &amp;sd. not found. Skipping QNAM=&amp;qn. (RDOMAIN=&amp;rd.);
    %return;
  %end;

  /* 2. Validate source variable exists */
  %let _varid_ = %sysfunc(varnum(&amp;_dsid_., &amp;sv.));
  %if &amp;_varid_. = 0 %then %do;
    %let _dsid_ = %sysfunc(close(&amp;_dsid_.));
    %put WARNING: [_supp_one] Variable &amp;sv. not found in &amp;sd.. Skipping QNAM=&amp;qn. (RDOMAIN=&amp;rd.);
    %return;
  %end;

  /* 3. Validate IDVAR and detect its type */
  %let _ivtype_ = C;
  %if %sysfunc(lengthn(%sysfunc(strip(&amp;iv.)))) &gt; 0 %then %do;
    %let _ivid_ = %sysfunc(varnum(&amp;_dsid_., &amp;iv.));
    %if &amp;_ivid_. = 0 %then %do;
      %let _dsid_ = %sysfunc(close(&amp;_dsid_.));
      %put WARNING: [_supp_one] IDVAR=&amp;iv. not found in &amp;sd.. Skipping QNAM=&amp;qn. (RDOMAIN=&amp;rd.);
      %return;
    %end;
    %let _ivtype_ = %sysfunc(vartype(&amp;_dsid_., &amp;_ivid_.));
  %end;

  %let _dsid_ = %sysfunc(close(&amp;_dsid_.));

  /* 4. Guard QNAM length in macro context before DATA step compile */
  %let _qn_len_ = %length(%sysfunc(strip(%upcase(&amp;qn.))));
  %if &amp;_qn_len_. &gt; 8 %then %do;
    %put WARNING: [_supp_one] QNAM=&amp;qn. is &amp;_qn_len_. characters and exceeds the 8-character limit.;
    %put WARNING: [_supp_one] Output will be truncated. Fix SUPPQUAL_META before submission.;
  %end;

  /* 5. Build one QNAM contribution dataset */
  data _supp_&amp;i_.
    (keep=studyid rdomain usubjid idvar idvarval qnam qlabel qval qorig qeval);

    length
      studyid  $200
      rdomain  $2
      usubjid  $200
      idvar    $8
      idvarval $200
      qnam     $8
      qlabel   $40
      qval     $200
      qorig    $200
      qeval    $8;

    set &amp;sd. (keep=studyid usubjid
                   %if %sysfunc(lengthn(%sysfunc(strip(&amp;iv.)))) &gt; 0 %then &amp;iv.;
                   &amp;sv.);

    rdomain = &quot;&amp;rd.&quot;;
    idvar   = &quot;%sysfunc(strip(&amp;iv.))&quot;;
    qnam    = &quot;%upcase(%sysfunc(strip(&amp;qn.)))&quot;;
    qlabel  = &quot;&amp;ql.&quot;;
    qorig   = &quot;&amp;qo.&quot;;
    qeval   = &quot;&amp;qe.&quot;;

    %if %sysfunc(lengthn(%sysfunc(strip(&amp;iv.)))) &gt; 0 %then %do;
      %if &amp;_ivtype_. = N %then %do;
        idvarval = strip(put(&amp;iv., best32.));
      %end;
      %else %do;
        idvarval = strip(&amp;iv.);
      %end;
    %end;
    %else %do;
      idvarval = &#39;&#39;;
    %end;

    %if %upcase(&amp;sn.) = Y %then %do;
      %if %sysfunc(lengthn(%sysfunc(strip(&amp;sf.)))) &gt; 0 %then %do;
        qval = strip(put(&amp;sv., &amp;sf..));
      %end;
      %else %do;
        qval = strip(put(&amp;sv., best32.));
      %end;
    %end;
    %else %do;
      qval = strip(&amp;sv.);
    %end;

    if missing(qval) then delete;
  run;

%mend _supp_one;
&lt;/pre&gt;

&lt;p&gt;
A few details here matter. &lt;code&gt;%sysfunc(vartype())&lt;/code&gt; detects whether IDVAR is numeric or character before the DATA step runs. That matters because most sequence variables are numeric in the parent dataset but must be written as character in IDVARVAL. Using &lt;code&gt;put(AESEQ, best32.)&lt;/code&gt; gives a clean unformatted value. Using &lt;code&gt;vvalue()&lt;/code&gt; would return the formatted value and can create the wrong result when custom formats exist.
&lt;/p&gt;

&lt;p&gt;
The QNAM length guard lives in macro context for a reason. Once QNAM is assigned to a DATA step variable declared as &lt;code&gt;$8&lt;/code&gt;, SAS truncates it immediately and silently. Any later &lt;code&gt;length(qnam)&lt;/code&gt; check in the DATA step is too late, the value has already been shortened. The macro check catches the original full control-dataset value before compilation.
&lt;/p&gt;

&lt;p&gt;
The &lt;code&gt;missing(qval)&lt;/code&gt; delete is not optional. If the qualifier has no data value, it should not be written out as a SUPP record.
&lt;/p&gt;

&lt;h3&gt;Driver Macro: %gen_suppqual&lt;/h3&gt;

&lt;pre&gt;
/* ============================================================
   %GEN_SUPPQUAL
   Driver macro. Reads SUPPQUAL_META, calls %_supp_one for
   each row, stacks results, and writes one SUPP dataset per
   parent domain to OUTLIB.
   ============================================================ */
%macro gen_suppqual(
  meta   = WORK.SUPPQUAL_META,
  outlib = WORK
);

  %local _nrows_ _i_ _any_created_ _domains_ _nd_ _d_ _dom_ _dsid_ _nobs_;

  /* 1. Validate metadata dataset exists */
  %if not %sysfunc(exist(&amp;meta.)) %then %do;
    %put ERROR: [gen_suppqual] Control dataset &amp;meta. not found. Macro aborted.;
    %return;
  %end;

  /* 2. Count active rows */
  proc sql noprint;
    select count(*) into :_nrows_ trimmed
    from &amp;meta.
    where not missing(rdomain)
      and not missing(qnam)
      and not missing(src_ds)
      and not missing(src_var)
      and upcase(coalescec(activate,&#39;Y&#39;)) = &#39;Y&#39;;
  quit;

  %if &amp;_nrows_. = 0 %then %do;
    %put WARNING: [gen_suppqual] No valid rows found in &amp;meta.. Macro aborted.;
    %return;
  %end;

  %put NOTE: [gen_suppqual] Found &amp;_nrows_. active QNAM entries to process.;

  /* 3. Load metadata into macro variable arrays */
  %do _i_ = 1 %to &amp;_nrows_.;
    %local _rd&amp;_i_. _qn&amp;_i_. _ql&amp;_i_. _sd&amp;_i_. _sv&amp;_i_.
           _iv&amp;_i_. _qo&amp;_i_. _qe&amp;_i_. _sn&amp;_i_. _sf&amp;_i_.;
  %end;

  proc sql noprint;
    select
      strip(rdomain),
      strip(qnam),
      strip(qlabel),
      strip(src_ds),
      strip(src_var),
      strip(coalescec(idvar,&#39;&#39;)),
      strip(coalescec(qorig,&#39;CRF&#39;)),
      strip(coalescec(qeval,&#39;&#39;)),
      strip(coalescec(src_isnum,&#39;N&#39;)),
      strip(coalescec(src_fmt,&#39;&#39;))
    into
      :_rd1 - :_rd&amp;_nrows_.,
      :_qn1 - :_qn&amp;_nrows_.,
      :_ql1 - :_ql&amp;_nrows_.,
      :_sd1 - :_sd&amp;_nrows_.,
      :_sv1 - :_sv&amp;_nrows_.,
      :_iv1 - :_iv&amp;_nrows_.,
      :_qo1 - :_qo&amp;_nrows_.,
      :_qe1 - :_qe&amp;_nrows_.,
      :_sn1 - :_sn&amp;_nrows_.,
      :_sf1 - :_sf&amp;_nrows_.
    from &amp;meta.
    where not missing(rdomain)
      and not missing(qnam)
      and not missing(src_ds)
      and not missing(src_var)
      and upcase(coalescec(activate,&#39;Y&#39;)) = &#39;Y&#39;
    order by rdomain, qnam;
  quit;

  /* 4. Call helper macro */
  %do _i_ = 1 %to &amp;_nrows_.;
    %_supp_one(
      i  = &amp;_i_.,
      rd = &amp;&amp;_rd&amp;_i_.,
      qn = &amp;&amp;_qn&amp;_i_.,
      ql = &amp;&amp;_ql&amp;_i_.,
      sd = &amp;&amp;_sd&amp;_i_.,
      sv = &amp;&amp;_sv&amp;_i_.,
      iv = &amp;&amp;_iv&amp;_i_.,
      qo = &amp;&amp;_qo&amp;_i_.,
      qe = &amp;&amp;_qe&amp;_i_.,
      sn = &amp;&amp;_sn&amp;_i_.,
      sf = &amp;&amp;_sf&amp;_i_.
    );
  %end;

  /* 5. Check output existence */
  %let _any_created_ = 0;
  %do _i_ = 1 %to &amp;_nrows_.;
    %if %sysfunc(exist(work._supp_&amp;_i_.)) %then %let _any_created_ = 1;
  %end;

  %if &amp;_any_created_. = 0 %then %do;
    %put WARNING: [gen_suppqual] No contribution datasets created. Check source datasets and variable names.;
    %return;
  %end;

  /* 6. Stack all contributions */
  data _supp_all_;
    set
    %do _i_ = 1 %to &amp;_nrows_.;
      %if %sysfunc(exist(work._supp_&amp;_i_.)) %then work._supp_&amp;_i_.;
    %end;
    ;
  run;

  /* 7. Get list of represented domains */
  proc sql noprint;
    select distinct strip(rdomain) into :_domains_ separated by &#39;|&#39;
    from _supp_all_
    where not missing(rdomain);

    select count(distinct rdomain) into :_nd_ trimmed
    from _supp_all_
    where not missing(rdomain);
  quit;

  /* 8. Write one SUPP dataset per domain */
  %do _d_ = 1 %to &amp;_nd_.;
    %let _dom_ = %scan(&amp;_domains_., &amp;_d_., |);

    proc sort
      data=_supp_all_(where=(rdomain=&quot;&amp;_dom_.&quot;))
      out=&amp;outlib..supp&amp;_dom_.(label=&quot;Supplemental Qualifiers for %upcase(&amp;_dom_.)&quot;);
      by studyid rdomain usubjid idvar idvarval qnam;
    run;

    %let _dsid_ = %sysfunc(open(&amp;outlib..supp&amp;_dom_.));
    %let _nobs_ = %sysfunc(attrn(&amp;_dsid_., nobs));
    %let _dsid_ = %sysfunc(close(&amp;_dsid_.));

    %put NOTE: [gen_suppqual] &amp;outlib..SUPP&amp;_dom_. created with &amp;_nobs_. observations.;
  %end;

  /* 9. Clean up */
  proc datasets lib=work nolist nowarn;
    delete _supp_:;
  quit;

  %put NOTE: [gen_suppqual] Complete. &amp;_nd_. SUPP dataset(s) written to &amp;outlib..;

%mend gen_suppqual;
&lt;/pre&gt;

&lt;h2&gt;Calling the Macro&lt;/h2&gt;

&lt;p&gt;
Once the control dataset is ready and the macros are compiled, generation becomes a single call.
&lt;/p&gt;

&lt;pre&gt;
%validate_meta(meta=SDTM.SUPPQUAL_META);
%gen_suppqual(meta=SDTM.SUPPQUAL_META, outlib=SDTM);
&lt;/pre&gt;

&lt;p&gt;
The SAS log should show one NOTE per created SUPP dataset along with the observation count. Any source-dataset or source-variable mismatches should produce clear WARNING messages that point back to the relevant QNAM and RDOMAIN.
&lt;/p&gt;

&lt;h2&gt;Handling Numeric QVAL Variables&lt;/h2&gt;

&lt;p&gt;
Most SUPPQUAL values start as character variables. But some studies need numeric source variables carried into QVAL. The combination of &lt;code&gt;SRC_ISNUM&lt;/code&gt; and &lt;code&gt;SRC_FMT&lt;/code&gt; handles that cleanly.
&lt;/p&gt;

&lt;pre&gt;
data SUPPQUAL_META;
  set SUPPQUAL_META;
  if qnam = &#39;LBCALC&#39; then do;
    src_isnum = &#39;Y&#39;;
    src_fmt   = &#39;8.3&#39;;
  end;
run;
&lt;/pre&gt;

&lt;p&gt;
If &lt;code&gt;SRC_ISNUM=Y&lt;/code&gt; and &lt;code&gt;SRC_FMT&lt;/code&gt; is blank, the macro uses &lt;code&gt;best32.&lt;/code&gt;. If you need fixed decimal places preserved in QVAL, provide an explicit numeric format in the metadata.
&lt;/p&gt;

&lt;div class=&quot;note&quot;&gt;
&lt;strong&gt;Decimal display:&lt;/strong&gt; &lt;code&gt;best32.&lt;/code&gt; will turn 2.0 into &quot;2&quot;, not &quot;2.0&quot;. If decimal presentation matters, set &lt;code&gt;SRC_FMT&lt;/code&gt; to a value such as &lt;code&gt;8.2&lt;/code&gt;.
&lt;/div&gt;

&lt;h2&gt;Pinnacle 21 and Metadata Validation&lt;/h2&gt;

&lt;p&gt;
Correct macro output is not enough. You should validate the metadata before generation and check the output after generation.
&lt;/p&gt;

&lt;p&gt;
A practical validation macro is shown below. It checks QNAM length, QNAM naming pattern, uppercase consistency, and missing required fields before the driver macro runs.
&lt;/p&gt;

&lt;pre&gt;
/* ============================================================
   %VALIDATE_META
   Run before %GEN_SUPPQUAL. Aborts on any failure.
   ============================================================ */
%macro validate_meta(meta=WORK.SUPPQUAL_META, outlib=WORK);

  proc sql noprint;
    create table &amp;outlib.._meta_errors as

    select &#39;SD0083&#39; as check_id, rdomain, qnam,
           &#39;QNAM exceeds 8 characters&#39; as description
    from &amp;meta.
    where length(strip(qnam)) &gt; 8

    union all

    select &#39;SD0082&#39; as check_id, rdomain, qnam,
           &#39;QNAM fails naming convention&#39; as description
    from &amp;meta.
    where not prxmatch(&#39;/^[A-Za-z][A-Za-z0-9]{0,7}$/&#39;, strip(qnam))

    union all

    select &#39;FORMAT&#39; as check_id, rdomain, qnam,
           &#39;QNAM contains lowercase and should be uppercase in metadata&#39; as description
    from &amp;meta.
    where qnam ne upcase(qnam)

    union all

    select &#39;MISSING&#39; as check_id, rdomain, qnam,
           cats(&#39;Missing required field: &#39;,
                case
                  when missing(src_ds) then &#39;SRC_DS&#39;
                  when missing(src_var) then &#39;SRC_VAR&#39;
                  else &#39;RDOMAIN or QNAM&#39;
                end) as description
    from &amp;meta.
    where missing(src_ds)
       or missing(src_var)
       or missing(rdomain)
       or missing(qnam);
  quit;

  %local _nerr_;
  proc sql noprint;
    select count(*) into :_nerr_ trimmed
    from &amp;outlib.._meta_errors;
  quit;

  %if &amp;_nerr_. &gt; 0 %then %do;
    proc print data=&amp;outlib.._meta_errors noobs; run;
    %put ERROR: [validate_meta] &amp;_nerr_. validation issue(s) found in &amp;meta..;
    %put ERROR: [validate_meta] Fix metadata before calling %nrstr(%gen_suppqual).;
    %abort cancel;
  %end;
  %else %do;
    %put NOTE: [validate_meta] Metadata checks passed.;
  %end;

%mend validate_meta;
&lt;/pre&gt;

&lt;p&gt;
You should also run a post-generation duplicate check. Duplicate QNAM values for the same parent record are a common structural issue when the source working dataset has not been deduplicated correctly.
&lt;/p&gt;

&lt;pre&gt;
proc sort data=SDTM.SUPPAE nodupkey dupout=_dups_;
  by studyid rdomain usubjid idvar idvarval qnam;
run;

%if %sysfunc(exist(_dups_)) %then %do;
  %local _dsid_;
  %let _dsid_ = %sysfunc(open(_dups_));
  %if %sysfunc(attrn(&amp;_dsid_., nobs)) &gt; 0 %then
    %put WARNING: Duplicate QNAM records found in SUPPAE. Review source data.;
  %let _dsid_ = %sysfunc(close(&amp;_dsid_));
%end;
&lt;/pre&gt;

&lt;h2&gt;Extending the Approach&lt;/h2&gt;

&lt;p&gt;
This macro assumes the source variable lives in the same dataset that already contains STUDYID, USUBJID, and the linking IDVAR. That is the cleanest pattern and the one most teams should aim for. If your supplemental variable lives elsewhere and needs to be joined back to the parent domain to obtain the sequence number, do that in a preprocessing step. Keep the SUPPQUAL macro focused on extraction and formatting, not on dataset joins.
&lt;/p&gt;

&lt;p&gt;
The same metadata can also help feed define.xml generation. QNAM, QLABEL, QORIG, and QEVAL already exist in the control dataset, so you are not maintaining the same information in two different places.
&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;
A metadata-driven SUPPQUAL framework does not remove complexity. It moves it into one controlled dataset where it is visible, testable, and easier to maintain. The macros shown here handle the main technical requirements, IDVAR type detection, numeric-to-character conversion, blank IDVAR handling for one-record-per-subject domains, QVAL exclusion when missing, and output sorted into submission-ready SUPP datasets.
&lt;/p&gt;

&lt;p&gt;
The biggest payoff comes when the specification changes. Adding a new QNAM becomes a metadata change, not a program rewrite.
&lt;/p&gt;

&lt;p&gt;
For regulated studies, keep these macros in a controlled and versioned macro library. Do not pull production macros from ad hoc URLs at runtime. The code used for submission work should come from a locked, auditable source.
&lt;/p&gt;

&lt;p&gt;
Source-aligned with SDTMIG v3.3 Section 8.4. Numeric-to-character IDVARVAL conversion using &lt;code&gt;best32.&lt;/code&gt; is consistent with SAS 9.4 behavior. Validation outcomes should still be checked against the Pinnacle 21 version defined in the study validation plan.
&lt;/p&gt;

&lt;hr style=&quot;margin-top:48px; border:0; border-top:1px solid #dddddd;&quot;&gt;
&lt;p class=&quot;tags&quot;&gt;
Tags: SDTM, SUPPQUAL, SAS Macros, Metadata-Driven Programming, Define.xml, Pinnacle 21, Regulatory Submissions
&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/8138307078881198116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/8138307078881198116'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/04/dynamic-suppqual-generation-using.html' title='Dynamic SUPPQUAL Generation Using Metadata-Driven SAS Macros'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-2910300344123038701</id><published>2026-04-01T13:12:00.004-04:00</published><updated>2026-04-01T13:14:26.520-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Automate QC Checks"/><category scheme="http://www.blogger.com/atom/ns#" term="SDTM QC Checks"/><title type='text'>Cross-domain SDTM QC Checks You Should Automate, With SAS Snippets</title><content type='html'>&lt;body&gt;

&lt;p class=&quot;post-meta&quot;&gt;SDTM Programming &amp;#183; SAS &amp;#183; Submission QC &amp;#183; Pinnacle 21 &amp;#183; Define.xml&lt;/p&gt;

&lt;h1&gt;&lt;/h1&gt;

&lt;p&gt;Most SDTM QC still stops at domain‑level review and Pinnacle 21 output.&lt;/p&gt;

&lt;p&gt;That leaves a big gap.&lt;/p&gt;

&lt;p&gt;A study can be structurally clean and still fail basic cross‑domain logic. AE timing can conflict with EX. Death can exist in DM without a matching DS record. RFSTDTC can disagree with the earliest exposure date. None of that is rare. None of it should be left to manual review.&lt;/p&gt;

&lt;p&gt;If you want stronger SDTM, automate the checks that validate how domains work together, not just whether each domain looks correct in isolation.&lt;/p&gt;

&lt;p&gt;These are not meant to replace protocol review, medical review, or P21. They are meant to catch the quiet, cross‑domain failures that sit between them.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Why Cross-domain QC Matters&lt;/h2&gt;

&lt;p&gt;P21 validates conformance.&lt;/p&gt;
&lt;p&gt;Cross‑domain QC validates coherence.&lt;/p&gt;

&lt;p&gt;That is the difference between:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a dataset that follows SDTM rules&lt;/li&gt;
  &lt;li&gt;and a dataset that actually represents the study correctly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The most expensive issues in submission work usually live in that second category.&lt;/p&gt;

&lt;div class=&quot;callout&quot;&gt;
These are not edge cases. This is where most real submission issues live.
&lt;/div&gt;

&lt;hr&gt;

&lt;h2&gt;A Good Rule Before Writing Any Check&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Chronology&lt;/strong&gt;: Did events happen in a clinically possible order?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Consistency&lt;/strong&gt;: Do anchor variables agree across domains?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Completeness&lt;/strong&gt;: Is a required partner record present somewhere else?&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Traceability&lt;/strong&gt;: Does a claimed relationship actually resolve?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If a check does not answer one of those questions, it is probably better handled elsewhere.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;1. AE Start Date Before First Exposure&lt;/h2&gt;

&lt;p&gt;This is one of the most useful cross‑domain checks. An AE that starts before first exposure is not always wrong — it may reflect pre‑treatment conditions or prior medical history that the protocol is capturing — but it should always be flagged and reviewed.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;proc sql;
  create table ex_first as
  select usubjid,
         min(input(exstdtc, ?? is8601da.)) as first_exdt format=date9.
  from sdtm.ex
  where not missing(exstdtc)
  group by usubjid;
quit;

proc sql;
  create table qc_ae_before_ex as
  select a.usubjid, a.aeseq, a.aestdtc, e.first_exdt
  from sdtm.ae as a
  left join ex_first as e
    on a.usubjid = e.usubjid
  where input(a.aestdtc, ?? is8601da.) &amp;lt; e.first_exdt;
quit;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Issues that show up here often include bad date mapping, wrong reference dates, or AE‑related timing logic that clashes with protocol‑defined treatment‑emergent assumptions.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;2. DM RFSTDTC vs Earliest EXSTDTC&lt;/h2&gt;

&lt;p&gt;If &lt;code&gt;RFSTDTC&lt;/code&gt; is the date of first study treatment, it should match the earliest exposure date in EX for that subject. When they disagree, every downstream day‑based calculation built from &lt;code&gt;RFSTDTC&lt;/code&gt; becomes suspect.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;proc sql;
  create table ex_first as
  select usubjid,
         min(input(exstdtc, ?? is8601da.)) as first_exdt format=date9.
  from sdtm.ex
  where not missing(exstdtc)
  group by usubjid;
quit;

data qc_dm_rfstdtc_mismatch;
  set sdtm.dm;
  rfstdt = input(rfstdtc, ?? is8601da.);
run;

proc sql;
  create table qc_dm_rfstdtc_mismatch as
  select d.usubjid, d.rfstdtc, e.first_exdt format=date9.
  from qc_dm_rfstdtc_mismatch as d
  left join ex_first as e
    on d.usubjid = e.usubjid
  where not missing(d.rfstdt) and not missing(e.first_exdt)
    and d.rfstdt ne e.first_exdt;
quit;&lt;/code&gt;&lt;/pre&gt;

&lt;hr&gt;

&lt;h2&gt;3. DM Death Without DS Record&lt;/h2&gt;

&lt;p&gt;If &lt;code&gt;DTHFL = &quot;Y&quot;&lt;/code&gt; or &lt;code&gt;DTHDTC&lt;/code&gt; is populated in DM, there should usually be a corresponding DS record that reflects the subject’s disposition tied to death. A mismatch undermines the death-disposition narrative for the reviewer.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;proc sql;
  create table qc_dm_death_no_ds as
  select d.usubjid
  from sdtm.dm as d
  left join sdtm.ds as s
    on d.usubjid = s.usubjid
  where upcase(d.dthfl) = &quot;Y&quot;
    and missing(s.usubjid);
quit;&lt;/code&gt;&lt;/pre&gt;

&lt;hr&gt;

&lt;h2&gt;4. LB Outside Study Window&lt;/h2&gt;

&lt;p&gt;Lab records can look fine in isolation, but they become problematic when placed against the subject’s actual study window from DM (&lt;code&gt;RFSTDTC&lt;/code&gt; to &lt;code&gt;RFENDTC&lt;/code&gt;). This check catches labs that are genuinely out‑of‑window, mis‑mapped, or pulled into SDTM by mistake.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;proc sql;
  create table dm_window as
  select usubjid,
         input(rfstdtc, ?? is8601da.) as rfstdt format=date9.,
         input(rfendtc, ?? is8601da.) as rfendt format=date9.
  from sdtm.dm;
quit;

proc sql;
  create table qc_lb_outside_window as
  select l.usubjid, l.lbseq, l.lbdtc,
         d.rfstdt, d.rfendt
  from sdtm.lb as l
  left join dm_window as d
    on l.usubjid = d.usubjid
  where not missing(l.lbdtc)
    and (
         input(l.lbdtc, ?? is8601da.) &amp;lt; d.rfstdt
         or
         (not missing(d.rfendt) and input(l.lbdtc, ?? is8601da.) &amp;gt; d.rfendt)
        );
quit;&lt;/code&gt;&lt;/pre&gt;

&lt;hr&gt;

&lt;h2&gt;5. RELREC Link Resolution&lt;/h2&gt;

&lt;p&gt;A RELREC record is only useful if the referenced record actually exists. This is a classic cross‑domain traceability check. Broken RELREC links create false confidence rather than real traceability. This is one of the few checks where structure can be completely correct and still be functionally useless.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;%macro check_relrec(domain=, idvar=);
  proc sql;
    create table qc_relrec_&amp;amp;domain as
    select r.usubjid, r.rdomain, r.idvar, r.idvarval
    from sdtm.relrec as r
    left join sdtm.&amp;amp;domain as d
      on r.usubjid = d.usubjid
     and input(r.idvarval, best.) = d.&amp;amp;idvar
    where upcase(r.rdomain) = &quot;%upcase(&amp;amp;domain)&quot;
      and upcase(r.idvar) = &quot;%upcase(&amp;amp;idvar)&quot;
      and missing(d.usubjid);
  quit;
%mend;

%check_relrec(domain=ae, idvar=aeseq);
%check_relrec(domain=cm, idvar=cmseq);&lt;/code&gt;&lt;/pre&gt;

&lt;hr&gt;

&lt;h2&gt;6. VLM Coverage Gaps&lt;/h2&gt;

&lt;p&gt;If a value appears in the data but has no matching value-level metadata entry, that is a real documentation gap, even when the define.xml is technically valid.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;proc sql;
  create table suppae_qnam_data as
  select distinct upcase(qnam) as qnam
  from sdtm.suppae;

  create table suppae_qnam_meta as
  select distinct upcase(value) as qnam
  from meta.vlm
  where upcase(dataset) = &quot;SUPPAE&quot;
    and upcase(variable) = &quot;QNAM&quot;;

  create table qc_suppae_qnam_vlm_gap as
  select d.qnam
  from suppae_qnam_data as d
  left join suppae_qnam_meta as m
    on d.qnam = m.qnam
  where missing(m.qnam);
quit;&lt;/code&gt;&lt;/pre&gt;

&lt;hr&gt;

&lt;h2&gt;Building These Checks Into a Reusable SAS QC Framework&lt;/h2&gt;

&lt;p&gt;These checks are most useful when packaged as a shared macro library and QC findings layer used across studies, not as one‑off snippets in individual program folders.&lt;/p&gt;

&lt;p&gt;You can build them as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;standard macros (e.g., &lt;code&gt;%check_relrec&lt;/code&gt;, &lt;code&gt;%check_ae_ex_timing&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;standard QC datasets (one per check)&lt;/li&gt;
  &lt;li&gt;a standard reporting layer that appends all findings into a single QC findings dataset&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once that structure is in place, each new study can reuse the same logic with little customization.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;What You Should Automate First&lt;/h2&gt;

&lt;p&gt;If you are starting from scratch, automate these first:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;DM‑to‑EX date anchor checks (RFSTDTC vs earliest EXSTDTC)&lt;/li&gt;
  &lt;li&gt;AE‑to‑EX chronology (AE before first exposure)&lt;/li&gt;
  &lt;li&gt;DM‑to‑DS death consistency&lt;/li&gt;
  &lt;li&gt;LB‑to‑DM timeline (LB outside study window)&lt;/li&gt;
  &lt;li&gt;RELREC link resolution&lt;/li&gt;
  &lt;li&gt;VLM coverage for key variables&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These give you the fastest return on investment and form the backbone of a cross‑domain QC framework.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;What Automation Will Not Solve&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;mapping correctness&lt;/li&gt;
  &lt;li&gt;protocol interpretation&lt;/li&gt;
  &lt;li&gt;clinical judgment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Automation cannot replace those decisions. It can, however, force them into the open early by surfacing the inconsistencies they create.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Bottom Line&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Clean domains are not enough. The domains have to agree with each other.&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;closing&quot;&gt;
Cross‑domain QC is where SDTM moves from compliant to credible.
&lt;/div&gt;

&lt;/body&gt;
```</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/2910300344123038701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/2910300344123038701'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/04/html-sdtm-programming-sas-submission-qc.html' title='Cross-domain SDTM QC Checks You Should Automate, With SAS Snippets'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-8666477164473217878</id><published>2026-04-01T12:11:00.003-04:00</published><updated>2026-04-24T07:22:03.194-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="P21 Enterprise Issues"/><category scheme="http://www.blogger.com/atom/ns#" term="SDTM Validation"/><title type='text'>The Illusion of P21 Clean: Why Passing Validation Is Not Enough</title><content type='html'>&lt;style&gt;
  .post-body-wrap {
    font-family: Georgia, &#39;Times New Roman&#39;, serif;
    font-size: 17px;
    line-height: 1.9;
    color: #1a1a1a;
  }
  .post-body-wrap .post-meta {
    font-family: &#39;Courier New&#39;, monospace;
    font-size: 0.78em;
    color: #999;
    margin-bottom: 38px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
  }
  .post-body-wrap h2 {
    font-size: 1.3em;
    font-weight: 700;
    margin-top: 56px;
    margin-bottom: 12px;
    color: #111;
    border-left: 4px solid #c0392b;
    padding-left: 14px;
  }
  .post-body-wrap h3 {
    font-size: 1.05em;
    font-weight: 700;
    margin-top: 40px;
    margin-bottom: 4px;
    color: #c0392b;
  }
  .post-body-wrap p {
    margin: 0 0 20px;
  }
  .post-body-wrap ul {
    margin: 0 0 22px 0;
    padding-left: 22px;
  }
  .post-body-wrap li {
    margin-bottom: 10px;
  }
  .post-body-wrap code {
    font-family: &#39;Courier New&#39;, monospace;
    font-size: 0.86em;
    background: #f5f5f5;
    border: 1px solid #e2e2e2;
    padding: 1px 5px;
    border-radius: 3px;
    color: #c0392b;
  }
  .post-body-wrap .callout {
    background: #fafafa;
    border-left: 4px solid #2c3e50;
    padding: 18px 24px;
    margin: 34px 0;
    color: #333;
    font-size: 1.01em;
    font-style: italic;
  }
  .post-body-wrap .sanity-box {
    background: #f9f9f9;
    border: 1px solid #ddd;
    border-top: 3px solid #2c3e50;
    padding: 24px 28px;
    margin: 40px 0;
  }
  .post-body-wrap .sanity-box p {
    margin-bottom: 12px;
  }
  .post-body-wrap .sanity-box strong {
    display: block;
    font-size: 1.02em;
    margin-bottom: 10px;
    color: #111;
  }
  .post-body-wrap hr {
    border: none;
    border-top: 1px solid #e4e4e4;
    margin: 52px 0;
  }
&lt;/style&gt;

&lt;div class=&quot;post-body-wrap&quot;&gt;


&lt;p&gt;Most SDTM teams still treat a clean run in Pinnacle 21 Enterprise as the finish line. It isn&amp;#8217;t.&lt;/p&gt;

&lt;p&gt;It tells you one thing: your datasets passed a rule-based conformance check aligned to published standards such as the SDTM model, SDTM IG, controlled terminology, and define.xml schema.&lt;/p&gt;

&lt;p&gt;It does not tell you:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;if the data is clinically interpretable,&lt;/li&gt;
  &lt;li&gt;if the relationships across domains make sense,&lt;/li&gt;
  &lt;li&gt;if a reviewer can actually use the package without stopping to question it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That gap matters most in SDTM, because SDTM is the base layer of the submission. If SDTM distorts the study, everything downstream inherits that distortion, including define.xml, reviewer traceability, and the regulatory review itself.&lt;/p&gt;

&lt;p&gt;P21 clean means the package passed rules. It does not mean the package is correct.&lt;/p&gt;

&lt;p&gt;This is not a knock on Pinnacle 21 Enterprise. It is an essential tool. But essential and sufficient are not the same thing. Teams that treat them as the same end up confusing conformance with quality, and that is where avoidable submission risk starts.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;What P21 Actually Does&lt;/h2&gt;

&lt;p&gt;At its core, P21 is a conformance checker. It verifies that datasets and define.xml align with published CDISC standards. In practice, that means it checks things like dataset structure, required variable presence, type and length expectations, controlled terminology membership, schema validity for define.xml, and selected referential consistency such as &lt;code&gt;STUDYID&lt;/code&gt; or &lt;code&gt;USUBJID&lt;/code&gt; alignment.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Dataset structure&lt;/strong&gt;: required variables, expected data types, labels, and special-purpose domain formatting&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Controlled terminology compliance&lt;/strong&gt;: whether submitted values appear in the expected codelist&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Define.xml schema validity&lt;/strong&gt;: whether the metadata package is structurally valid under define.xml 2.0 or 2.1&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Selective referential checks&lt;/strong&gt;: subject and study identifiers, some foreign key relationships&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Metadata completeness at a structural level&lt;/strong&gt;: required datasets, SUPPQUAL structure, standard references&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That work is necessary. A P21-clean package is structurally safer than one that fails basic conformance. But the real review question is not, “Does this fit the standard?” It is, “Does this represent the study correctly?”&lt;/p&gt;

&lt;p&gt;P21 answers the first question. Reviewers care about the second.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;Where P21 Stays Silent&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;This is where many real submission problems live.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;1. Clinical Logic and Timeline Plausibility&lt;/h3&gt;

&lt;p&gt;P21 has no protocol awareness. It does not know that an adverse event start date before first dose may be impossible in context, or that a death flag in DM should usually line up with a death disposition record in DS, or that a 12‑week study should not show impossible subject‑level date sequences.&lt;/p&gt;

&lt;p&gt;Take a simple example. A subject has &lt;code&gt;AESTDTC = 2021-03-01&lt;/code&gt; and &lt;code&gt;EXSTDTC = 2021-04-15&lt;/code&gt;. That AE record can be structurally perfect and still raise immediate concern in review. Same for informed consent after first dose, fatal AE outcomes paired with completion disposition, or lab collection dates that sit outside the subject&amp;#8217;s actual study window.&lt;/p&gt;

&lt;p&gt;Those are not formatting failures. They are study representation failures.&lt;/p&gt;

&lt;h3&gt;2. EX Can Be Valid and Still Misrepresent Treatment&lt;/h3&gt;

&lt;p&gt;EX is where reviewers rebuild dosing history. P21 can tell you EX is structurally valid. It cannot tell you whether EX still reflects what actually happened.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Dosing interruptions flattened&lt;/strong&gt;: a two‑week treatment hold is absorbed into one continuous record&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Dose reductions collapsed&lt;/strong&gt;: multiple dosing episodes become one final‑dose record&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Administration detail lost&lt;/strong&gt;: cycle‑level summaries replace administration‑level records in settings where timing matters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once EX is flattened, downstream review breaks. AE timing, dose intensity, and treatment relationship all become harder to reconstruct, even though the dataset still passes validation.&lt;/p&gt;

&lt;h3&gt;3. LB Often Passes While the Standardization Is Wrong&lt;/h3&gt;

&lt;p&gt;LB is one of the easiest domains to make look clean. It is also one of the easiest places to hide quiet failures.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Reference ranges mismatch standardized units&lt;/strong&gt;: &lt;code&gt;LBSTRESN&lt;/code&gt; is converted, but &lt;code&gt;LBSTNRLO&lt;/code&gt; and &lt;code&gt;LBSTNRHI&lt;/code&gt; stay in the original unit&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cross‑vendor inconsistency&lt;/strong&gt;: the same &lt;code&gt;LBTESTCD&lt;/code&gt; is normalized differently across sites or lab vendors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Reviewers use LB heavily for safety review. If the units, ranges, or normalization logic are inconsistent, the problem is methodological, not structural. P21 will not rescue you from that.&lt;/p&gt;

&lt;h3&gt;4. Traceability and Domain Design Failures&lt;/h3&gt;

&lt;p&gt;Some of the most damaging submission issues are not dataset‑format issues at all. They are design and traceability issues.&lt;/p&gt;

&lt;p&gt;SUPPQUAL is a common example. A SUPP-- domain can be perfectly valid while still being overloaded with clinically important qualifiers that should have stayed in the parent domain. When reviewers must manually reconstruct central interpretation variables by merging supplemental qualifiers back into &lt;code&gt;AE&lt;/code&gt; or another parent domain, the design has already failed its reader.&lt;/p&gt;

&lt;p&gt;The same thing happens when mapping intent and mapping outcome drift apart. A procedure ends up modeled like an event in the wrong class. A topic variable holds the wrong kind of concept. The record is valid in shape but wrong in meaning. Reviewers do not experience that as a standards issue. They experience it as untrustworthy data.&lt;/p&gt;

&lt;p&gt;RELREC has the same risk. It may be structurally sound while still pointing to nonexistent records, incomplete relationships, or clinically meaningless links. A technically valid relationship structure that nobody can follow is not doing its job.&lt;/p&gt;

&lt;h3&gt;5. Trial Design and Define.xml Coverage Gaps&lt;/h3&gt;

&lt;p&gt;Trial design domains and define.xml often look better in validation output than they do in actual review.&lt;/p&gt;

&lt;p&gt;P21 can confirm that &lt;code&gt;TA&lt;/code&gt;, &lt;code&gt;TE&lt;/code&gt;, &lt;code&gt;TV&lt;/code&gt;, &lt;code&gt;TI&lt;/code&gt;, and &lt;code&gt;TS&lt;/code&gt; have the right structure. It cannot confirm that the arm design, element order, visit structure, or epoch assumptions actually reflect the protocol and what subjects experienced.&lt;/p&gt;

&lt;p&gt;The same applies to define.xml. Schema‑valid does not mean review‑ready.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Missing value‑level metadata coverage&lt;/strong&gt;: actual &lt;code&gt;QNAM&lt;/code&gt;, &lt;code&gt;LBTESTCD&lt;/code&gt;, or &lt;code&gt;VSTESTCD&lt;/code&gt; values appear in data but not in VLM&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Weak origin documentation&lt;/strong&gt;: variables are tagged &lt;code&gt;Origin = &quot;Derived&quot;&lt;/code&gt; with no useful computational method&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Metadata that documents structure but not logic&lt;/strong&gt;: technically valid, but not enough for reviewer traceability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A define.xml that passes schema checks but does not explain what the reviewer needs to understand is still a weak define.xml.&lt;/p&gt;

&lt;h3&gt;6. Controlled Terminology Can Be Right on Paper and Wrong in Context&lt;/h3&gt;

&lt;p&gt;P21 checks whether a value exists in the expected codelist. It does not know whether the chosen term is the right one for the record.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;DSDECOD&lt;/code&gt; value may be codelist‑compliant and still clash with the subject&amp;#8217;s actual AE history. &lt;code&gt;AESER = &quot;Y&quot;&lt;/code&gt; may be populated without any seriousness criterion that makes the record clinically coherent. A standardized medication or medical history term can be formally allowed and still be wrong in context.&lt;/p&gt;

&lt;p&gt;That is the difference between terminology membership and clinical correctness. P21 checks one. Reviewers judge the other.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;What Reviewers Actually Do with SDTM&lt;/h2&gt;

&lt;p&gt;Reviewers do not think in terms of “P21 clean.” They open define.xml, move into &lt;code&gt;AE&lt;/code&gt;, &lt;code&gt;EX&lt;/code&gt;, &lt;code&gt;LB&lt;/code&gt;, &lt;code&gt;DM&lt;/code&gt;, &lt;code&gt;DS&lt;/code&gt;, and trial design domains, and try to rebuild the subject story. They ask simple questions.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Can I follow exposure history from EX?&lt;/li&gt;
  &lt;li&gt;Can I line up AEs against dosing?&lt;/li&gt;
  &lt;li&gt;Can I trust the study epochs and visit structure?&lt;/li&gt;
  &lt;li&gt;Can I move from dataset to metadata and back without confusion?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is no, they raise questions even when the package is technically compliant. Review is not just a conformance exercise. It is a clinical audit.&lt;/p&gt;

&lt;p&gt;This is why P21 clean is a gate, not a verdict.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;The Severity Tier Problem&lt;/h2&gt;

&lt;p&gt;Even when P21 does find issues, teams often misread the severity hierarchy.&lt;/p&gt;

&lt;p&gt;In many organizations, the unwritten workflow is simple: fix Errors, selectively review Warnings, ignore Notices. That sounds practical, but the severity tiers are tied to standards language, not to what a reviewer will care about most.&lt;/p&gt;

&lt;p&gt;Some warnings that get waved through too easily:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;SD0052&lt;/strong&gt;: non‑standard variable labels that later create metadata confusion&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SD0083&lt;/strong&gt;: variables in define.xml but not in the dataset, often a real build or metadata‑sync problem&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SD0256 / SD0257&lt;/strong&gt;: date‑format inconsistencies that may be intentional, but still need to be explained clearly in metadata&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notices are often treated as background noise, even though unusual value patterns, rare coded terms, and odd visit distributions are exactly the things that can point to real mapping problems.&lt;/p&gt;

&lt;div class=&quot;callout&quot;&gt;
  P21 severity reflects standards conformance logic. It does not map cleanly to reviewer concern. Treating those two hierarchies as the same is where teams get surprised.
&lt;/div&gt;

&lt;hr&gt;

&lt;h2&gt;What Robust QC Actually Looks Like&lt;/h2&gt;

&lt;p&gt;A P21‑clean package is the floor. Submission‑ready work needs another layer.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Cross‑domain temporal checks&lt;/strong&gt;: AE against EX, DS against AE outcomes, LB against DM windows, MH against subject reference dates&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;EX completeness checks&lt;/strong&gt;: separate records for interruptions, reductions, and distinct administrations where needed&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;LB consistency checks&lt;/strong&gt;: unit conversion logic, standardized ranges, site‑level and vendor‑level consistency by test&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;DM reference‑date checks&lt;/strong&gt;: &lt;code&gt;RFSTDTC&lt;/code&gt; against earliest EX, death variables against DS, reference dates in plausible order&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Define.xml coverage checks&lt;/strong&gt;: actual dataset values cross‑checked against VLM entries&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Trial design reconciliation&lt;/strong&gt;: TA, TE, TV, TI, and TS reviewed against protocol and actual study conduct&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;RELREC validation&lt;/strong&gt;: verify that linked identifiers actually exist and represent useful relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And then there is the step that catches more than teams like to admit.&lt;/p&gt;

&lt;p&gt;Have one programmer act like a reviewer. Start from the cSDRG or define.xml. Follow variable origins. Rebuild a few subject‑level stories end to end. Any confusion there is not theoretical. It is a likely review problem waiting to happen.&lt;/p&gt;

&lt;hr&gt;

&lt;h2&gt;The One‑Subject Test&lt;/h2&gt;

&lt;div class=&quot;sanity-box&quot;&gt;
  &lt;strong&gt;Before submission, do this once.&lt;/strong&gt;
  &lt;p&gt;Pick one subject, ideally someone with an AE, a dose change, and at least one out‑of‑range lab result.&lt;/p&gt;
  &lt;p&gt;Now try to:&lt;/p&gt;
  &lt;ul style=&quot;margin-bottom: 14px;&quot;&gt;
    &lt;li&gt;reconstruct the full dosing history from EX alone,&lt;/li&gt;
    &lt;li&gt;align AEs against exposure using &lt;code&gt;--DY&lt;/code&gt; variables,&lt;/li&gt;
    &lt;li&gt;review LB trends with the correct normalized units and reference ranges,&lt;/li&gt;
    &lt;li&gt;confirm the study epoch from trial design and findings domains,&lt;/li&gt;
    &lt;li&gt;trace disposition through DS and confirm the reference dates in DM agree.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p&gt;If that exercise is slow, confusing, or full of workarounds, the issue is not validation. The issue is SDTM quality.&lt;/p&gt;
  &lt;p&gt;P21 will not run that test for you.&lt;/p&gt;
&lt;/div&gt;

&lt;hr&gt;

&lt;h2&gt;The Deeper Issue&lt;/h2&gt;

&lt;p&gt;The bigger problem is not the tool. The bigger problem is what teams ask the tool to stand in for.&lt;/p&gt;

&lt;p&gt;P21 was built to check conformance. It does that well. But many submission pipelines quietly promote it into a proxy for clinical consistency, metadata adequacy, and overall package quality. That is a category mistake.&lt;/p&gt;

&lt;p&gt;Conformance means the data fits the standard. Quality means the data represents the study faithfully, holds together across domains, remains traceable from source to dataset to define.xml, and can survive a competent reviewer trying to audit it.&lt;/p&gt;

&lt;p&gt;Those are not the same thing.&lt;/p&gt;

&lt;p&gt;P21 can tell you that &lt;code&gt;EPOCH&lt;/code&gt; is spelled correctly and drawn from the right codelist. It cannot tell you that &lt;code&gt;EPOCH = &quot;TREATMENT&quot;&lt;/code&gt; on a pre‑dose record is wrong. It can tell you EX is structurally valid. It cannot tell you a collapsed exposure history has erased the real dosing story. It can tell you define.xml is schema‑valid. It cannot tell you whether the reviewer can actually follow your logic.&lt;/p&gt;

&lt;p&gt;That judgment still lives with the people building the submission.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clean SDTM passes validation. Strong SDTM survives review. Those are not the same bar.&lt;/</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/8666477164473217878'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/8666477164473217878'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/04/the-illusion-of-p21-clean-why-passing.html' title='The Illusion of P21 Clean: Why Passing Validation Is Not Enough'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-7106011471908909269</id><published>2026-03-30T21:45:00.005-04:00</published><updated>2026-04-03T13:25:35.914-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Character Encoding"/><category scheme="http://www.blogger.com/atom/ns#" term="Japanese Text"/><category scheme="http://www.blogger.com/atom/ns#" term="SDTM Package"/><title type='text'>Character Encoding, Japanese Text, and Why Your SDTM Package Can Fail Even When the Data Logic Is Fine</title><content type='html'>&lt;div class=&quot;studysas-post&quot;&gt;
  &lt;style&gt;
    .studysas-post {
      font-family: Arial, Helvetica, sans-serif;
      color: #1f2937;
      line-height: 1.75;
      font-size: 16px;
      max-width: 900px;
      margin: 0 auto;
    }

    .studysas-hero {
      background: linear-gradient(135deg, #0f172a, #1e3a8a);
      color: #ffffff;
      padding: 36px 28px;
      border-radius: 14px;
      margin-bottom: 28px;
    }

    .studysas-kicker {
      font-size: 13px;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      font-weight: 700;
      color: #c7d2fe;
      margin-bottom: 10px;
    }

    .studysas-title {
      font-size: 34px;
      line-height: 1.25;
      font-weight: 700;
      margin: 0 0 14px 0;
      color: #ffffff !important;
      text-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
    }

    .highlight-main {
      color: #60a5fa;
      font-weight: 700;
    }

    .highlight-accent {
      color: #93c5fd;
    }

    .studysas-subtitle {
      font-size: 17px;
      color: #dbeafe;
      margin: 0;
    }

    .studysas-card {
      background: #ffffff;
      border: 1px solid #e5e7eb;
      border-radius: 14px;
      padding: 26px 24px;
      margin: 22px 0;
      box-shadow: 0 2px 10px rgba(15, 23, 42, 0.04);
    }

    .studysas-card h2 {
      font-size: 25px;
      line-height: 1.3;
      margin: 0 0 14px 0;
      color: #0f172a;
    }

    .studysas-card h3 {
      font-size: 20px;
      line-height: 1.4;
      margin: 24px 0 10px 0;
      color: #1e3a8a;
    }

    .studysas-card p {
      margin: 0 0 16px 0;
    }

    .studysas-card ul {
      margin: 10px 0 16px 22px;
      padding: 0;
    }

    .studysas-card li {
      margin-bottom: 8px;
    }

    .studysas-callout {
      background: #eff6ff;
      border-left: 5px solid #2563eb;
      padding: 16px 18px;
      border-radius: 10px;
      margin: 18px 0;
      color: #1e3a8a;
      font-weight: 600;
    }

    .studysas-warning {
      background: #fff7ed;
      border-left: 5px solid #ea580c;
      padding: 16px 18px;
      border-radius: 10px;
      margin: 18px 0;
      color: #9a3412;
      font-weight: 600;
    }

    .studysas-note {
      background: #f8fafc;
      border: 1px solid #e2e8f0;
      padding: 16px 18px;
      border-radius: 10px;
      margin: 18px 0;
    }

    .studysas-code {
      background: #0f172a;
      color: #e2e8f0;
      border-radius: 12px;
      padding: 18px;
      overflow-x: auto;
      font-family: Consolas, Monaco, monospace;
      font-size: 14px;
      line-height: 1.6;
      margin: 18px 0;
      white-space: pre-wrap;
    }

    .studysas-section-label {
      display: inline-block;
      background: #dbeafe;
      color: #1d4ed8;
      font-size: 12px;
      font-weight: 700;
      letter-spacing: 0.04em;
      text-transform: uppercase;
      padding: 6px 10px;
      border-radius: 999px;
      margin-bottom: 12px;
    }

    .studysas-closing {
      background: #0f172a;
      color: #f8fafc;
      border-radius: 14px;
      padding: 24px;
      margin-top: 24px;
    }

    .studysas-closing h2 {
      color: #ffffff;
      margin-top: 0;
    }

    .studysas-small {
      font-size: 14px;
      color: #475569;
    }

    .studysas-sources ul {
      margin-top: 8px;
    }

    .studysas-sources a {
      color: #1d4ed8;
      text-decoration: none;
    }

    .studysas-sources a:hover {
      text-decoration: underline;
    }

    @media (max-width: 768px) {
      .studysas-title {
        font-size: 28px;
      }

      .studysas-card {
        padding: 20px 18px;
      }

      .studysas-hero {
        padding: 28px 20px;
      }
    }
  &lt;/style&gt;


  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;p&gt;Your SDTM derivations are correct.&lt;br&gt;
    Your P21 run is clean.&lt;br&gt;
    Your define.xml opens and looks fine.&lt;/p&gt;

    &lt;p&gt;And yet, the package still trips up in review.&lt;/p&gt;

    &lt;p&gt;Not because of the data.&lt;br&gt;
    Because of encoding.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;PMDA expectation&lt;/div&gt;
    &lt;h2&gt;What PMDA expects, and why it trips teams&lt;/h2&gt;

    &lt;p&gt;PMDA’s Technical Conformance Guide states that if languages other than English are used, including Japanese, the character set and encoding scheme must be documented in the reviewer’s guide.&lt;/p&gt;

    &lt;p class=&quot;studysas-small&quot;&gt;&lt;em&gt;Source: PMDA Technical Conformance Guide on Electronic Study Data Submissions, April 2024&lt;/em&gt;&lt;/p&gt;

    &lt;p&gt;This is not a footnote. It shows up in real submissions when XML, metadata, or reviewer tools fail to render text consistently.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Common misunderstanding&lt;/div&gt;
    &lt;h2&gt;The key misunderstanding&lt;/h2&gt;

    &lt;p&gt;Many teams assume:&lt;/p&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      “We’ll just use ASCII.”
    &lt;/div&gt;

    &lt;p&gt;The actual expectation is:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Use Unicode, typically UTF-8, as the working encoding&lt;/li&gt;
      &lt;li&gt;Restrict dataset content to ASCII-compatible characters where required&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;These are not the same thing.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Root constraint&lt;/div&gt;
    &lt;h2&gt;The XPT format limitation that drives the whole problem&lt;/h2&gt;

    &lt;p&gt;SDTM datasets are submitted in &lt;strong&gt;SAS Transport v5 (XPT)&lt;/strong&gt; format.&lt;/p&gt;

    &lt;p&gt;That format:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;was designed for US-ASCII exchange&lt;/li&gt;
      &lt;li&gt;has no encoding metadata in the file header&lt;/li&gt;
      &lt;li&gt;does not tell the receiver what encoding was used&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-warning&quot;&gt;
      The receiving system has to guess the encoding.
    &lt;/div&gt;

    &lt;p&gt;When SAS opens an XPT file created in a different encoding, it attempts transcoding.&lt;/p&gt;

    &lt;p&gt;That can result in:&lt;/p&gt;

    &lt;div class=&quot;studysas-code&quot;&gt;WARNING: Some character data was lost during transcoding in the dataset.&lt;/div&gt;

    &lt;p&gt;That message does not identify the variable or the observation.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Your data can be corrupted silently.&lt;/strong&gt;&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Programming consequence&lt;/div&gt;
    &lt;h2&gt;Byte limits, not character limits&lt;/h2&gt;

    &lt;p&gt;XPT constraints are in &lt;strong&gt;bytes&lt;/strong&gt;, not characters.&lt;/p&gt;

    &lt;p&gt;For UTF-8 encoded Japanese text, one character typically uses about 3 bytes.&lt;/p&gt;

    &lt;div class=&quot;studysas-note&quot;&gt;
      &lt;strong&gt;Practical effect:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      40-byte label → about 13 Japanese characters&lt;br&gt;
      200-byte variable → about 66 Japanese characters
    &lt;/div&gt;

    &lt;p&gt;This affects:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;variable lengths&lt;/li&gt;
      &lt;li&gt;labels&lt;/li&gt;
      &lt;li&gt;define.xml metadata&lt;/li&gt;
      &lt;li&gt;macro logic that assumes character counts&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Failure points&lt;/div&gt;
    &lt;h2&gt;Where encoding actually breaks&lt;/h2&gt;

    &lt;p&gt;Encoding problems do not usually show up during mapping. They surface later:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;XML rendering&lt;/li&gt;
      &lt;li&gt;stylesheet loading&lt;/li&gt;
      &lt;li&gt;reviewer-side tools&lt;/li&gt;
      &lt;li&gt;XPT read and write&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Common failure patterns include:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;define.xml renders incorrectly&lt;/li&gt;
      &lt;li&gt;XML parsing fails&lt;/li&gt;
      &lt;li&gt;dataset comments become unreadable&lt;/li&gt;
      &lt;li&gt;XPT import causes truncation&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Pipeline cracks&lt;/div&gt;
    &lt;h2&gt;Where the cracks really come from&lt;/h2&gt;

    &lt;h3&gt;SAS session encoding&lt;/h3&gt;
    &lt;p&gt;If SAS is not UTF-8:&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;transcoding occurs&lt;/li&gt;
      &lt;li&gt;data may be altered silently&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      Recommended setup: SAS session encoding = UTF-8
    &lt;/div&gt;

    &lt;h3&gt;XML generation&lt;/h3&gt;
    &lt;p&gt;XML requires strict consistency:&lt;/p&gt;

    &lt;div class=&quot;studysas-code&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/div&gt;

    &lt;p&gt;If the declared encoding does not match the actual encoding, parsing issues follow.&lt;/p&gt;

    &lt;h3&gt;External tools&lt;/h3&gt;
    &lt;p&gt;Excel, Notepad, and XML editors often change encoding silently or introduce hidden characters.&lt;/p&gt;

    &lt;h3&gt;Manual edits&lt;/h3&gt;
    &lt;p&gt;Opening and saving XML manually can change encoding without warning.&lt;/p&gt;

    &lt;h3&gt;Copy and paste risk&lt;/h3&gt;
    &lt;p&gt;Copying from Word or email can introduce hidden non-ASCII characters.&lt;/p&gt;

    &lt;div class=&quot;studysas-note&quot;&gt;
      The non-ASCII scan macro below will surface these characters before handoff. That is why running it late in the build cycle, not just at the start, matters.
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Build-chain warning&lt;/div&gt;
    &lt;h2&gt;CPORT is not XPT&lt;/h2&gt;

    &lt;p&gt;Do not use &lt;strong&gt;PROC CPORT&lt;/strong&gt; for submission datasets.&lt;/p&gt;

    &lt;p&gt;Even if the file extension is &lt;code&gt;.xpt&lt;/code&gt;, CPORT does &lt;strong&gt;not&lt;/strong&gt; create XPT v5 format.&lt;/p&gt;

    &lt;div class=&quot;studysas-warning&quot;&gt;
      PMDA gateway cannot process CPORT files.
    &lt;/div&gt;

    &lt;p class=&quot;studysas-small&quot;&gt;&lt;em&gt;Source: Pinnacle 21 Help Center, PMDA Engine Update 2211.0&lt;/em&gt;&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Correct build pattern&lt;/div&gt;
    &lt;h2&gt;How to generate XPT correctly&lt;/h2&gt;

    &lt;p&gt;Use the LIBNAME XPORT engine:&lt;/p&gt;

    &lt;div class=&quot;studysas-code&quot;&gt;libname out xport &#39;/path/to/output/ae.xpt&#39;;

proc copy in=mylib out=out;
  select ae;
run;

libname out clear;&lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Why UTF-8 wins&lt;/div&gt;
    &lt;h2&gt;Why UTF-8 is the correct approach&lt;/h2&gt;

    &lt;p&gt;UTF-8 is not just about consistency. It matches the rest of the submission pipeline:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;EDC systems are typically Unicode&lt;/li&gt;
      &lt;li&gt;define.xml is XML with UTF-8 declaration&lt;/li&gt;
      &lt;li&gt;Pinnacle 21 runs in a Unicode session&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      Using UTF-8 end to end avoids transcoding and reduces the risk of silent data loss.
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Japanese text path&lt;/div&gt;
    &lt;h2&gt;What PMDA expects when Japanese text is involved&lt;/h2&gt;

    &lt;p&gt;PMDA allows two paths.&lt;/p&gt;

    &lt;h3&gt;If translation does not lose meaning&lt;/h3&gt;
    &lt;p&gt;Submit the English-translated dataset.&lt;/p&gt;

    &lt;h3&gt;If translation would lose meaning&lt;/h3&gt;
    &lt;p&gt;Submit both:&lt;/p&gt;
    &lt;ul&gt;
      &lt;li&gt;the Japanese dataset&lt;/li&gt;
      &lt;li&gt;the English-translated version&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;This is the correct alternative to simply saying “just use ASCII.”&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Practical SAS check&lt;/div&gt;
    &lt;h2&gt;Scan for non-ASCII characters before handoff&lt;/h2&gt;

    &lt;div class=&quot;studysas-code&quot;&gt;%macro check_nonascii(lib=, dsn=);

data non_ascii_check;
  set &amp;lib..&amp;dsn;

  array _char _character_;

  do i = 1 to dim(_char);
    if prxmatch(&#39;/[^\x00-\x7F]/&#39;, _char{i}) then do;
      dataset  = &quot;&amp;dsn&quot;;
      variable = vname(_char{i});
      value    = _char{i};
      output;
    end;
  end;

  keep dataset variable value;
run;

%mend check_nonascii;&lt;/div&gt;

    &lt;p&gt;This gives you a repeatable way to surface non-ASCII content before handoff.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Reviewer guide&lt;/div&gt;
    &lt;h2&gt;What PMDA expects in practice&lt;/h2&gt;

    &lt;p&gt;PMDA expects:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;encoding clearly documented&lt;/li&gt;
      &lt;li&gt;character set explained&lt;/li&gt;
      &lt;li&gt;consistency across all files&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;The reviewer guide should include:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;SAS session encoding&lt;/li&gt;
      &lt;li&gt;XML encoding, typically UTF-8&lt;/li&gt;
      &lt;li&gt;dataset character constraints&lt;/li&gt;
      &lt;li&gt;handling of non-English text&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Example language&lt;/div&gt;
    &lt;h2&gt;Example reviewer guide note&lt;/h2&gt;

    &lt;div class=&quot;studysas-code&quot;&gt;Character Encoding:

All datasets and metadata files were generated using UTF-8 encoding.

Dataset content is restricted to ASCII-compatible characters.

Japanese text, where required, is handled per PMDA guidance and
represented consistently across datasets and metadata.

All XML files include explicit encoding declarations.&lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-closing&quot;&gt;
    &lt;h2&gt;Why this matters&lt;/h2&gt;

    &lt;p&gt;FDA workflows are mostly English, so encoding problems are less visible until something breaks downstream.&lt;/p&gt;

    &lt;p&gt;PMDA workflows often include Japanese and explicitly require encoding clarity, which makes encoding a submission risk, not just a technical detail.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Encoding is one of the few areas where your data can be completely correct and your submission can still fail.&lt;/strong&gt;&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card studysas-sources&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Sources&lt;/div&gt;
    &lt;h2&gt;References&lt;/h2&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.pmda.go.jp/files/000267942.pdf&quot; target=&quot;_blank&quot;&gt;PMDA Technical Conformance Guide (April 2024)&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.pmda.go.jp/english/review-services/reviews/0002.html&quot; target=&quot;_blank&quot;&gt;PMDA Electronic Study Data Review Page&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;Pinnacle 21 Help Center — PMDA Engine Update 2211.0&lt;/li&gt;
      &lt;li&gt;FDA Study Data Technical Conformance Guide&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7106011471908909269'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7106011471908909269'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/03/character-encoding-japanese-text-and.html' title='Character Encoding, Japanese Text, and Why Your SDTM Package Can Fail Even When the Data Logic Is Fine'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-3645478680723545254</id><published>2026-03-30T21:24:00.004-04:00</published><updated>2026-04-03T13:29:00.102-04:00</updated><title type='text'> Passing Validation Isn’t Enough: What PMDA Actually Reviews in Your Submission Package </title><content type='html'>&lt;div class=&quot;studysas-post&quot;&gt;
  &lt;style&gt;
    .studysas-post {
      font-family: Arial, Helvetica, sans-serif;
      color: #1f2937;
      line-height: 1.75;
      font-size: 16px;
      max-width: 900px;
      margin: 0 auto;
    }

    .studysas-hero {
      background: linear-gradient(135deg, #0f172a, #1e3a8a);
      color: #ffffff;
      padding: 36px 28px;
      border-radius: 14px;
      margin-bottom: 28px;
    }

    .studysas-kicker {
      font-size: 13px;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      font-weight: 700;
      color: #c7d2fe;
      margin-bottom: 10px;
    }

    .studysas-title {
      font-size: 34px;
      line-height: 1.25;
      font-weight: 700;
      margin: 0 0 14px 0;
      color: #ffffff !important;
      text-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
    }

    .highlight-main {
      color: #60a5fa;
      font-weight: 700;
    }

    .highlight-accent {
      color: #93c5fd;
    }

    .studysas-subtitle {
      font-size: 17px;
      color: #dbeafe;
      margin: 0;
    }

    .studysas-card {
      background: #ffffff;
      border: 1px solid #e5e7eb;
      border-radius: 14px;
      padding: 26px 24px;
      margin: 22px 0;
      box-shadow: 0 2px 10px rgba(15, 23, 42, 0.04);
    }

    .studysas-card h2 {
      font-size: 25px;
      line-height: 1.3;
      margin: 0 0 14px 0;
      color: #0f172a;
    }

    .studysas-card h3 {
      font-size: 20px;
      line-height: 1.4;
      margin: 24px 0 10px 0;
      color: #1e3a8a;
    }

    .studysas-card p {
      margin: 0 0 16px 0;
    }

    .studysas-card ul {
      margin: 10px 0 16px 22px;
      padding: 0;
    }

    .studysas-card li {
      margin-bottom: 8px;
    }

    .studysas-callout {
      background: #eff6ff;
      border-left: 5px solid #2563eb;
      padding: 16px 18px;
      border-radius: 10px;
      margin: 18px 0;
      color: #1e3a8a;
      font-weight: 600;
    }

    .studysas-warning {
      background: #fff7ed;
      border-left: 5px solid #ea580c;
      padding: 16px 18px;
      border-radius: 10px;
      margin: 18px 0;
      color: #9a3412;
      font-weight: 600;
    }

    .studysas-note {
      background: #f8fafc;
      border: 1px solid #e2e8f0;
      padding: 16px 18px;
      border-radius: 10px;
      margin: 18px 0;
    }

    .studysas-code {
      background: #0f172a;
      color: #e2e8f0;
      border-radius: 12px;
      padding: 18px;
      overflow-x: auto;
      font-family: Consolas, Monaco, monospace;
      font-size: 14px;
      line-height: 1.6;
      margin: 18px 0;
      white-space: pre-wrap;
    }

    .studysas-section-label {
      display: inline-block;
      background: #dbeafe;
      color: #1d4ed8;
      font-size: 12px;
      font-weight: 700;
      letter-spacing: 0.04em;
      text-transform: uppercase;
      padding: 6px 10px;
      border-radius: 999px;
      margin-bottom: 12px;
    }

    .studysas-closing {
      background: #0f172a;
      color: #f8fafc;
      border-radius: 14px;
      padding: 24px;
      margin-top: 24px;
    }

    .studysas-closing h2 {
      color: #ffffff;
      margin-top: 0;
    }

    .studysas-small {
      font-size: 14px;
      color: #475569;
    }

    .studysas-sources ul {
      margin-top: 8px;
    }

    .studysas-sources a {
      color: #1d4ed8;
      text-decoration: none;
    }

    .studysas-sources a:hover {
      text-decoration: underline;
    }

    @media (max-width: 768px) {
      .studysas-title {
        font-size: 28px;
      }

      .studysas-card {
        padding: 20px 18px;
      }

      .studysas-hero {
        padding: 28px 20px;
      }
    }
  &lt;/style&gt;

  &lt;p&gt;For PMDA, a clean validation run is only part of the story. 
    The real pressure is in the documentation layer, rule-version timing, reviewer guide detail, and how clearly the package explains itself at submission.&lt;/p&gt;

    &lt;p&gt;Most SDTM teams have a handoff checklist.&lt;/p&gt;

    &lt;p&gt;Datasets locked.&lt;br&gt;
    define.xml generated.&lt;br&gt;
    Reviewer guide drafted.&lt;br&gt;
    P21 run clean.&lt;/p&gt;

    &lt;p&gt;Done.&lt;/p&gt;

  
    &lt;p&gt;For PMDA, that checklist is not complete.&lt;/p&gt;

    &lt;p&gt;The submission package is not just what you validated.&lt;br&gt;
    It is:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;how you validated&lt;/li&gt;
      &lt;li&gt;what you validated with&lt;/li&gt;
      &lt;li&gt;what changed between runs&lt;/li&gt;
      &lt;li&gt;how clearly you explained every finding that was not corrected&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;That last part is where PMDA feels fundamentally different from FDA.&lt;br&gt;
    Not in the data standards. In the &lt;strong&gt;documentation standards&lt;/strong&gt;.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Validation philosophy&lt;/div&gt;
    &lt;h2&gt;The core difference in validation philosophy&lt;/h2&gt;

    &lt;p&gt;Both FDA and PMDA use Pinnacle 21 Enterprise.&lt;/p&gt;

    &lt;p&gt;But they do not treat the results the same way.&lt;/p&gt;

    &lt;p&gt;FDA has deprecated severity classification. There is no formal Reject, Error, or Warning requirement driving submission acceptance. The expectation is simple:&lt;/p&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      Every unresolved issue must be explained.
    &lt;/div&gt;

    &lt;p&gt;PMDA is different.&lt;/p&gt;

    &lt;p&gt;PMDA maintains a strict severity hierarchy:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Reject&lt;/li&gt;
      &lt;li&gt;Error&lt;/li&gt;
      &lt;li&gt;Warning&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;This is not cosmetic.&lt;/p&gt;

    &lt;div class=&quot;studysas-warning&quot;&gt;
      Reject-level findings stop review.
    &lt;/div&gt;

    &lt;p&gt;PMDA will not begin or continue review when:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Reject issues are present&lt;/li&gt;
      &lt;li&gt;validation cannot run because files are corrupt or malformed&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;This is enforced at the gateway level.&lt;/p&gt;

    &lt;p&gt;According to Pinnacle 21 documentation, applications have been halted due to unresolved Reject findings.&lt;/p&gt;

    &lt;p class=&quot;studysas-small&quot;&gt;&lt;em&gt;Source: Pinnacle 21 Help Center, PMDA Engine Update 2211.0&lt;/em&gt;&lt;/p&gt;

    &lt;p&gt;For programmers, this changes your priority:&lt;/p&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      Reject findings must be fully resolved before handoff. Everything else comes after.
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Engine version control&lt;/div&gt;
    &lt;h2&gt;Validation engine version is submission metadata, not background context&lt;/h2&gt;

    &lt;p&gt;For FDA, the reviewer guide typically records:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;tool used&lt;/li&gt;
      &lt;li&gt;issues remaining&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;That is usually enough.&lt;/p&gt;

    &lt;p&gt;For PMDA, the validation engine version is part of the submission record.&lt;/p&gt;

    &lt;p&gt;PMDA publishes acceptable rule versions tied to submission windows.&lt;/p&gt;

    &lt;div class=&quot;studysas-note&quot;&gt;
      &lt;strong&gt;Practical view:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Version 3.0 → PMDA 2010.2 → Jan 2022 – Mar 2025&lt;br&gt;
      Version 4.0 → PMDA 2211.1 → Apr 2023 – Mar 2026&lt;br&gt;
      Version 5.0 → PMDA 2311.0 → Apr 2024 – Mar 2027&lt;br&gt;
      Version 6.0 → PMDA 2411.0 → Apr 2025 onward
    &lt;/div&gt;

    &lt;p class=&quot;studysas-small&quot;&gt;
      Source: &lt;a href=&quot;https://www.pmda.go.jp/english/review-services/reviews/0002.html&quot; target=&quot;_blank&quot;&gt;PMDA Electronic Data Review Page&lt;/a&gt;
    &lt;/p&gt;

    &lt;p&gt;PMDA runs your package through its own validation environment and compares results against your reviewer guide.&lt;/p&gt;

    &lt;p&gt;If your engine and PMDA’s engine differ:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;findings differ&lt;/li&gt;
      &lt;li&gt;explanations don’t match&lt;/li&gt;
      &lt;li&gt;queries follow&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Submission timing&lt;/div&gt;
    &lt;h2&gt;The rule-version problem most teams miss&lt;/h2&gt;

    &lt;p&gt;Validation is tied to submission timing.&lt;/p&gt;

    &lt;p&gt;A common scenario:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;study validated months earlier&lt;/li&gt;
      &lt;li&gt;submission delayed&lt;/li&gt;
      &lt;li&gt;new engine becomes current&lt;/li&gt;
      &lt;li&gt;new findings appear&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Now your reviewer guide no longer reflects what PMDA sees.&lt;/p&gt;

    &lt;p&gt;PMDA states:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;submission validation uses the &lt;strong&gt;current acceptable rule set&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;follow-up data may use the rule set active at filing&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p class=&quot;studysas-small&quot;&gt;
      Source: &lt;a href=&quot;https://www.pmda.go.jp/english/review-services/reviews/0002.html&quot; target=&quot;_blank&quot;&gt;PMDA Electronic Review Page&lt;/a&gt;
    &lt;/p&gt;

    &lt;div class=&quot;studysas-warning&quot;&gt;
      If your validation engine is no longer acceptable at submission time, validation must be rerun, findings must be reassessed, and the reviewer guide must be updated.
    &lt;/div&gt;

    &lt;p&gt;This is not a documentation update.&lt;/p&gt;

    &lt;p&gt;It is a &lt;strong&gt;re-validation requirement&lt;/strong&gt;.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Multi-study applications&lt;/div&gt;
    &lt;h2&gt;One engine per application&lt;/h2&gt;

    &lt;p&gt;For multi-study programs, PMDA expects one validation engine version across the entire application.&lt;/p&gt;

    &lt;p&gt;During development:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;different studies may use different engines&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;At submission:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;everything must align&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;If:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Study A → PMDA 2211.1&lt;/li&gt;
      &lt;li&gt;Study B → PMDA 2311.0&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Someone must reconcile that before submission.&lt;/p&gt;

    &lt;p&gt;It does not fix itself.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Reviewer guide detail&lt;/div&gt;
    &lt;h2&gt;What the reviewer guide must actually contain&lt;/h2&gt;

    &lt;p&gt;The PMDA reviewer guide is not a summary.&lt;/p&gt;

    &lt;p&gt;It is a structured validation record.&lt;/p&gt;

    &lt;p&gt;It must include:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;validation tool and version&lt;/li&gt;
      &lt;li&gt;engine version, explicitly named&lt;/li&gt;
      &lt;li&gt;rule version&lt;/li&gt;
      &lt;li&gt;for each unresolved finding:
        &lt;ul&gt;
          &lt;li&gt;rule ID&lt;/li&gt;
          &lt;li&gt;severity&lt;/li&gt;
          &lt;li&gt;justification&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      Reject findings must not remain.
    &lt;/div&gt;

    &lt;p&gt;If they do, you do not have a documentation issue.&lt;br&gt;
    You have a submission-blocking issue.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Example language&lt;/div&gt;
    &lt;h2&gt;What “good” looks like&lt;/h2&gt;

    &lt;div class=&quot;studysas-code&quot;&gt;Validation Summary:

Initial validation performed using Pinnacle 21 Enterprise
with PMDA Engine v5.0.

Final validation performed prior to submission using PMDA Engine v6.0,
which is the acceptable version at the time of submission.

New findings identified in final validation were reviewed and assessed.

All Reject-level issues were resolved prior to submission.
Remaining findings are documented with justification in Section 6.3.&lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Form A&lt;/div&gt;
    &lt;h2&gt;Form A is not the SDSP, and timing matters&lt;/h2&gt;

    &lt;p&gt;PMDA requires the Explanation of Electronic Study Data, Form A.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;no longer required before initial submission for applications dated from October 2023 onward&lt;/li&gt;
      &lt;li&gt;still required for pre-NDA consultation&lt;/li&gt;
      &lt;li&gt;still required for supplemental submissions&lt;/li&gt;
      &lt;li&gt;must be updated if PMDA requests clarification&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Before handoff, confirm:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Form A is current&lt;/li&gt;
      &lt;li&gt;it aligns with the reviewer guide&lt;/li&gt;
      &lt;li&gt;it reflects the validation engine used&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Mismatch between Form A and the reviewer guide is a known source of PMDA queries.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Define.xml control&lt;/div&gt;
    &lt;h2&gt;Define.xml is a validation object, not a publishing step&lt;/h2&gt;

    &lt;p&gt;PMDA independently validates:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;dataset vs dataset consistency&lt;/li&gt;
      &lt;li&gt;define.xml vs dataset consistency&lt;/li&gt;
      &lt;li&gt;XML structure&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p class=&quot;studysas-small&quot;&gt;
      Source: &lt;a href=&quot;https://www.pmda.go.jp/files/000267942.pdf&quot; target=&quot;_blank&quot;&gt;PMDA Technical Conformance Guide&lt;/a&gt;
    &lt;/p&gt;

    &lt;p&gt;Define.xml 1.0 is not accepted.&lt;br&gt;
    2.0 and 2.1 are required.&lt;/p&gt;

    &lt;div class=&quot;studysas-warning&quot;&gt;
      If your pipeline still produces Define.xml 1.0, that is a Reject-level issue.
    &lt;/div&gt;

    &lt;p&gt;PMDA also strongly expects Analysis Results Metadata, ARM, in ADaM define.xml. This documents the link between define.xml, analysis outputs, and CDISC standards.&lt;/p&gt;

    &lt;p&gt;Define.xml must reflect:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;final datasets&lt;/li&gt;
      &lt;li&gt;final derivation logic&lt;/li&gt;
      &lt;li&gt;final value-level metadata&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;If it lags, your package is not ready.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Pre-handoff QC&lt;/div&gt;
    &lt;h2&gt;Pre-handoff checklist for PMDA&lt;/h2&gt;

    &lt;p&gt;Before calling a package ready:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Define.xml is 2.0 or 2.1&lt;/li&gt;
      &lt;li&gt;Validation engine version is explicitly documented&lt;/li&gt;
      &lt;li&gt;Engine version is valid for the submission date&lt;/li&gt;
      &lt;li&gt;All Reject findings are resolved&lt;/li&gt;
      &lt;li&gt;Error findings are documented in the reviewer guide and Form A&lt;/li&gt;
      &lt;li&gt;Rule IDs, severity, and explanations are included&lt;/li&gt;
      &lt;li&gt;Validation logs are archived&lt;/li&gt;
      &lt;li&gt;Engine version is unified across studies&lt;/li&gt;
      &lt;li&gt;Submission date is recorded for revalidation risk&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      The FDA checklist is shorter. That is the point.
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-closing&quot;&gt;
    &lt;h2&gt;The question PMDA is actually asking&lt;/h2&gt;

    &lt;p&gt;&lt;strong&gt;FDA asks:&lt;/strong&gt;&lt;br&gt;
    Did you validate your data?&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;PMDA asks:&lt;/strong&gt;&lt;br&gt;
    Can you prove how you validated, with what, when, and is that still valid at submission?&lt;/p&gt;

    &lt;p&gt;Your handoff package is the answer.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card studysas-sources&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Sources&lt;/div&gt;
    &lt;h2&gt;References&lt;/h2&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.pmda.go.jp/files/000267942.pdf&quot; target=&quot;_blank&quot;&gt;PMDA Technical Conformance Guide (April 2024)&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://www.pmda.go.jp/english/review-services/reviews/0002.html&quot; target=&quot;_blank&quot;&gt;PMDA Electronic Study Data Review Page&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;Pinnacle 21 Help Center — PMDA Engine Updates (2211.0 / 2211.1)&lt;/li&gt;
      &lt;li&gt;PhUSE EU Connect 2024, Paper SA06&lt;/li&gt;
      &lt;li&gt;PhUSE 2021, Paper EP-146&lt;/li&gt;
      &lt;li&gt;FDA Study Data Technical Conformance Guide (Oct 2024)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/div&gt;
&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/3645478680723545254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/3645478680723545254'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/03/for-pmda-clean-validation-run-is-only.html' title=' Passing Validation Isn’t Enough: What PMDA Actually Reviews in Your Submission Package '/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-7326148498474596239</id><published>2026-03-30T19:32:00.004-04:00</published><updated>2026-04-03T13:33:24.729-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Define.xml"/><category scheme="http://www.blogger.com/atom/ns#" term="FDA vs PMDA Submissions"/><title type='text'>FDA vs PMDA Submissions: What Really Changes for SDTM Programmers and Define.xml Teams</title><content type='html'>&lt;div class=&quot;studysas-post&quot;&gt;
  &lt;style&gt;
    .studysas-post {
      font-family: Arial, Helvetica, sans-serif;
      color: #1f2937;
      line-height: 1.75;
      font-size: 16px;
      max-width: 900px;
      margin: 0 auto;
    }

    .studysas-hero {
      background: linear-gradient(135deg, #0f172a, #1e3a8a);
      color: #ffffff;
      padding: 36px 28px;
      border-radius: 14px;
      margin-bottom: 28px;
    }

    .studysas-kicker {
      font-size: 13px;
      letter-spacing: 0.08em;
      text-transform: uppercase;
      font-weight: 700;
      color: #c7d2fe;
      margin-bottom: 10px;
    }

    .studysas-title {
      font-size: 34px;
      line-height: 1.25;
      font-weight: 700;
      margin: 0 0 14px 0;
      color: #ffffff !important;
      text-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
    }

    .highlight-main {
      color: #60a5fa;
      font-weight: 700;
    }

    .highlight-accent {
      color: #93c5fd;
    }

    .studysas-subtitle {
      font-size: 17px;
      color: #dbeafe;
      margin: 0;
    }

    .studysas-card {
      background: #ffffff;
      border: 1px solid #e5e7eb;
      border-radius: 14px;
      padding: 26px 24px;
      margin: 22px 0;
      box-shadow: 0 2px 10px rgba(15, 23, 42, 0.04);
    }

    .studysas-card h2 {
      font-size: 25px;
      line-height: 1.3;
      margin: 0 0 14px 0;
      color: #0f172a;
    }

    .studysas-card h3 {
      font-size: 20px;
      line-height: 1.4;
      margin: 24px 0 10px 0;
      color: #1e3a8a;
    }

    .studysas-card p {
      margin: 0 0 16px 0;
    }

    .studysas-card ul {
      margin: 10px 0 16px 22px;
      padding: 0;
    }

    .studysas-card li {
      margin-bottom: 8px;
    }

    .studysas-callout {
      background: #eff6ff;
      border-left: 5px solid #2563eb;
      padding: 16px 18px;
      border-radius: 10px;
      margin: 18px 0;
      color: #1e3a8a;
      font-weight: 600;
    }

    .studysas-warning {
      background: #fff7ed;
      border-left: 5px solid #ea580c;
      padding: 16px 18px;
      border-radius: 10px;
      margin: 18px 0;
      color: #9a3412;
      font-weight: 600;
    }

    .studysas-note {
      background: #f8fafc;
      border: 1px solid #e2e8f0;
      padding: 16px 18px;
      border-radius: 10px;
      margin: 18px 0;
    }

    .studysas-table-wrap {
      overflow-x: auto;
      margin: 18px 0;
    }

    .studysas-table {
      width: 100%;
      border-collapse: collapse;
      font-size: 15px;
    }

    .studysas-table th,
    .studysas-table td {
      border: 1px solid #d1d5db;
      padding: 12px 14px;
      text-align: left;
      vertical-align: top;
    }

    .studysas-table th {
      background: #eff6ff;
      color: #1e3a8a;
      font-weight: 700;
    }

    .studysas-code {
      background: #0f172a;
      color: #e2e8f0;
      border-radius: 12px;
      padding: 18px;
      overflow-x: auto;
      font-family: Consolas, Monaco, monospace;
      font-size: 14px;
      line-height: 1.6;
      margin: 18px 0;
      white-space: pre-wrap;
    }

    .studysas-section-label {
      display: inline-block;
      background: #dbeafe;
      color: #1d4ed8;
      font-size: 12px;
      font-weight: 700;
      letter-spacing: 0.04em;
      text-transform: uppercase;
      padding: 6px 10px;
      border-radius: 999px;
      margin-bottom: 12px;
    }

    .studysas-closing {
      background: #0f172a;
      color: #f8fafc;
      border-radius: 14px;
      padding: 24px;
      margin-top: 24px;
    }

    .studysas-closing h2 {
      color: #ffffff;
      margin-top: 0;
    }

    .studysas-small {
      font-size: 14px;
      color: #475569;
    }

    .studysas-inline-strong {
      font-weight: 700;
      color: #0f172a;
    }

    @media (max-width: 768px) {
      .studysas-title {
        font-size: 28px;
      }

      .studysas-card {
        padding: 20px 18px;
      }

      .studysas-hero {
        padding: 28px 20px;
      }
    }
  &lt;/style&gt;

    &lt;p&gt;
      The real differences are usually not in domain structure. They show up in validation timing,
      metadata discipline, reviewer guide structure, rule-version control, encoding, and how clearly
      the submission package explains itself.
    &lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;p&gt;Most teams say they have “global submission-ready SDTM.” That usually means the datasets validate, define.xml opens, and the reviewer guides exist.&lt;/p&gt;

    &lt;p&gt;But “submission-ready” is not the same as being ready for every agency.&lt;/p&gt;

    &lt;p&gt;The FDA and PMDA overlap a lot. Both expect standardized study data. Both expect define.xml. Both run conformance checks. But the habits that work for one agency can still create extra work, or extra risk, for the other.&lt;/p&gt;

    &lt;p&gt;For senior programmers, the real difference is usually not domain structure. It shows up in how metadata is described, how validation is explained, how rule versions are tracked, how text is encoded, and how the package is documented.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;What stays the same&lt;/div&gt;
    &lt;h2&gt;Core SDTM discipline does not change&lt;/h2&gt;

    &lt;p&gt;At the core, your SDTM package still needs to be CDISC-conformant, traceable, and reviewable.&lt;/p&gt;

    &lt;p&gt;That part does not change between FDA and PMDA. You still need to build traceable, conformant, and reviewable data.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Consistent derivations&lt;/li&gt;
      &lt;li&gt;Stable controlled terminology handling&lt;/li&gt;
      &lt;li&gt;Clean date logic&lt;/li&gt;
      &lt;li&gt;Correct SUPP usage&lt;/li&gt;
      &lt;li&gt;Complete value-level metadata&lt;/li&gt;
      &lt;li&gt;Reviewer guides that explain what a validator alone cannot explain&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      If your SDTM is not stable, no agency-specific packaging step is going to save you.
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Where PMDA feels different&lt;/div&gt;
    &lt;h2&gt;Documentation gets operational, not just technical&lt;/h2&gt;

    &lt;p&gt;The biggest shift is documentation depth.&lt;/p&gt;

    &lt;p&gt;PMDA expects teams to be clear about the validation setup itself, not just the final outcome. That means the reviewer guide is no longer just background text. It becomes part of the operational record of how the package was checked.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;Validation tool and version&lt;/li&gt;
      &lt;li&gt;Rule version used&lt;/li&gt;
      &lt;li&gt;Explanation of findings with rule IDs&lt;/li&gt;
      &lt;li&gt;Issue handling based on PMDA severity categories&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      &lt;strong&gt;PMDA pushes teams to demonstrate how they validated, not just that they did.&lt;/strong&gt;
    &lt;/div&gt;

    &lt;p&gt;FDA also expects reviewer guides. But PMDA makes the validation process itself much more visible. If your team validates with one engine, fixes with another, and submits after a later engine becomes current, that gap needs to be visible and defendable.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Critical difference&lt;/div&gt;
    &lt;h2&gt;What can actually break your submission&lt;/h2&gt;

    &lt;p&gt;One important distinction is often underplayed. PMDA validation findings are not just documentation items. They can directly affect review acceptance.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;PMDA uses Severity levels:&lt;/strong&gt; Reject, Error, Warning&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Reject-level findings can halt review&lt;/strong&gt; until fixed&lt;/li&gt;
      &lt;li&gt;Reviewer guide issue summaries need to reflect that structure&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-warning&quot;&gt;
      This is not just a documentation problem. It is a submission acceptance risk.
    &lt;/div&gt;

    &lt;p&gt;FDA works differently. FDA no longer uses the same severity model in the same way, and the focus is on explanation of unresolved issues rather than a PMDA-style Reject gating model.&lt;/p&gt;

    &lt;p&gt;This changes how aggressively you fix findings before submission and how you structure the issue summary in the reviewer guide.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Validation model&lt;/div&gt;
    &lt;h2&gt;FDA and PMDA do not use the same rule system&lt;/h2&gt;

    &lt;p&gt;One common mistake is treating validation as a single system. It is not.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;FDA uses FDA Validator Rules&lt;/strong&gt;&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;PMDA uses its own published, versioned rule sets&lt;/strong&gt;&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      You are not running one validation. You are running two different rule systems.
    &lt;/div&gt;

    &lt;p&gt;This affects which findings appear, how those findings are grouped, and what must be fixed versus explained.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Validation timing&lt;/div&gt;
    &lt;h2&gt;The rule-version issue is not small&lt;/h2&gt;

    &lt;p&gt;PMDA applies the latest acceptable validation rules at submission, but follow-up data may use the rule version active when the application was filed.&lt;/p&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      &lt;strong&gt;Validation is not a one-time milestone.&lt;/strong&gt;
    &lt;/div&gt;

    &lt;p&gt;It is time-sensitive. For programmers, that changes behavior in a practical way.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;You need a rerun close to submission&lt;/li&gt;
      &lt;li&gt;You need traceability of engine and rule versions&lt;/li&gt;
      &lt;li&gt;You need alignment between validator output and the reviewer guide&lt;/li&gt;
      &lt;li&gt;You need to check whether your planned submission date changes which engine is acceptable&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-note&quot;&gt;
      &lt;strong&gt;Operational reality:&lt;/strong&gt; PMDA publishes acceptable validation engines and rule versions. A team should check the acceptable engine on the planned submission date, not just the engine used earlier in study closeout.
    &lt;/div&gt;

    &lt;div class=&quot;studysas-note&quot;&gt;
      &lt;strong&gt;Example:&lt;/strong&gt; A team validated with Pinnacle 21 using one PMDA engine during closeout, but the final submission happened after a newer acceptable engine became current. New rules flagged findings that did not exist earlier. The reviewer now sees issues the team never documented. That is not really a data problem. It is a submission timing problem.
    &lt;/div&gt;

    &lt;div class=&quot;studysas-warning&quot;&gt;
      If the engine used during validation is no longer acceptable at submission time, validation may need to be rerun and the reviewer guide updated.
    &lt;/div&gt;

    &lt;p&gt;Document rule versions directly in your cSDRG, and archive validation logs at each rerun point. That one step prevents a lot of avoidable review confusion.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Encoding risk&lt;/div&gt;
    &lt;h2&gt;Character encoding can become a late-stage submission issue&lt;/h2&gt;

    &lt;p&gt;FDA-centered workflows often run with English-only assumptions. PMDA submissions can make character encoding much more visible, especially when Japanese text appears in supporting material, annotations, comments, or linked documentation.&lt;/p&gt;

    &lt;p&gt;This affects more than just the dataset itself.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;SAS session encoding&lt;/li&gt;
      &lt;li&gt;XML generation&lt;/li&gt;
      &lt;li&gt;External file exports&lt;/li&gt;
      &lt;li&gt;Stylesheet rendering&lt;/li&gt;
      &lt;li&gt;Round-trip handling between tools&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      Unicode, typically UTF-8 session encoding, is the safer working setup. Dataset content still needs to stay ASCII-compatible where required.
    &lt;/div&gt;

    &lt;div class=&quot;studysas-warning&quot;&gt;
      Character encoding issues often surface late, during stylesheet rendering or define.xml validation, when they are hardest to fix.
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Define.xml matters&lt;/div&gt;
    &lt;h2&gt;Define.xml needs to do more than exist&lt;/h2&gt;

    &lt;p&gt;Many teams still treat define.xml as a final publishing step. That is where trouble starts, especially for dual-agency submissions.&lt;/p&gt;

    &lt;p&gt;Define.xml is not just a technical artifact. It is part of what reviewers actually read. If the datasets have moved but your metadata still reflects an earlier state, you are going to create confusion even when the package technically opens.&lt;/p&gt;

    &lt;div class=&quot;studysas-callout&quot;&gt;
      &lt;strong&gt;Define.xml isn’t output decoration. It’s part of the submission.&lt;/strong&gt;
    &lt;/div&gt;

    &lt;p&gt;For PMDA work, another practical point often missed is ARM. PMDA teams often need to think more carefully about Analysis Results Metadata placement and whether the ADaM definition package is telling the reviewer enough without forcing them into extra cross-referencing.&lt;/p&gt;

    &lt;p&gt;If your metadata lags behind your datasets, you are not submission-ready.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;SDTM impact&lt;/div&gt;
    &lt;h2&gt;Small differences that show up in datasets&lt;/h2&gt;

    &lt;p&gt;Not every FDA versus PMDA difference is structural. Some show up in day-to-day programming details.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Units:&lt;/strong&gt; teams often need to think about conventional units for FDA-facing expectations versus SI-unit expectations in PMDA-facing work&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Reviewer guide issue layout:&lt;/strong&gt; PMDA severity categories change how issue summaries are written&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;ADaM metadata packaging:&lt;/strong&gt; ARM handling can be more visible in PMDA-oriented builds&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;These are not always massive coding changes. But they affect how datasets and metadata are interpreted during review.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Side-by-side view&lt;/div&gt;
    &lt;h2&gt;FDA vs PMDA, what actually differs&lt;/h2&gt;

    &lt;div class=&quot;studysas-table-wrap&quot;&gt;
      &lt;table class=&quot;studysas-table&quot;&gt;
        &lt;thead&gt;
          &lt;tr&gt;
            &lt;th&gt;Area&lt;/th&gt;
            &lt;th&gt;FDA&lt;/th&gt;
            &lt;th&gt;PMDA&lt;/th&gt;
          &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
          &lt;tr&gt;
            &lt;td&gt;Validation Rules&lt;/td&gt;
            &lt;td&gt;FDA validator rule set&lt;/td&gt;
            &lt;td&gt;PMDA-specific published rule set&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;Define.xml&lt;/td&gt;
            &lt;td&gt;Expected as part of the submission metadata package&lt;/td&gt;
            &lt;td&gt;Expected with style sheet and checked closely against datasets&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;Reviewer Guide&lt;/td&gt;
            &lt;td&gt;Expected and important for review context&lt;/td&gt;
            &lt;td&gt;More operational, should document validation setup and findings clearly&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;Issue Classification&lt;/td&gt;
            &lt;td&gt;Focus on explanation of unresolved issues&lt;/td&gt;
            &lt;td&gt;Severity model matters, Reject/Error/Warning&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;Submission Risk&lt;/td&gt;
            &lt;td&gt;Findings generally drive questions and clarification&lt;/td&gt;
            &lt;td&gt;Reject findings can block or suspend review until fixed&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;Rule Version Handling&lt;/td&gt;
            &lt;td&gt;Usually less visible in submission narrative&lt;/td&gt;
            &lt;td&gt;Timing matters because the acceptable engine and rule context can change&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;Encoding&lt;/td&gt;
            &lt;td&gt;Often English-only in practice&lt;/td&gt;
            &lt;td&gt;Needs more care when non-English content is present&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;Units&lt;/td&gt;
            &lt;td&gt;Conventional unit expectations more common&lt;/td&gt;
            &lt;td&gt;SI-unit expectations more visible&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
            &lt;td&gt;Validation Scope&lt;/td&gt;
            &lt;td&gt;Datasets and metadata must be reviewable&lt;/td&gt;
            &lt;td&gt;Cross-checks across datasets, metadata, and XML structure matter more visibly&lt;/td&gt;
          &lt;/tr&gt;
        &lt;/tbody&gt;
      &lt;/table&gt;
    &lt;/div&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Build model&lt;/div&gt;
    &lt;h2&gt;Recommended workflow&lt;/h2&gt;

    &lt;p&gt;For efficiency, separate at the packaging and documentation layer, not the derivation layer.&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;One SDTM derivation pipeline&lt;/li&gt;
      &lt;li&gt;One controlled metadata source&lt;/li&gt;
      &lt;li&gt;One conformance issue log&lt;/li&gt;
      &lt;li&gt;Agency-specific reviewer guide wording&lt;/li&gt;
      &lt;li&gt;PMDA-specific engine and rule-version tracking&lt;/li&gt;
      &lt;li&gt;Explicit encoding checks&lt;/li&gt;
      &lt;li&gt;Final validation rerun close to submission&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;This keeps programming unified while allowing submission differences where they actually matter.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Sample cSDRG language&lt;/div&gt;
    &lt;h2&gt;Example cSDRG excerpt for rule-version documentation&lt;/h2&gt;

    &lt;div class=&quot;studysas-code&quot;&gt;Validation Summary:

All SDTM datasets were validated using Pinnacle 21 Enterprise
with the PMDA engine and rule version acceptable at the time of final submission.

Initial validation was performed earlier in study closeout using a prior acceptable engine.
A final rerun was conducted prior to submission to align with the current acceptable engine and rule set.

Any new findings introduced in the final rerun were reviewed and assessed before submission.
Issue details, rationale, and resolution status are documented in Section 6.3.

For FDA-facing review, unresolved issues are explained in the Issue Summary.
For PMDA-facing review, issues are grouped and described using the applicable severity structure.&lt;/div&gt;

    &lt;p class=&quot;studysas-small&quot;&gt;The point is not just to say what was used. The point is to show that the final submission package was checked against the acceptable rule context at the time of submission.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-card&quot;&gt;
    &lt;div class=&quot;studysas-section-label&quot;&gt;Sample define.xml metadata&lt;/div&gt;
    &lt;h2&gt;Example define.xml snippet showing value-level clarity&lt;/h2&gt;

    &lt;div class=&quot;studysas-code&quot;&gt;&amp;lt;ValueListDef OID=&quot;VL.AE.AESTDTC&quot;&amp;gt;
  &amp;lt;ItemRef ItemOID=&quot;IT.AE.AESTDTC&quot; Mandatory=&quot;Yes&quot;/&amp;gt;
&amp;lt;/ValueListDef&amp;gt;

&amp;lt;WhereClauseDef OID=&quot;WC.AE.PARTIAL&quot;&amp;gt;
  &amp;lt;RangeCheck Comparator=&quot;EQ&quot;&amp;gt;
    &amp;lt;CheckValue&amp;gt;PARTIAL&amp;lt;/CheckValue&amp;gt;
  &amp;lt;/RangeCheck&amp;gt;
&amp;lt;/WhereClauseDef&amp;gt;

&amp;lt;ItemDef OID=&quot;IT.AE.AESTDTC&quot; Name=&quot;AESTDTC&quot; DataType=&quot;text&quot;&amp;gt;
  &amp;lt;Description&amp;gt;
    &amp;lt;TranslatedText&amp;gt;
      Start date of adverse event. Partial dates are imputed to the first day of the month when day is missing.
    &amp;lt;/TranslatedText&amp;gt;
  &amp;lt;/Description&amp;gt;
&amp;lt;/ItemDef&amp;gt;&lt;/div&gt;

    &lt;p&gt;This kind of wording reduces reviewer confusion when partial date handling differs across domains or when imputation rules need to be stated plainly.&lt;/p&gt;
  &lt;/div&gt;

  &lt;div class=&quot;studysas-closing&quot;&gt;
    &lt;h2&gt;Final point&lt;/h2&gt;
    &lt;p&gt;The difference is not really about standards versions alone.&lt;/p&gt;
    &lt;p&gt;It is about submission narration, what you validated, with what, when, under which rule set, and how clearly your metadata explains the data.&lt;/p&gt;
    &lt;p&gt;&lt;strong&gt;PMDA makes these expectations explicit and enforces them through validation outcomes. FDA expects the same clarity, but relies more on explanation and reviewer interpretation.&lt;/strong&gt;&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7326148498474596239'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7326148498474596239'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/03/fda-vs-pmda-submissions-what-really.html' title='FDA vs PMDA Submissions: What Really Changes for SDTM Programmers and Define.xml Teams'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-2087996360024401701</id><published>2026-03-30T15:44:00.004-04:00</published><updated>2026-04-03T13:32:35.748-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Define.xml Review Checklist"/><title type='text'>A Define.xml Review Checklist I Actually Use Before Submission</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;title&gt;A Define.xml Review Checklist I Actually Use Before Submission&lt;/title&gt;
&lt;/head&gt;
&lt;body style=&quot;margin:0; padding:0; background:#ffffff; font-family:Arial, Helvetica, sans-serif; color:#1f2937;&quot;&gt;

  &lt;div style=&quot;max-width:1200px; margin:0 auto; background:#ffffff; padding:36px 28px 64px 28px; line-height:1.8; font-size:16px;&quot;&gt;
       &lt;p&gt;
        An SDTM-focused practical checklist for reviewing define.xml before submission, with emphasis on reproducibility, traceability, consistency, and the reviewer-facing problems that weak metadata creates.
      &lt;/p&gt;
    &lt;/div&gt;
    &lt;p&gt;If you work on SDTM submissions long enough, you learn that define.xml is never just a metadata file.&lt;/p&gt;

    &lt;p&gt;It is the reviewer’s map to the datasets, the controlled terminology, the derivations, the value-level rules, and the awkward corners of the study that never fully fit the standard.&lt;/p&gt;

    &lt;p&gt;Over time, I stopped treating validation as the only sign-off gate. I started using a review checklist that asks a harder question:&lt;/p&gt;

    &lt;div style=&quot;background:#153a63; color:#ffffff; border-radius:14px; padding:20px 22px; margin:18px 0;&quot;&gt;
      If I were a reviewer opening this package for the first time, would I understand the SDTM data without asking the sponsor what they meant?
    &lt;/div&gt;

    &lt;p&gt;A strong define.xml does two jobs at once. It tells the reviewer what is in the submission, and it tells them how to think about it. That is why I review it at three levels: package consistency, metadata accuracy, and reviewer usability. A file can be technically valid and still be weak in one of the other two.&lt;/p&gt;

    &lt;p&gt;What follows is the checklist I actually use before an SDTM submission goes out the door.&lt;/p&gt;

    &lt;!-- Diagram 1 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #dbe4ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 1. Validation clean is not the same as review-ready&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 18px 20px; color:#64748b; font-size:14px;&quot;&gt;A practical difference between technical conformance and reviewer understanding.&lt;/div&gt;
      &lt;div style=&quot;padding:10px 16px 24px 16px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 290&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Validation clean versus review ready&quot;&gt;
          &lt;rect x=&quot;30&quot; y=&quot;36&quot; width=&quot;320&quot; height=&quot;190&quot; rx=&quot;18&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;190&quot; y=&quot;70&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Validation clean&lt;/text&gt;
          &lt;text x=&quot;60&quot; y=&quot;116&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#334e68&quot;&gt;• SDTM structure valid&lt;/text&gt;
          &lt;text x=&quot;60&quot; y=&quot;152&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#334e68&quot;&gt;• Controlled terms valid&lt;/text&gt;
          &lt;text x=&quot;60&quot; y=&quot;188&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#334e68&quot;&gt;• Basic consistency checked&lt;/text&gt;

          &lt;rect x=&quot;510&quot; y=&quot;36&quot; width=&quot;320&quot; height=&quot;190&quot; rx=&quot;18&quot; fill=&quot;#eef8ef&quot; stroke=&quot;#8bb38d&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;670&quot; y=&quot;70&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#27673a&quot; font-weight=&quot;700&quot;&gt;Review-ready&lt;/text&gt;
          &lt;text x=&quot;540&quot; y=&quot;116&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2f5132&quot;&gt;• Logic reproducible&lt;/text&gt;
          &lt;text x=&quot;540&quot; y=&quot;152&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2f5132&quot;&gt;• Boundary rules explicit&lt;/text&gt;
          &lt;text x=&quot;540&quot; y=&quot;188&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2f5132&quot;&gt;• Reviewer does not need to guess&lt;/text&gt;

          &lt;path d=&quot;M350 130 C425 130, 435 130, 510 130&quot; fill=&quot;none&quot; stroke=&quot;#c2871a&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;510,130 498,123 498,137&quot; fill=&quot;#c2871a&quot;/&gt;
          &lt;text x=&quot;430&quot; y=&quot;110&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#9a6710&quot; font-weight=&quot;700&quot;&gt;The real gap&lt;/text&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Start with the submission package&lt;/h2&gt;

    &lt;p&gt;Before I even open the XML structure itself, I verify that the dataset package and metadata package agree on the basics.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Confirm every submitted SDTM domain appears in define.xml.&lt;/li&gt;
      &lt;li&gt;Confirm define.xml does not list any domain that is not actually in the submission package.&lt;/li&gt;
      &lt;li&gt;Verify domain names, labels, classes, and structures match the submitted datasets.&lt;/li&gt;
      &lt;li&gt;Check file names, folder placement, and package conventions are consistent.&lt;/li&gt;
      &lt;li&gt;Check the SDRG, aCRF, datasets, and define.xml all point to the same final delivery.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Confirm standards and versions are explicitly identified&lt;/h2&gt;

    &lt;p&gt;This sounds basic, but it is one of the easiest things to leave half-finished when metadata is updated late.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Confirm the SDTMIG version is correctly identified.&lt;/li&gt;
      &lt;li&gt;Confirm the Define-XML version is the one intended for the submission.&lt;/li&gt;
      &lt;li&gt;Confirm controlled terminology versions are named consistently.&lt;/li&gt;
      &lt;li&gt;Confirm external dictionaries such as MedDRA, WHODrug, LOINC, or other study-level standards are versioned consistently across define.xml, SDRG, and study documentation.&lt;/li&gt;
      &lt;li&gt;Confirm no old standard version labels remain from template reuse.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;I always treat version signaling as a reviewer orientation issue, not just a metadata housekeeping issue.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Check dataset metadata first&lt;/h2&gt;

    &lt;p&gt;The fastest way to spot a weak define.xml is to compare dataset-level metadata against the actual XPT files.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Dataset label matches the dataset’s real purpose and SDTM domain.&lt;/li&gt;
      &lt;li&gt;Class is correct and consistent with SDTM usage.&lt;/li&gt;
      &lt;li&gt;Structure is correct, including whether the domain is one record per subject, one record per event, or another expected pattern.&lt;/li&gt;
      &lt;li&gt;Keys and identifier variables are consistent with the domain content.&lt;/li&gt;
      &lt;li&gt;Dataset-level comments explain anything unusual the reviewer needs to know.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;I never trust the metadata spec alone here. I compare the XPT header, define.xml dataset metadata, and the mapping spec line by line for high-risk domains like DM, EX, AE, LB, VS, DS, and SUPP--.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Then review variables one by one&lt;/h2&gt;

    &lt;p&gt;This is where most quiet problems live.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Variable name, label, type, length, and format match the actual dataset.&lt;/li&gt;
      &lt;li&gt;Variable order is sensible and consistent with the implementation.&lt;/li&gt;
      &lt;li&gt;Core SDTM variables are present where expected.&lt;/li&gt;
      &lt;li&gt;Required, expected, and permissible usage is justified by the domain.&lt;/li&gt;
      &lt;li&gt;Controlled terminology fields actually point to the right codelist, and the codelist reflects what is used in the data.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;1. Can the variable be reproduced from define.xml alone?&lt;/h2&gt;

    &lt;p&gt;This is the first true reviewer test I use.&lt;/p&gt;

    &lt;p&gt;If a reviewer or another programmer had only the SDTM dataset and define.xml, could they recreate the variable safely?&lt;/p&gt;

    &lt;p&gt;If the answer is no, the metadata is not complete enough.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;What I check&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Formula is explicitly stated.&lt;/li&gt;
      &lt;li&gt;Anchor variables are named.&lt;/li&gt;
      &lt;li&gt;Selection logic is written, not implied.&lt;/li&gt;
      &lt;li&gt;Units and conversions are visible.&lt;/li&gt;
      &lt;li&gt;The description is specific enough that another programmer could reproduce the result without opening an internal spec.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div style=&quot;background:#f8fafc; border:1px solid #dbe4ee; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Weak&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Derived from reference start date.
    &lt;/div&gt;

    &lt;div style=&quot;background:#eef8ef; border:1px solid #bdd9c1; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Better&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Study day is calculated as Event Date minus DM.RFSTDTC plus 1 when Event Date is on or after DM.RFSTDTC; otherwise Event Date minus DM.RFSTDTC. Records with partial dates are not assigned study day.
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;2. Are boundary conditions clearly defined?&lt;/h2&gt;

    &lt;p&gt;Most ambiguity comes from the edges, not the main rule.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;What I check&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Same-day records&lt;/li&gt;
      &lt;li&gt;Missing time&lt;/li&gt;
      &lt;li&gt;Partial dates&lt;/li&gt;
      &lt;li&gt;Multiple qualifying records&lt;/li&gt;
      &lt;li&gt;Pre-treatment versus post-treatment boundary&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;For SDTM Findings flags such as &lt;code style=&quot;font-family:&#39;Courier New&#39;, monospace; background:#eef4fb; padding:2px 6px; border-radius:5px;&quot;&gt;LBLOBXFL&lt;/code&gt;, reviewers usually ask the same things.&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Is “prior” based on date or datetime?&lt;/li&gt;
      &lt;li&gt;Are same-day records eligible?&lt;/li&gt;
      &lt;li&gt;What if time is missing?&lt;/li&gt;
      &lt;li&gt;How is “last” selected?&lt;/li&gt;
    &lt;/ul&gt;

    &lt;!-- XML Snippet 1 --&gt;
    &lt;div style=&quot;margin:26px 0 12px 0; font-weight:bold; color:#153a63;&quot;&gt;SDTM XML example for LBLOBXFL&lt;/div&gt;
    &lt;div style=&quot;background:#fbfbfc; border:1px solid #d9e2ea; border-radius:12px; overflow:hidden; margin-bottom:22px;&quot;&gt;
      &lt;div style=&quot;background:#edf2f7; padding:10px 14px; font-size:13px; color:#4b5d73; border-bottom:1px solid #d9e2ea;&quot;&gt;Listing 1. Reviewer-friendly method description&lt;/div&gt;
      &lt;pre style=&quot;margin:0; padding:18px; overflow:auto; font-size:14px; line-height:1.6; font-family:&#39;Courier New&#39;, monospace; color:#243447;&quot;&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;ItemDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;IT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;DataType=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Length=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;Last Observation Before Exposure Flag&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Origin&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Derived&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodRef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;MethodOID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/ItemDef&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Last Observation Before Exposure Flag Derivation&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Computation&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
      LBLOBXFL is assigned as &#39;Y&#39; to the chronologically latest non-missing
      result collected before first exposure. If only dates are available,
      collection date must be strictly earlier than DM.RFSTDTC. Records on
      the first-dose date are eligible only when both collection time and
      dosing time are available and the collection occurs before dosing.
      Records with missing time on the first-dose date are not eligible.
      If multiple qualifying records exist, the latest chronological record
      is selected.
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/MethodDef&amp;gt;&lt;/span&gt;&lt;/pre&gt;
    &lt;/div&gt;

    &lt;!-- Diagram 2 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #dbe4ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 2. Boundary cases that should be visible in define.xml&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 18px 20px; color:#64748b; font-size:14px;&quot;&gt;These are the places where reviewer interpretation usually starts to diverge from team intent.&lt;/div&gt;
      &lt;div style=&quot;padding:10px 16px 24px 16px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 300&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Boundary case checklist&quot;&gt;
          &lt;rect x=&quot;60&quot; y=&quot;40&quot; width=&quot;180&quot; height=&quot;60&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;150&quot; y=&quot;77&quot; text-anchor=&quot;middle&quot; font-size=&quot;20&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Same-day records&lt;/text&gt;

          &lt;rect x=&quot;340&quot; y=&quot;40&quot; width=&quot;180&quot; height=&quot;60&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;430&quot; y=&quot;77&quot; text-anchor=&quot;middle&quot; font-size=&quot;20&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Missing time&lt;/text&gt;

          &lt;rect x=&quot;620&quot; y=&quot;40&quot; width=&quot;180&quot; height=&quot;60&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;710&quot; y=&quot;77&quot; text-anchor=&quot;middle&quot; font-size=&quot;20&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Partial dates&lt;/text&gt;

          &lt;rect x=&quot;200&quot; y=&quot;170&quot; width=&quot;210&quot; height=&quot;60&quot; rx=&quot;14&quot; fill=&quot;#fff7e8&quot; stroke=&quot;#cfa65a&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;305&quot; y=&quot;207&quot; text-anchor=&quot;middle&quot; font-size=&quot;20&quot; font-family=&quot;Arial&quot; fill=&quot;#8b6314&quot; font-weight=&quot;700&quot;&gt;Multiple qualifiers&lt;/text&gt;

          &lt;rect x=&quot;470&quot; y=&quot;170&quot; width=&quot;210&quot; height=&quot;60&quot; rx=&quot;14&quot; fill=&quot;#fff7e8&quot; stroke=&quot;#cfa65a&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;575&quot; y=&quot;207&quot; text-anchor=&quot;middle&quot; font-size=&quot;20&quot; font-family=&quot;Arial&quot; fill=&quot;#8b6314&quot; font-weight=&quot;700&quot;&gt;Date vs datetime anchor&lt;/text&gt;

          &lt;path d=&quot;M150 100 L305 170&quot; stroke=&quot;#7b96b6&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M430 100 L430 170&quot; stroke=&quot;#7b96b6&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M710 100 L575 170&quot; stroke=&quot;#7b96b6&quot; stroke-width=&quot;3&quot;/&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;3. Is partial date handling explicitly documented?&lt;/h2&gt;

    &lt;p&gt;Partial date handling is one of the biggest sources of inconsistency across SDTM.&lt;/p&gt;

    &lt;p&gt;Many define.xml files simply say:&lt;/p&gt;

    &lt;div style=&quot;background:#f8fafc; border:1px solid #dbe4ee; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      Partial dates were imputed.
    &lt;/div&gt;

    &lt;p&gt;That does not tell the reviewer enough.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;What I check&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Which patterns are imputed&lt;/li&gt;
      &lt;li&gt;What values are assigned&lt;/li&gt;
      &lt;li&gt;Where the imputation is used&lt;/li&gt;
      &lt;li&gt;Whether imputed values are stored in SDTM&lt;/li&gt;
      &lt;li&gt;Whether the logic is consistent across domains&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div style=&quot;background:#eef8ef; border:1px solid #bdd9c1; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Better&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      AE start dates in YYYY-MM format are imputed to the first day of the month for treatment-emergent classification only. Imputed values are not stored in SDTM and are not used for time-to-event analyses.
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;4. Is unit standardization clearly described?&lt;/h2&gt;

    &lt;p&gt;For domains such as LB, VS, and EG, this matters more than many teams expect.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;What I check&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Whether results are converted&lt;/li&gt;
      &lt;li&gt;What source drives the conversion&lt;/li&gt;
      &lt;li&gt;Whether standardization happens before flag derivation&lt;/li&gt;
      &lt;li&gt;How character results are handled&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div style=&quot;background:#f8fafc; border:1px solid #dbe4ee; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Weak&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Standard unit.
    &lt;/div&gt;

    &lt;div style=&quot;background:#eef8ef; border:1px solid #bdd9c1; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Better&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Results for LBTESTCD = ALT are standardized to U/L using approved central lab conversion factors before derivation of LBNRIND. Character results reported as below quantification limit remain in LBSTRESC and do not populate LBSTRESN.
    &lt;/div&gt;

    &lt;!-- XML Snippet 2 --&gt;
    &lt;div style=&quot;margin:26px 0 12px 0; font-weight:bold; color:#153a63;&quot;&gt;Value-level metadata example for lab standardization&lt;/div&gt;
    &lt;div style=&quot;background:#fbfbfc; border:1px solid #d9e2ea; border-radius:12px; overflow:hidden; margin-bottom:22px;&quot;&gt;
      &lt;div style=&quot;background:#edf2f7; padding:10px 14px; font-size:13px; color:#4b5d73; border-bottom:1px solid #d9e2ea;&quot;&gt;Listing 2. Example VLM description pattern&lt;/div&gt;
      &lt;pre style=&quot;margin:0; padding:18px; overflow:auto; font-size:14px; line-height:1.6; font-family:&#39;Courier New&#39;, monospace; color:#243447;&quot;&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;WhereClauseDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;WC.LB.ALT&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;RangeCheck&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Comparator=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;EQ&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;SoftHard=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Soft&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;CheckValue&amp;gt;&lt;/span&gt;ALT&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/CheckValue&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;ItemOID&amp;gt;&lt;/span&gt;IT.LB.LBTESTCD&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/ItemOID&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/RangeCheck&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/WhereClauseDef&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;ItemDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;IT.LB.LBSTRESN&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;LBSTRESN&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;DataType=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;float&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
      For LBTESTCD = ALT, LBSTRESN is standardized to U/L using approved
      central lab conversion factors before derivation of LBNRIND.
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/ItemDef&amp;gt;&lt;/span&gt;&lt;/pre&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Controlled terminology needs reviewer logic&lt;/h2&gt;

    &lt;p&gt;Controlled terminology problems are rarely dramatic, but they are exactly the kind of thing reviewers notice.&lt;/p&gt;

    &lt;p&gt;I do not stop at checking whether a variable points to a codelist. I also check whether the codelist actually explains the values used in the dataset.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Every coded variable points to the correct codelist.&lt;/li&gt;
      &lt;li&gt;Every coded value in the dataset is represented in the linked codelist.&lt;/li&gt;
      &lt;li&gt;Extensible versus non-extensible behavior is handled correctly.&lt;/li&gt;
      &lt;li&gt;“Other” values are used appropriately and not as a catch-all for unresolved mapping.&lt;/li&gt;
      &lt;li&gt;Custom terms are clearly identified, justified, and used only when needed.&lt;/li&gt;
      &lt;li&gt;External terminology references are consistent with the study implementation.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Traceability must make sense&lt;/h2&gt;

    &lt;p&gt;Define.xml is not only about naming things correctly. It is about helping a reviewer understand where data came from and how it was derived.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Origin is correct for each variable, especially collected, derived, and assigned variables.&lt;/li&gt;
      &lt;li&gt;Derivation descriptions are clear, concise, and reproducible.&lt;/li&gt;
      &lt;li&gt;External references, comments, and derivation logic are understandable without reading an internal spec.&lt;/li&gt;
      &lt;li&gt;If something is nonstandard, define.xml and SDRG tell the same story.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;This matters most when a variable is derived from multiple sources, when date imputation is involved, or when the domain includes sponsor-specific nuances.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Review computational methods as reusable objects&lt;/h2&gt;

    &lt;p&gt;In define.xml, a derivation is not just a sentence. It is a metadata object. If the same logic appears in multiple places, the method references should make that obvious.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Each MethodDef is actually referenced where intended.&lt;/li&gt;
      &lt;li&gt;Duplicated logic is reused rather than described differently in multiple places.&lt;/li&gt;
      &lt;li&gt;Method text is specific enough to reproduce the derivation.&lt;/li&gt;
      &lt;li&gt;Sponsor-defined methods are not described so broadly that they hide record-level conditions.&lt;/li&gt;
      &lt;li&gt;Method naming is understandable to a reviewer and not only to the study team.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;5. Is origin and traceability unambiguous?&lt;/h2&gt;

    &lt;p&gt;This is one of the biggest reviewer confidence checks.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;What I check&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Is the value CRF-collected, assigned, or derived?&lt;/li&gt;
      &lt;li&gt;Is sponsor mapping logic visible?&lt;/li&gt;
      &lt;li&gt;Does define.xml align with SDRG or cSDRG wording?&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div style=&quot;background:#f8fafc; border:1px solid #dbe4ee; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Weak&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Relationship to study drug.
    &lt;/div&gt;

    &lt;div style=&quot;background:#eef8ef; border:1px solid #bdd9c1; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Better&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Collected on AE CRF as investigator assessment of relationship to study treatment. In studies with multiple investigational products, SDTM value represents relationship to primary study treatment as defined in protocol. Sponsor mapping rules are applied when more than one relationship is recorded.
    &lt;/div&gt;

    &lt;!-- Diagram 3 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #dbe4ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 3. Traceability path I expect define.xml to support&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 18px 20px; color:#64748b; font-size:14px;&quot;&gt;This is the path a reviewer should be able to follow without guessing.&lt;/div&gt;
      &lt;div style=&quot;padding:10px 16px 24px 16px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 240&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Traceability path&quot;&gt;
          &lt;rect x=&quot;20&quot; y=&quot;84&quot; width=&quot;150&quot; height=&quot;70&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;95&quot; y=&quot;118&quot; text-anchor=&quot;middle&quot; font-size=&quot;20&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;CRF&lt;/text&gt;
          &lt;text x=&quot;95&quot; y=&quot;140&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#4a6075&quot;&gt;Collected data&lt;/text&gt;

          &lt;rect x=&quot;220&quot; y=&quot;84&quot; width=&quot;150&quot; height=&quot;70&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;295&quot; y=&quot;118&quot; text-anchor=&quot;middle&quot; font-size=&quot;20&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;SDTM&lt;/text&gt;
          &lt;text x=&quot;295&quot; y=&quot;140&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#4a6075&quot;&gt;Mapped records&lt;/text&gt;

          &lt;rect x=&quot;420&quot; y=&quot;70&quot; width=&quot;180&quot; height=&quot;98&quot; rx=&quot;14&quot; fill=&quot;#eef8ef&quot; stroke=&quot;#8bb38d&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;510&quot; y=&quot;104&quot; text-anchor=&quot;middle&quot; font-size=&quot;20&quot; font-family=&quot;Arial&quot; fill=&quot;#27673a&quot; font-weight=&quot;700&quot;&gt;define.xml&lt;/text&gt;
          &lt;text x=&quot;510&quot; y=&quot;128&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#3a5a3d&quot;&gt;Origin&lt;/text&gt;
          &lt;text x=&quot;510&quot; y=&quot;146&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#3a5a3d&quot;&gt;Method&lt;/text&gt;
          &lt;text x=&quot;510&quot; y=&quot;164&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#3a5a3d&quot;&gt;VLM&lt;/text&gt;

          &lt;rect x=&quot;650&quot; y=&quot;84&quot; width=&quot;190&quot; height=&quot;70&quot; rx=&quot;14&quot; fill=&quot;#fff7e8&quot; stroke=&quot;#cfa65a&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;745&quot; y=&quot;118&quot; text-anchor=&quot;middle&quot; font-size=&quot;20&quot; font-family=&quot;Arial&quot; fill=&quot;#8b6314&quot; font-weight=&quot;700&quot;&gt;Reviewer&lt;/text&gt;
          &lt;text x=&quot;745&quot; y=&quot;140&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#8b6314&quot;&gt;Interpretation&lt;/text&gt;

          &lt;path d=&quot;M170 119 L220 119&quot; stroke=&quot;#6e8fb4&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;220,119 208,112 208,126&quot; fill=&quot;#6e8fb4&quot;/&gt;

          &lt;path d=&quot;M370 119 L420 119&quot; stroke=&quot;#6e8fb4&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;420,119 408,112 408,126&quot; fill=&quot;#6e8fb4&quot;/&gt;

          &lt;path d=&quot;M600 119 L650 119&quot; stroke=&quot;#c2871a&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;650,119 638,112 638,126&quot; fill=&quot;#c2871a&quot;/&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Value-level metadata deserves extra attention&lt;/h2&gt;

    &lt;p&gt;Value-level metadata is often where strong define.xml packages become weak. It is especially important when a variable behaves differently by record type, when metadata changes by subset, or when special derivations need precise explanation.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Value-level metadata is used only when needed and not as a workaround for poor dataset design.&lt;/li&gt;
      &lt;li&gt;The conditions for the value-level metadata are correctly specified.&lt;/li&gt;
      &lt;li&gt;The metadata actually covers all relevant records in the dataset.&lt;/li&gt;
      &lt;li&gt;The resulting description is understandable to a reviewer who is not part of the study team.&lt;/li&gt;
      &lt;li&gt;Each VLM entry adds something useful beyond the parent variable description.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Review SUPP-- carefully&lt;/h2&gt;

    &lt;p&gt;SUPP-- is often technically valid and still a sign that something needs a second look. I always check whether supplemental qualifiers are truly the right implementation, or whether the metadata is compensating for a design decision that deserves more scrutiny.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Each supplemental qualifier is appropriate for SUPP-- use.&lt;/li&gt;
      &lt;li&gt;QNAM, QLABEL, QVAL, IDVAR, and IDVARVAL align with the parent record.&lt;/li&gt;
      &lt;li&gt;Supplemental qualifiers are traceable back to the source collection.&lt;/li&gt;
      &lt;li&gt;Reviewer-facing comments explain any heavy reliance on SUPP--.&lt;/li&gt;
      &lt;li&gt;The same concept is not represented both in a parent domain and in SUPP-- without explanation.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;6. Are value-level metadata entries actually useful?&lt;/h2&gt;

    &lt;p&gt;I do not look at VLM just to see whether it exists. I look at whether it adds anything useful.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;What I check&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Does each VLM entry add context that the parent variable does not?&lt;/li&gt;
      &lt;li&gt;Are conditions clearly defined?&lt;/li&gt;
      &lt;li&gt;Are methods aligned across subsets?&lt;/li&gt;
      &lt;li&gt;Are units, flags, and derivations consistent with the condition?&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;If VLM is only repeating variable-level text, it is not doing enough.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;7. Is the logic consistent across domains?&lt;/h2&gt;

    &lt;p&gt;This is where quiet inconsistency shows up.&lt;/p&gt;

    &lt;p&gt;Typical pattern:&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;AE uses imputed dates&lt;/li&gt;
      &lt;li&gt;LB excludes partial dates&lt;/li&gt;
      &lt;li&gt;VS uses visit date&lt;/li&gt;
      &lt;li&gt;EG uses datetime boundary&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Each rule may be valid. But together they may look inconsistent unless the metadata explains where the differences are intentional.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;What I check&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Same concept, same logic where possible&lt;/li&gt;
      &lt;li&gt;If not, differences are clearly documented&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Hyperlinks and references must work&lt;/h2&gt;

    &lt;p&gt;A broken link in define.xml feels small until it lands in a reviewer’s lap.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;All internal references resolve correctly.&lt;/li&gt;
      &lt;li&gt;All external links point to the intended file or metadata object.&lt;/li&gt;
      &lt;li&gt;Links to codelists, origin documents, and external references render correctly in the stylesheet output.&lt;/li&gt;
      &lt;li&gt;The stylesheet displays the metadata in a readable way for human review.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Review define.xml as a reviewer would actually read it&lt;/h2&gt;

    &lt;p&gt;I always open the rendered define.xml in a browser and navigate it as if I were seeing the package for the first time. This catches problems that schema validation does not.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Dataset pages load cleanly.&lt;/li&gt;
      &lt;li&gt;Variable pages are readable and not cluttered with broken references.&lt;/li&gt;
      &lt;li&gt;Value-level metadata is easy to follow in the rendered view.&lt;/li&gt;
      &lt;li&gt;Long method text wraps correctly and is still readable.&lt;/li&gt;
      &lt;li&gt;Codelists, comments, and document links open in a way that helps rather than slows review.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Confirm consistency with SDRG and aCRF&lt;/h2&gt;

    &lt;p&gt;In practice, define.xml, SDRG, aCRF, and datasets should all tell the same story about the SDTM implementation.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Dataset descriptions in define.xml match the SDRG narrative.&lt;/li&gt;
      &lt;li&gt;Deviations from SDTM IG or controlled terminology are explained the same way across documents.&lt;/li&gt;
      &lt;li&gt;aCRF annotations support the variables and origins described in define.xml.&lt;/li&gt;
      &lt;li&gt;Custom domains or special handling are described consistently across the package.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Pay extra attention to custom domains and sponsor-defined variables&lt;/h2&gt;

    &lt;p&gt;Reviewers are usually more tolerant of nonstandard implementation than teams expect, as long as it is explained clearly and consistently. What creates friction is not the existence of a custom rule. It is weak explanation.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Custom domains are clearly identified and justified.&lt;/li&gt;
      &lt;li&gt;Sponsor-defined variables do not look like standard variables by accident.&lt;/li&gt;
      &lt;li&gt;Naming, labels, origins, and methods are aligned across define.xml and SDRG.&lt;/li&gt;
      &lt;li&gt;Reviewer-facing explanations describe why the implementation was needed, not only what was done.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;8. Does the metadata match the actual SDTM data?&lt;/h2&gt;

    &lt;p&gt;This sounds obvious, but it fails more often than it should.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;What I check&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Derivation wording matches observed values.&lt;/li&gt;
      &lt;li&gt;Units match actual standardized data.&lt;/li&gt;
      &lt;li&gt;Flags behave the way the method says they do.&lt;/li&gt;
      &lt;li&gt;No leftover template language remains.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;A common example is when metadata says “latest value prior to treatment,” but same-day post-dose records are still flagged. That is not a programming issue anymore. That is a metadata credibility issue.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Run validation, but do not stop there&lt;/h2&gt;

    &lt;p&gt;Validation catches structural problems. It does not catch every reviewer-facing problem.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;XML validates against the intended Define-XML schema.&lt;/li&gt;
      &lt;li&gt;No broken references or unresolved metadata objects remain.&lt;/li&gt;
      &lt;li&gt;No obvious conformance errors remain after tool-based validation.&lt;/li&gt;
      &lt;li&gt;Manual review confirms the metadata still makes reviewer sense after the final dataset freeze.&lt;/li&gt;
      &lt;li&gt;The stylesheet output is readable and matches the intended submission package.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;9. Are ambiguous phrases eliminated?&lt;/h2&gt;

    &lt;p&gt;These phrases are common, but they usually create more uncertainty than they remove:&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Derived from reference start date&lt;/li&gt;
      &lt;li&gt;Last non-missing value&lt;/li&gt;
      &lt;li&gt;Standard unit&lt;/li&gt;
      &lt;li&gt;Partial dates were imputed&lt;/li&gt;
      &lt;li&gt;Relationship to study drug&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;Each one hides decisions. The fix is not more words for the sake of more words. The fix is writing the actual rule.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Recheck after the final metadata refresh&lt;/h2&gt;

    &lt;p&gt;One of the most common late-stage problems is not a wrong derivation. It is a right derivation described by the wrong final metadata because the datasets, SDRG, aCRF, and define.xml did not freeze in the same rhythm.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Checklist&lt;/strong&gt;&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Final XPT files match the last define.xml build.&lt;/li&gt;
      &lt;li&gt;No late updates were made to one document but not the others.&lt;/li&gt;
      &lt;li&gt;Reviewer comments, methods, and links still point to the final objects.&lt;/li&gt;
      &lt;li&gt;The rendered define.xml reflects the actual submission package, not the pre-freeze draft.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;!-- Diagram 4 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #dbe4ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 4. The checklist I use before sign-off&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 18px 20px; color:#64748b; font-size:14px;&quot;&gt;A simple pre-submission pass that catches most weak-metadata problems.&lt;/div&gt;
      &lt;div style=&quot;padding:10px 16px 24px 16px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 360&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Define.xml checklist&quot;&gt;
          &lt;rect x=&quot;320&quot; y=&quot;16&quot; width=&quot;220&quot; height=&quot;50&quot; rx=&quot;12&quot; fill=&quot;#153a63&quot;/&gt;
          &lt;text x=&quot;430&quot; y=&quot;48&quot; text-anchor=&quot;middle&quot; font-size=&quot;22&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;define.xml review&lt;/text&gt;

          &lt;rect x=&quot;40&quot; y=&quot;108&quot; width=&quot;170&quot; height=&quot;62&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;125&quot; y=&quot;135&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Reproducibility&lt;/text&gt;
          &lt;text x=&quot;125&quot; y=&quot;157&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#4a6075&quot;&gt;Can it be rebuilt?&lt;/text&gt;

          &lt;rect x=&quot;245&quot; y=&quot;108&quot; width=&quot;170&quot; height=&quot;62&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;330&quot; y=&quot;135&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Boundaries&lt;/text&gt;
          &lt;text x=&quot;330&quot; y=&quot;157&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#4a6075&quot;&gt;Are edge cases clear?&lt;/text&gt;

          &lt;rect x=&quot;450&quot; y=&quot;108&quot; width=&quot;170&quot; height=&quot;62&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;535&quot; y=&quot;135&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Traceability&lt;/text&gt;
          &lt;text x=&quot;535&quot; y=&quot;157&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#4a6075&quot;&gt;Origin and method clear?&lt;/text&gt;

          &lt;rect x=&quot;655&quot; y=&quot;108&quot; width=&quot;170&quot; height=&quot;62&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#9ab8dc&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;740&quot; y=&quot;135&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Consistency&lt;/text&gt;
          &lt;text x=&quot;740&quot; y=&quot;157&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#4a6075&quot;&gt;Across domains?&lt;/text&gt;

          &lt;rect x=&quot;245&quot; y=&quot;242&quot; width=&quot;170&quot; height=&quot;62&quot; rx=&quot;14&quot; fill=&quot;#fff7e8&quot; stroke=&quot;#cfa65a&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;330&quot; y=&quot;269&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#8b6314&quot; font-weight=&quot;700&quot;&gt;VLM quality&lt;/text&gt;
          &lt;text x=&quot;330&quot; y=&quot;291&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#8b6314&quot;&gt;Adds useful context?&lt;/text&gt;

          &lt;rect x=&quot;450&quot; y=&quot;242&quot; width=&quot;170&quot; height=&quot;62&quot; rx=&quot;14&quot; fill=&quot;#fff7e8&quot; stroke=&quot;#cfa65a&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;535&quot; y=&quot;269&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#8b6314&quot; font-weight=&quot;700&quot;&gt;No ambiguity&lt;/text&gt;
          &lt;text x=&quot;535&quot; y=&quot;291&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#8b6314&quot;&gt;Would reviewer ask?&lt;/text&gt;

          &lt;path d=&quot;M430 66 L125 108&quot; stroke=&quot;#7b96b6&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M430 66 L330 108&quot; stroke=&quot;#7b96b6&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M430 66 L535 108&quot; stroke=&quot;#7b96b6&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M430 66 L740 108&quot; stroke=&quot;#7b96b6&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M330 170 L330 242&quot; stroke=&quot;#c2871a&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M535 170 L535 242&quot; stroke=&quot;#c2871a&quot; stroke-width=&quot;3&quot;/&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;10. Final test: will this create a reviewer question?&lt;/h2&gt;

    &lt;p&gt;This is the last question I ask.&lt;/p&gt;

    &lt;div style=&quot;background:#153a63; color:#ffffff; border-radius:14px; padding:20px 22px; margin:18px 0;&quot;&gt;
      Can a reviewer understand this rule without asking what we meant?
    &lt;/div&gt;

    &lt;p&gt;If the answer is no, the metadata is still too thin.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Final thought&lt;/h2&gt;

    &lt;p&gt;The define.xml packages that cause the fewest review problems are usually not the ones with the fanciest tooling.&lt;/p&gt;

    &lt;p&gt;They are the ones where the metadata, datasets, SDRG, and annotated CRF tell the same story without forcing the reviewer to fill in the gaps.&lt;/p&gt;

    &lt;p&gt;That is the standard I use before submission.&lt;/p&gt;

    &lt;div style=&quot;margin-top:36px; padding:18px 20px; border-radius:14px; background:#0f172a; color:#ffffff;&quot;&gt;
      &lt;strong&gt;Suggested closing question for comments&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Which define.xml checkpoint catches the most problems in your SDTM submissions, reproducibility, traceability, standards/version control, or boundary handling?
    &lt;/div&gt;

  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/2087996360024401701'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/2087996360024401701'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/03/a-definexml-review-checklist-i-actually.html' title='A Define.xml Review Checklist I Actually Use Before Submission'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-7707934396719644475</id><published>2026-03-30T13:10:00.001-04:00</published><updated>2026-03-30T13:11:02.422-04:00</updated><title type='text'>Five Define.xml Phrases That Sound Fine, But Trigger Review Questions</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;title&gt;Five Define.xml Phrases That Sound Fine, But Trigger Review Questions&lt;/title&gt;
&lt;/head&gt;
&lt;body style=&quot;margin:0; padding:0; background:#f3f6fa; font-family:Arial, Helvetica, sans-serif; color:#1f2937;&quot;&gt;

  &lt;div style=&quot;max-width:900px; margin:0 auto; background:#ffffff; padding:36px 28px 64px 28px; line-height:1.75; font-size:16px;&quot;&gt;

    &lt;!-- Hero --&gt;
    &lt;div style=&quot;background:linear-gradient(135deg,#153a63,#2b68b0); color:#ffffff; padding:34px 30px; border-radius:16px; margin-bottom:30px;&quot;&gt;
      &lt;div style=&quot;font-size:12px; letter-spacing:1px; text-transform:uppercase; opacity:0.9; margin-bottom:8px;&quot;&gt;StudySAS Blog&lt;/div&gt;
      &lt;h1 style=&quot;margin:0 0 10px 0; font-size:34px; line-height:1.2;&quot;&gt;Five Define.xml Phrases That Sound Fine, But Trigger Review Questions&lt;/h1&gt;
      &lt;p style=&quot;margin:0; font-size:18px; line-height:1.6; max-width:760px;&quot;&gt;
        A practical look at the wording patterns that pass internal review, validate cleanly, and still create trouble when a reviewer tries to understand your SDTM logic from metadata alone.
      &lt;/p&gt;
    &lt;/div&gt;

    &lt;p&gt;Some define.xml wording looks perfectly acceptable during internal review.&lt;/p&gt;

    &lt;p&gt;Then the same wording creates questions during submission review.&lt;/p&gt;

    &lt;p&gt;Not because the data is wrong. Not because the programming is broken. But because the description leaves too much room for interpretation.&lt;/p&gt;

    &lt;p&gt;That gap matters more than many teams realize. Define.xml is the reviewer’s first structured view of your SDTM package. If the metadata is thin, the reviewer starts guessing. And once guessing starts, questions follow.&lt;/p&gt;

    &lt;div style=&quot;background:#fff7e9; border-left:6px solid #d08d21; padding:18px 18px 18px 20px; margin:28px 0; border-radius:10px;&quot;&gt;
      &lt;strong&gt;One useful standard&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      A good define.xml description should let another programmer, or a reviewer, understand the rule without relying on team memory.
    &lt;/div&gt;

    &lt;!-- Visual 1 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #d7e1ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 1. Why these phrases fail in review&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 20px 20px; color:#5b6878; font-size:14px;&quot;&gt;The problem is rarely the variable itself. The problem is the space between what the team knows and what the metadata actually says.&lt;/div&gt;
      &lt;div style=&quot;padding:8px 14px 24px 14px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 310&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Why weak phrases trigger review questions&quot;&gt;
          &lt;defs&gt;
            &lt;linearGradient id=&quot;bluebox2&quot; x1=&quot;0%&quot; y1=&quot;0%&quot; x2=&quot;100%&quot; y2=&quot;100%&quot;&gt;
              &lt;stop offset=&quot;0%&quot; stop-color=&quot;#edf4fb&quot;/&gt;
              &lt;stop offset=&quot;100%&quot; stop-color=&quot;#d9e8f8&quot;/&gt;
            &lt;/linearGradient&gt;
            &lt;linearGradient id=&quot;goldbox2&quot; x1=&quot;0%&quot; y1=&quot;0%&quot; x2=&quot;100%&quot; y2=&quot;100%&quot;&gt;
              &lt;stop offset=&quot;0%&quot; stop-color=&quot;#fff7e8&quot;/&gt;
              &lt;stop offset=&quot;100%&quot; stop-color=&quot;#f9ebc8&quot;/&gt;
            &lt;/linearGradient&gt;
            &lt;linearGradient id=&quot;redbox2&quot; x1=&quot;0%&quot; y1=&quot;0%&quot; x2=&quot;100%&quot; y2=&quot;100%&quot;&gt;
              &lt;stop offset=&quot;0%&quot; stop-color=&quot;#fff1f1&quot;/&gt;
              &lt;stop offset=&quot;100%&quot; stop-color=&quot;#f6dcdc&quot;/&gt;
            &lt;/linearGradient&gt;
          &lt;/defs&gt;

          &lt;rect x=&quot;20&quot; y=&quot;40&quot; width=&quot;230&quot; height=&quot;200&quot; rx=&quot;18&quot; fill=&quot;url(#bluebox2)&quot; stroke=&quot;#90b3da&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;135&quot; y=&quot;72&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Team intent&lt;/text&gt;
          &lt;text x=&quot;135&quot; y=&quot;118&quot; text-anchor=&quot;middle&quot; font-size=&quot;17&quot; font-family=&quot;Arial&quot; fill=&quot;#3d5875&quot;&gt;Rule exists&lt;/text&gt;
          &lt;text x=&quot;135&quot; y=&quot;148&quot; text-anchor=&quot;middle&quot; font-size=&quot;17&quot; font-family=&quot;Arial&quot; fill=&quot;#3d5875&quot;&gt;Programming is correct&lt;/text&gt;
          &lt;text x=&quot;135&quot; y=&quot;178&quot; text-anchor=&quot;middle&quot; font-size=&quot;17&quot; font-family=&quot;Arial&quot; fill=&quot;#3d5875&quot;&gt;QC is complete&lt;/text&gt;

          &lt;rect x=&quot;315&quot; y=&quot;40&quot; width=&quot;230&quot; height=&quot;200&quot; rx=&quot;18&quot; fill=&quot;url(#goldbox2)&quot; stroke=&quot;#caa45a&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;430&quot; y=&quot;72&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#8c6616&quot; font-weight=&quot;700&quot;&gt;Metadata wording&lt;/text&gt;
          &lt;text x=&quot;430&quot; y=&quot;118&quot; text-anchor=&quot;middle&quot; font-size=&quot;17&quot; font-family=&quot;Arial&quot; fill=&quot;#7d5b18&quot;&gt;Too short&lt;/text&gt;
          &lt;text x=&quot;430&quot; y=&quot;148&quot; text-anchor=&quot;middle&quot; font-size=&quot;17&quot; font-family=&quot;Arial&quot; fill=&quot;#7d5b18&quot;&gt;Too broad&lt;/text&gt;
          &lt;text x=&quot;430&quot; y=&quot;178&quot; text-anchor=&quot;middle&quot; font-size=&quot;17&quot; font-family=&quot;Arial&quot; fill=&quot;#7d5b18&quot;&gt;Edge cases missing&lt;/text&gt;

          &lt;rect x=&quot;610&quot; y=&quot;40&quot; width=&quot;230&quot; height=&quot;200&quot; rx=&quot;18&quot; fill=&quot;url(#redbox2)&quot; stroke=&quot;#d69797&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;725&quot; y=&quot;72&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#8f2e2e&quot; font-weight=&quot;700&quot;&gt;Review result&lt;/text&gt;
          &lt;text x=&quot;725&quot; y=&quot;118&quot; text-anchor=&quot;middle&quot; font-size=&quot;17&quot; font-family=&quot;Arial&quot; fill=&quot;#6a3535&quot;&gt;Reviewer guesses&lt;/text&gt;
          &lt;text x=&quot;725&quot; y=&quot;148&quot; text-anchor=&quot;middle&quot; font-size=&quot;17&quot; font-family=&quot;Arial&quot; fill=&quot;#6a3535&quot;&gt;Questions increase&lt;/text&gt;
          &lt;text x=&quot;725&quot; y=&quot;178&quot; text-anchor=&quot;middle&quot; font-size=&quot;17&quot; font-family=&quot;Arial&quot; fill=&quot;#6a3535&quot;&gt;Trust drops&lt;/text&gt;

          &lt;path d=&quot;M250 140 L315 140&quot; stroke=&quot;#6a8eb8&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;315,140 303,133 303,147&quot; fill=&quot;#6a8eb8&quot;/&gt;

          &lt;path d=&quot;M545 140 L610 140&quot; stroke=&quot;#c68a1f&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;610,140 598,133 598,147&quot; fill=&quot;#c68a1f&quot;/&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;1. “Derived from reference start date”&lt;/h2&gt;

    &lt;p&gt;This is common for &lt;code style=&quot;font-family:&#39;Courier New&#39;, monospace; background:#eef4fb; padding:2px 5px; border-radius:5px;&quot;&gt;--DY&lt;/code&gt; variables.&lt;/p&gt;

    &lt;p&gt;It sounds reasonable. But it does not tell the reviewer enough to recreate the rule safely.&lt;/p&gt;

    &lt;p&gt;What is missing:&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;The actual formula&lt;/li&gt;
      &lt;li&gt;The day 1 boundary rule&lt;/li&gt;
      &lt;li&gt;How pre-treatment values are handled&lt;/li&gt;
      &lt;li&gt;What happens with partial dates&lt;/li&gt;
      &lt;li&gt;Whether the logic is date-based or datetime-based&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div style=&quot;background:#f8fafc; border:1px solid #d7dee8; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Weak&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Derived from reference start date.
    &lt;/div&gt;

    &lt;div style=&quot;background:#eef8ef; border:1px solid #bbd9bf; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Better&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Study day is calculated as Event Date minus DM.RFSTDTC plus 1 when Event Date is on or after DM.RFSTDTC; otherwise Event Date minus DM.RFSTDTC. No date imputation is applied for this derivation. Records with partial event dates are not assigned study day.
    &lt;/div&gt;

    &lt;p&gt;The second version does real work. It tells the reviewer what the formula is, where the boundary sits, and what is excluded.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;2. “Last non-missing value prior to treatment”&lt;/h2&gt;

    &lt;p&gt;This is one of the most common metadata phrases in findings logic, especially when teams derive an SDTM flag such as &lt;code style=&quot;font-family:&#39;Courier New&#39;, monospace; background:#eef4fb; padding:2px 5px; border-radius:5px;&quot;&gt;LBLOBXFL&lt;/code&gt;.&lt;/p&gt;

    &lt;p&gt;The wording sounds precise. It is not.&lt;/p&gt;

    &lt;p&gt;It leaves open several questions:&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;What defines “prior”, reference start date or actual exposure datetime?&lt;/li&gt;
      &lt;li&gt;What happens for records on the first-dose date?&lt;/li&gt;
      &lt;li&gt;What if collection time is missing?&lt;/li&gt;
      &lt;li&gt;Are unscheduled visits included?&lt;/li&gt;
      &lt;li&gt;If more than one record qualifies, how is “last” decided?&lt;/li&gt;
    &lt;/ul&gt;

    &lt;!-- XML Example --&gt;
    &lt;div style=&quot;margin:26px 0 12px 0; font-weight:bold; color:#153a63;&quot;&gt;SDTM XML example, weak vs better&lt;/div&gt;

    &lt;div style=&quot;background:#fbfbfc; border:1px solid #d9dee7; border-radius:12px; overflow:hidden; margin-bottom:22px;&quot;&gt;
      &lt;div style=&quot;background:#e9eef5; padding:10px 14px; font-size:13px; color:#4d6078; border-bottom:1px solid #d9dee7;&quot;&gt;Listing 1. Minimal method description for LBLOBXFL&lt;/div&gt;
      &lt;pre style=&quot;margin:0; padding:18px 18px; overflow:auto; font-size:14px; line-height:1.6; font-family:&#39;Courier New&#39;, monospace; color:#243447;&quot;&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;ItemDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;IT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;DataType=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Length=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;Last Observation Before Exposure Flag&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Origin&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Derived&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodRef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;MethodOID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/ItemDef&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Last Observation Before Exposure Flag&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Computation&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
      Last non-missing result prior to treatment.
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/MethodDef&amp;gt;&lt;/span&gt;&lt;/pre&gt;
    &lt;/div&gt;

    &lt;div style=&quot;background:#fbfbfc; border:1px solid #d9dee7; border-radius:12px; overflow:hidden; margin-bottom:24px;&quot;&gt;
      &lt;div style=&quot;background:#e9eef5; padding:10px 14px; font-size:13px; color:#4d6078; border-bottom:1px solid #d9dee7;&quot;&gt;Listing 2. Reviewer-friendly method description for LBLOBXFL&lt;/div&gt;
      &lt;pre style=&quot;margin:0; padding:18px 18px; overflow:auto; font-size:14px; line-height:1.6; font-family:&#39;Courier New&#39;, monospace; color:#243447;&quot;&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;ItemDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;IT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;DataType=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Length=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;Last Observation Before Exposure Flag&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Origin&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Derived&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodRef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;MethodOID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/ItemDef&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Last Observation Before Exposure Flag Derivation&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Computation&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
      LBLOBXFL is assigned as &#39;Y&#39; to the chronologically latest non-missing
      result collected before first exposure. If only dates are available,
      collection date must be strictly earlier than DM.RFSTDTC. Records on
      the first-dose date are eligible only when both collection time and
      dosing time are available and the collection occurs before dosing.
      Records with missing time on the first-dose date are not eligible.
      If multiple qualifying records exist, the latest chronological record
      is selected.
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/MethodDef&amp;gt;&lt;/span&gt;&lt;/pre&gt;
    &lt;/div&gt;

    &lt;p&gt;The second version gives the reviewer something operational. It defines the anchor, the same-day rule, the missing-time rule, and the tie-break rule.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;3. “Partial dates were imputed”&lt;/h2&gt;

    &lt;p&gt;This is a classic phrase that carries almost no review value by itself.&lt;/p&gt;

    &lt;p&gt;It does not answer:&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Which date patterns were imputed&lt;/li&gt;
      &lt;li&gt;What values were assigned&lt;/li&gt;
      &lt;li&gt;Where the imputation was used&lt;/li&gt;
      &lt;li&gt;Whether SDTM values were changed or left as collected&lt;/li&gt;
      &lt;li&gt;Whether the rule applies across domains or only in one place&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div style=&quot;background:#f8fafc; border:1px solid #d7dee8; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Weak&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Partial dates were imputed.
    &lt;/div&gt;

    &lt;div style=&quot;background:#eef8ef; border:1px solid #bbd9bf; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Better&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Partial AE start dates are imputed for treatment-emergent classification only. Dates in YYYY-MM format are imputed to the first day of the month. Dates in YYYY format are imputed to January 1. Original collected values remain in AESTDTC. Imputed dates are not stored in SDTM and are not used for survival or time-to-event analyses.
    &lt;/div&gt;

    &lt;p&gt;The key point is not just the method. It is the scope.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;4. “Standard unit”&lt;/h2&gt;

    &lt;p&gt;This shows up in lab metadata all the time, especially when teams rely on short value-level notes.&lt;/p&gt;

    &lt;p&gt;The phrase does not tell the reviewer:&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Whether results were converted&lt;/li&gt;
      &lt;li&gt;How vendor-specific factors were handled&lt;/li&gt;
      &lt;li&gt;Whether standardization happened before or after flag derivation&lt;/li&gt;
      &lt;li&gt;What happened to character results such as below quantification limit&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div style=&quot;background:#f8fafc; border:1px solid #d7dee8; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Weak&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Standard unit.
    &lt;/div&gt;

    &lt;div style=&quot;background:#eef8ef; border:1px solid #bbd9bf; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Better&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Results for LBTESTCD = ALT are standardized to U/L in LBSTRESU. When LBORRESU differs from U/L, conversion uses approved central lab conversion factors before derivation of LBNRIND. Character results reported as below quantification limit remain in LBSTRESC and do not populate LBSTRESN.
    &lt;/div&gt;

    &lt;p&gt;This kind of wording is much more useful to experienced programmers because it states order of operations and data-type behavior.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;5. “Relationship to study drug”&lt;/h2&gt;

    &lt;p&gt;This looks harmless, but it often hides one of the hardest traceability questions in SDTM: was the value collected, assigned, or sponsor-derived?&lt;/p&gt;

    &lt;p&gt;That question gets sharper in studies with more than one treatment or more than one possible relationship target.&lt;/p&gt;

    &lt;div style=&quot;background:#f8fafc; border:1px solid #d7dee8; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Weak&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Relationship to study drug.
    &lt;/div&gt;

    &lt;div style=&quot;background:#eef8ef; border:1px solid #bbd9bf; border-radius:12px; padding:16px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Better&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Collected on the AE CRF as investigator assessment of relationship to study treatment. In studies with multiple investigational products, the SDTM value represents relationship to the primary investigational product defined in the protocol. When multiple products are recorded, sponsor mapping follows the hierarchy specified in the study data handling conventions.
    &lt;/div&gt;

    &lt;p&gt;The stronger version makes the origin and sponsor logic visible. That is what makes the metadata useful.&lt;/p&gt;

    &lt;!-- Visual 2 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #d7e1ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 2. The hidden pattern behind all five phrases&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 20px 20px; color:#5b6878; font-size:14px;&quot;&gt;The wording changes from short labels to actual rules.&lt;/div&gt;
      &lt;div style=&quot;padding:8px 14px 24px 14px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 320&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;From short labels to operational rules&quot;&gt;
          &lt;rect x=&quot;30&quot; y=&quot;36&quot; width=&quot;340&quot; height=&quot;248&quot; rx=&quot;18&quot; fill=&quot;#fff1f1&quot; stroke=&quot;#d69797&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;200&quot; y=&quot;68&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#8f2e2e&quot; font-weight=&quot;700&quot;&gt;Short label style&lt;/text&gt;
          &lt;text x=&quot;58&quot; y=&quot;112&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#693434&quot;&gt;• Derived from reference start date&lt;/text&gt;
          &lt;text x=&quot;58&quot; y=&quot;148&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#693434&quot;&gt;• Last non-missing prior to treatment&lt;/text&gt;
          &lt;text x=&quot;58&quot; y=&quot;184&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#693434&quot;&gt;• Partial dates were imputed&lt;/text&gt;
          &lt;text x=&quot;58&quot; y=&quot;220&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#693434&quot;&gt;• Standard unit&lt;/text&gt;
          &lt;text x=&quot;58&quot; y=&quot;256&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#693434&quot;&gt;• Relationship to study drug&lt;/text&gt;

          &lt;rect x=&quot;490&quot; y=&quot;36&quot; width=&quot;340&quot; height=&quot;248&quot; rx=&quot;18&quot; fill=&quot;#eef8ef&quot; stroke=&quot;#86b388&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;660&quot; y=&quot;68&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#27673a&quot; font-weight=&quot;700&quot;&gt;Operational rule style&lt;/text&gt;
          &lt;text x=&quot;518&quot; y=&quot;112&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d4f32&quot;&gt;• Formula stated&lt;/text&gt;
          &lt;text x=&quot;518&quot; y=&quot;148&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d4f32&quot;&gt;• Anchor stated&lt;/text&gt;
          &lt;text x=&quot;518&quot; y=&quot;184&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d4f32&quot;&gt;• Scope stated&lt;/text&gt;
          &lt;text x=&quot;518&quot; y=&quot;220&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d4f32&quot;&gt;• Order of operations stated&lt;/text&gt;
          &lt;text x=&quot;518&quot; y=&quot;256&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d4f32&quot;&gt;• Origin and exceptions stated&lt;/text&gt;

          &lt;path d=&quot;M370 160 C430 160, 440 160, 490 160&quot; fill=&quot;none&quot; stroke=&quot;#5e7fa4&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;490,160 478,153 478,167&quot; fill=&quot;#5e7fa4&quot;/&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;What these phrases have in common&lt;/h2&gt;

    &lt;p&gt;None of these phrases are always wrong.&lt;/p&gt;

    &lt;p&gt;The problem is that they are too short for the job they are trying to do.&lt;/p&gt;

    &lt;p&gt;They work as internal reminders for a team that already knows the logic. They do not work well as reviewer-facing metadata.&lt;/p&gt;

    &lt;p&gt;That is the shift worth making in define.xml work. Stop writing labels that point to logic. Start writing metadata that explains the logic.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;A practical test before sign-off&lt;/h2&gt;

    &lt;p&gt;Before a define.xml package goes out, ask this:&lt;/p&gt;

    &lt;div style=&quot;background:#153a63; color:#ffffff; border-radius:14px; padding:20px 22px; margin:18px 0;&quot;&gt;
      Can another programmer, or a reviewer, understand this rule without asking what we meant?
    &lt;/div&gt;

    &lt;p&gt;If the answer is no, the description is probably too thin.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Final thought&lt;/h2&gt;

    &lt;p&gt;Most review friction in define.xml does not come from dramatic mistakes.&lt;/p&gt;

    &lt;p&gt;It comes from ordinary wording that feels good enough until someone outside the team tries to rely on it.&lt;/p&gt;

    &lt;p&gt;That is why these five phrases matter. They look small. But they are often the exact place where trust in the metadata starts to weaken.&lt;/p&gt;

    &lt;div style=&quot;margin-top:36px; padding:18px 20px; border-radius:14px; background:#153a63; color:#ffffff;&quot;&gt;
      &lt;strong&gt;Suggested closing question for comments&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Which define.xml phrase do you see most often in submissions that sounds acceptable internally, but creates questions in review?
    &lt;/div&gt;

  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7707934396719644475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7707934396719644475'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/03/five-define.html' title='Five Define.xml Phrases That Sound Fine, But Trigger Review Questions'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-2220893745947486488</id><published>2026-03-30T11:54:00.003-04:00</published><updated>2026-03-30T12:12:39.958-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Define"/><category scheme="http://www.blogger.com/atom/ns#" term="define xml"/><category scheme="http://www.blogger.com/atom/ns#" term="Pinnacle 21"/><category scheme="http://www.blogger.com/atom/ns#" term="SDTM Validation"/><category scheme="http://www.blogger.com/atom/ns#" term="xml review and findings"/><title type='text'>Your SDTM Passed Validation. That Doesn’t Mean You’re Safe</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot;&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
  &lt;title&gt;Your SDTM Passed Validation. That Doesn’t Mean You’re Safe.&lt;/title&gt;
&lt;/head&gt;
&lt;body style=&quot;margin:0; padding:0; background:#f3f6fa; font-family:Arial, Helvetica, sans-serif; color:#1f2937;&quot;&gt;

  &lt;div style=&quot;max-width:900px; margin:0 auto; background:#ffffff; padding:36px 28px 64px 28px; line-height:1.75; font-size:16px;&quot;&gt;

    &lt;!-- Hero --&gt;
    &lt;div style=&quot;background:linear-gradient(135deg,#153a63,#2b68b0); color:#ffffff; padding:34px 30px; border-radius:16px; margin-bottom:30px;&quot;&gt;
      &lt;div style=&quot;font-size:12px; letter-spacing:1px; text-transform:uppercase; opacity:0.9; margin-bottom:8px;&quot;&gt;StudySAS Blog&lt;/div&gt;
      &lt;h1 style=&quot;margin:0 0 10px 0; font-size:34px; line-height:1.2;&quot;&gt;Your SDTM Passed Validation. That Doesn’t Mean You’re Safe.&lt;/h1&gt;
      &lt;p style=&quot;margin:0; font-size:18px; line-height:1.6; max-width:760px;&quot;&gt;
        Why clean Pinnacle 21 results do not always mean your SDTM package is ready for review, and why define.xml still decides how quickly a reviewer can understand and trust your data.
      &lt;/p&gt;
    &lt;/div&gt;

    &lt;p&gt;Most teams celebrate when Pinnacle 21 is clean.&lt;/p&gt;

    &lt;p&gt;That makes sense. It feels like the hard part is over.&lt;/p&gt;

    &lt;p&gt;But regulators do not review submissions that way.&lt;/p&gt;

    &lt;p&gt;They start with &lt;strong&gt;define.xml&lt;/strong&gt;.&lt;/p&gt;

    &lt;p&gt;Across repeated submission work, one pattern becomes obvious.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Clean datasets get you submitted.&lt;/strong&gt;&lt;br&gt;
    &lt;strong&gt;Clear metadata gets you through review.&lt;/strong&gt;&lt;/p&gt;

    &lt;!-- Visual 1 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #d7e1ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 1. What teams think vs what reviewers actually do&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 20px 20px; color:#5b6878; font-size:14px;&quot;&gt;A simple process view of the gap between validation completion and actual reviewer workflow.&lt;/div&gt;
      &lt;div style=&quot;padding:8px 14px 24px 14px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 300&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Comparison between team view and reviewer workflow&quot;&gt;
          &lt;defs&gt;
            &lt;linearGradient id=&quot;bluebox&quot; x1=&quot;0%&quot; y1=&quot;0%&quot; x2=&quot;100%&quot; y2=&quot;100%&quot;&gt;
              &lt;stop offset=&quot;0%&quot; stop-color=&quot;#edf4fb&quot;/&gt;
              &lt;stop offset=&quot;100%&quot; stop-color=&quot;#d9e8f8&quot;/&gt;
            &lt;/linearGradient&gt;
            &lt;linearGradient id=&quot;greenbox&quot; x1=&quot;0%&quot; y1=&quot;0%&quot; x2=&quot;100%&quot; y2=&quot;100%&quot;&gt;
              &lt;stop offset=&quot;0%&quot; stop-color=&quot;#eef7eb&quot;/&gt;
              &lt;stop offset=&quot;100%&quot; stop-color=&quot;#dcecd2&quot;/&gt;
            &lt;/linearGradient&gt;
          &lt;/defs&gt;

          &lt;rect x=&quot;20&quot; y=&quot;28&quot; width=&quot;330&quot; height=&quot;220&quot; rx=&quot;18&quot; fill=&quot;url(#bluebox)&quot; stroke=&quot;#90b3da&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;185&quot; y=&quot;58&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Common team view&lt;/text&gt;

          &lt;rect x=&quot;72&quot; y=&quot;86&quot; width=&quot;226&quot; height=&quot;46&quot; rx=&quot;12&quot; fill=&quot;#2b68b0&quot;/&gt;
          &lt;text x=&quot;185&quot; y=&quot;116&quot; text-anchor=&quot;middle&quot; font-size=&quot;19&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;P21 validation clean&lt;/text&gt;

          &lt;path d=&quot;M185 132 L185 164&quot; stroke=&quot;#6b8fb6&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;185,174 178,160 192,160&quot; fill=&quot;#6b8fb6&quot;/&gt;

          &lt;rect x=&quot;72&quot; y=&quot;180&quot; width=&quot;226&quot; height=&quot;42&quot; rx=&quot;12&quot; fill=&quot;#5f87bd&quot;/&gt;
          &lt;text x=&quot;185&quot; y=&quot;207&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;Submission ready&lt;/text&gt;

          &lt;rect x=&quot;510&quot; y=&quot;28&quot; width=&quot;330&quot; height=&quot;220&quot; rx=&quot;18&quot; fill=&quot;url(#greenbox)&quot; stroke=&quot;#8db07a&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;675&quot; y=&quot;58&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#2d5a27&quot; font-weight=&quot;700&quot;&gt;Actual reviewer flow&lt;/text&gt;

          &lt;rect x=&quot;565&quot; y=&quot;80&quot; width=&quot;220&quot; height=&quot;34&quot; rx=&quot;10&quot; fill=&quot;#62913a&quot;/&gt;
          &lt;text x=&quot;675&quot; y=&quot;102&quot; text-anchor=&quot;middle&quot; font-size=&quot;16&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;Open define.xml&lt;/text&gt;

          &lt;rect x=&quot;565&quot; y=&quot;124&quot; width=&quot;220&quot; height=&quot;34&quot; rx=&quot;10&quot; fill=&quot;#729f49&quot;/&gt;
          &lt;text x=&quot;675&quot; y=&quot;146&quot; text-anchor=&quot;middle&quot; font-size=&quot;16&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;Read derivation and origin&lt;/text&gt;

          &lt;rect x=&quot;565&quot; y=&quot;168&quot; width=&quot;220&quot; height=&quot;34&quot; rx=&quot;10&quot; fill=&quot;#84ab5d&quot;/&gt;
          &lt;text x=&quot;675&quot; y=&quot;190&quot; text-anchor=&quot;middle&quot; font-size=&quot;16&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;Check value-level metadata&lt;/text&gt;

          &lt;rect x=&quot;565&quot; y=&quot;212&quot; width=&quot;220&quot; height=&quot;34&quot; rx=&quot;10&quot; fill=&quot;#95b971&quot;/&gt;
          &lt;text x=&quot;675&quot; y=&quot;234&quot; text-anchor=&quot;middle&quot; font-size=&quot;16&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;Raise questions if unclear&lt;/text&gt;

          &lt;path d=&quot;M350 138 C420 138, 445 138, 510 138&quot; fill=&quot;none&quot; stroke=&quot;#cf8a1c&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;510,138 498,131 498,145&quot; fill=&quot;#cf8a1c&quot;/&gt;
          &lt;text x=&quot;430&quot; y=&quot;120&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#a4680e&quot; font-weight=&quot;700&quot;&gt;Interpretation gap&lt;/text&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;What reviewers actually do first&lt;/h2&gt;

    &lt;p&gt;Before they ever look at code, reviewers usually follow a simple path:&lt;/p&gt;

    &lt;ol style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;Open define.xml&lt;/li&gt;
      &lt;li&gt;Search for a variable or derivation rule&lt;/li&gt;
      &lt;li&gt;Read origin, comments, method, and value-level metadata&lt;/li&gt;
      &lt;li&gt;Decide whether the logic is clear enough to trust&lt;/li&gt;
      &lt;li&gt;Go to SDRG, ADRG, or programs only if something is still unclear&lt;/li&gt;
    &lt;/ol&gt;

    &lt;p&gt;If define.xml is vague, questions start early. Not because the programming is wrong, but because the reviewer cannot safely infer what you meant.&lt;/p&gt;

    &lt;div style=&quot;background:#fff7e9; border-left:6px solid #d08d21; padding:18px 18px 18px 20px; margin:28px 0; border-radius:10px;&quot;&gt;
      &lt;strong&gt;Practical point&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      A clean validation report tells you the package is technically acceptable. It does not tell you the metadata is reviewer-friendly.
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;A real example from SDTM LB&lt;/h2&gt;

    &lt;p&gt;Here is the kind of define.xml statement many teams use for an SDTM Findings flag:&lt;/p&gt;

    &lt;div style=&quot;background:#f5f7fa; border:1px solid #d7dee8; border-radius:12px; padding:14px 16px; margin:18px 0;&quot;&gt;
      &lt;code style=&quot;font-family:&#39;Courier New&#39;, monospace; font-size:15px; color:#25364a;&quot;&gt;Last observation before exposure flag is assigned to the last non-missing result prior to treatment.&lt;/code&gt;
    &lt;/div&gt;

    &lt;p&gt;On paper, that looks fine.&lt;/p&gt;

    &lt;p&gt;In review, it often is not enough.&lt;/p&gt;

    &lt;p&gt;A reviewer can reasonably ask:&lt;/p&gt;

    &lt;ul style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;What defines “prior to treatment”, RFSTDTC or exposure datetime?&lt;/li&gt;
      &lt;li&gt;What happens for records collected on the same day as first dose?&lt;/li&gt;
      &lt;li&gt;What if collection time is missing?&lt;/li&gt;
      &lt;li&gt;Are unscheduled visits included?&lt;/li&gt;
      &lt;li&gt;If multiple qualifying values exist, how is “last” decided?&lt;/li&gt;
      &lt;li&gt;Is the same rule used across LB, VS, EG, and QS?&lt;/li&gt;
    &lt;/ul&gt;

    &lt;p&gt;The data may be perfectly correct. The issue is that the metadata leaves room for more than one interpretation.&lt;/p&gt;

    &lt;!-- Visual 2 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #d7e1ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 2. Weak metadata vs strong metadata&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 20px 20px; color:#5b6878; font-size:14px;&quot;&gt;The difference is not style. It is whether the reviewer has to guess.&lt;/div&gt;
      &lt;div style=&quot;padding:8px 14px 24px 14px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 360&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Comparison of weak and strong metadata&quot;&gt;
          &lt;rect x=&quot;28&quot; y=&quot;32&quot; width=&quot;356&quot; height=&quot;286&quot; rx=&quot;18&quot; fill=&quot;#fff1f1&quot; stroke=&quot;#d69797&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;206&quot; y=&quot;66&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#8f2e2e&quot; font-weight=&quot;700&quot;&gt;Weak metadata&lt;/text&gt;
          &lt;rect x=&quot;66&quot; y=&quot;92&quot; width=&quot;280&quot; height=&quot;52&quot; rx=&quot;12&quot; fill=&quot;#c74a4a&quot;/&gt;
          &lt;text x=&quot;206&quot; y=&quot;124&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;“Last non-missing prior to treatment”&lt;/text&gt;
          &lt;text x=&quot;72&quot; y=&quot;182&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#633030&quot;&gt;• No anchor&lt;/text&gt;
          &lt;text x=&quot;72&quot; y=&quot;218&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#633030&quot;&gt;• No same-day rule&lt;/text&gt;
          &lt;text x=&quot;72&quot; y=&quot;254&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#633030&quot;&gt;• No missing-time rule&lt;/text&gt;
          &lt;text x=&quot;72&quot; y=&quot;290&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#633030&quot;&gt;• No tie-break logic&lt;/text&gt;

          &lt;rect x=&quot;476&quot; y=&quot;32&quot; width=&quot;356&quot; height=&quot;286&quot; rx=&quot;18&quot; fill=&quot;#eef8ef&quot; stroke=&quot;#86b388&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;654&quot; y=&quot;66&quot; text-anchor=&quot;middle&quot; font-size=&quot;24&quot; font-family=&quot;Arial&quot; fill=&quot;#27673a&quot; font-weight=&quot;700&quot;&gt;Strong metadata&lt;/text&gt;
          &lt;rect x=&quot;514&quot; y=&quot;92&quot; width=&quot;280&quot; height=&quot;52&quot; rx=&quot;12&quot; fill=&quot;#3f8a4d&quot;/&gt;
          &lt;text x=&quot;654&quot; y=&quot;124&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;Operational rule is explicit&lt;/text&gt;
          &lt;text x=&quot;520&quot; y=&quot;182&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d4f32&quot;&gt;• Defines anchor&lt;/text&gt;
          &lt;text x=&quot;520&quot; y=&quot;218&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d4f32&quot;&gt;• States same-day handling&lt;/text&gt;
          &lt;text x=&quot;520&quot; y=&quot;254&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d4f32&quot;&gt;• Handles missing time&lt;/text&gt;
          &lt;text x=&quot;520&quot; y=&quot;290&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d4f32&quot;&gt;• Resolves ties consistently&lt;/text&gt;

          &lt;path d=&quot;M384 174 C426 174, 438 174, 476 174&quot; fill=&quot;none&quot; stroke=&quot;#5e7fa4&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;476,174 464,167 464,181&quot; fill=&quot;#5e7fa4&quot;/&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;What strong metadata looks like in SDTM&lt;/h2&gt;

    &lt;p&gt;A better define.xml statement does not just sound more formal. It removes doubt.&lt;/p&gt;

    &lt;div style=&quot;background:#eef8ef; border:1px solid #bbd9bf; border-radius:12px; padding:18px 18px; margin:18px 0;&quot;&gt;
      &lt;strong&gt;Example of stronger wording&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      LBLOBXFL is assigned as &#39;Y&#39; to the chronologically latest non-missing result collected before first exposure. If only dates are available, collection date must be strictly earlier than DM.RFSTDTC. Records on the first-dose date are eligible only when both collection time and dosing time are available and the collection occurs before dosing. Records with missing time on the first-dose date are not eligible. If more than one qualifying records exist, the latest chronological record is selected.
    &lt;/div&gt;

    &lt;p&gt;Now the reviewer knows the anchor, the same-day rule, the missing-time rule, and the tie-break rule.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;CDISC-style metadata flow&lt;/h2&gt;

    &lt;p&gt;At a practical level, define.xml sits in the middle of a traceability chain. The reviewer should be able to move through that chain without guessing.&lt;/p&gt;

    &lt;!-- Visual 3 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #d7e1ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 3. Traceability path from collection to reviewer interpretation&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 20px 20px; color:#5b6878; font-size:14px;&quot;&gt;A CDISC-style flow showing how collected data becomes reviewer-facing metadata.&lt;/div&gt;
      &lt;div style=&quot;padding:8px 14px 24px 14px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 250&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Traceability flow diagram&quot;&gt;
          &lt;rect x=&quot;18&quot; y=&quot;86&quot; width=&quot;140&quot; height=&quot;72&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#90b3da&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;88&quot; y=&quot;116&quot; text-anchor=&quot;middle&quot; font-size=&quot;19&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;CRF&lt;/text&gt;
          &lt;text x=&quot;88&quot; y=&quot;138&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#3e5876&quot;&gt;Collected source&lt;/text&gt;

          &lt;rect x=&quot;186&quot; y=&quot;86&quot; width=&quot;140&quot; height=&quot;72&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#90b3da&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;256&quot; y=&quot;116&quot; text-anchor=&quot;middle&quot; font-size=&quot;19&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;SDTM&lt;/text&gt;
          &lt;text x=&quot;256&quot; y=&quot;138&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#3e5876&quot;&gt;Standardized data&lt;/text&gt;

          &lt;rect x=&quot;354&quot; y=&quot;72&quot; width=&quot;152&quot; height=&quot;100&quot; rx=&quot;14&quot; fill=&quot;#f4f8ee&quot; stroke=&quot;#8db07a&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;430&quot; y=&quot;102&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#2d5a27&quot; font-weight=&quot;700&quot;&gt;define.xml&lt;/text&gt;
          &lt;text x=&quot;430&quot; y=&quot;126&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#476734&quot;&gt;Origin&lt;/text&gt;
          &lt;text x=&quot;430&quot; y=&quot;146&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#476734&quot;&gt;Method&lt;/text&gt;
          &lt;text x=&quot;430&quot; y=&quot;166&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#476734&quot;&gt;Value-level rules&lt;/text&gt;

          &lt;rect x=&quot;534&quot; y=&quot;86&quot; width=&quot;140&quot; height=&quot;72&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#90b3da&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;604&quot; y=&quot;116&quot; text-anchor=&quot;middle&quot; font-size=&quot;19&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;SDRG&lt;/text&gt;
          &lt;text x=&quot;604&quot; y=&quot;138&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#3e5876&quot;&gt;Narrative context&lt;/text&gt;

          &lt;rect x=&quot;702&quot; y=&quot;86&quot; width=&quot;140&quot; height=&quot;72&quot; rx=&quot;14&quot; fill=&quot;#fff7e8&quot; stroke=&quot;#d3a44d&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;772&quot; y=&quot;116&quot; text-anchor=&quot;middle&quot; font-size=&quot;19&quot; font-family=&quot;Arial&quot; fill=&quot;#8a6313&quot; font-weight=&quot;700&quot;&gt;Reviewer&lt;/text&gt;
          &lt;text x=&quot;772&quot; y=&quot;138&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#8a6313&quot;&gt;Interpretation&lt;/text&gt;

          &lt;path d=&quot;M158 122 L186 122&quot; stroke=&quot;#6a8eb8&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;186,122 174,115 174,129&quot; fill=&quot;#6a8eb8&quot;/&gt;

          &lt;path d=&quot;M326 122 L354 122&quot; stroke=&quot;#6a8eb8&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;354,122 342,115 342,129&quot; fill=&quot;#6a8eb8&quot;/&gt;

          &lt;path d=&quot;M506 122 L534 122&quot; stroke=&quot;#6a8eb8&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;534,122 522,115 522,129&quot; fill=&quot;#6a8eb8&quot;/&gt;

          &lt;path d=&quot;M674 122 L702 122&quot; stroke=&quot;#c78b1f&quot; stroke-width=&quot;4&quot;/&gt;
          &lt;polygon points=&quot;702,122 690,115 690,129&quot; fill=&quot;#c78b1f&quot;/&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;XML snippet, weak vs stronger version&lt;/h2&gt;

    &lt;p&gt;One of the best ways to see the problem is in the XML itself. Here is the same SDTM concept shown two different ways.&lt;/p&gt;

    &lt;!-- XML block weak --&gt;
    &lt;div style=&quot;margin:22px 0 12px 0; font-weight:bold; color:#8f2e2e;&quot;&gt;Weak XML example&lt;/div&gt;
    &lt;div style=&quot;background:#fbfbfc; border:1px solid #d9dee7; border-radius:12px; overflow:hidden; margin-bottom:22px;&quot;&gt;
      &lt;div style=&quot;background:#e9eef5; padding:10px 14px; font-size:13px; color:#4d6078; border-bottom:1px solid #d9dee7; font-family:Arial, Helvetica, sans-serif;&quot;&gt;
        Listing 1. Minimal method description for SDTM LBLOBXFL
      &lt;/div&gt;
      &lt;pre style=&quot;margin:0; padding:18px 18px; overflow:auto; font-size:14px; line-height:1.6; font-family:&#39;Courier New&#39;, monospace; color:#243447;&quot;&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;ItemDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;IT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;DataType=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Length=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;Last Observation Before Exposure Flag&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Origin&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Derived&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodRef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;MethodOID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/ItemDef&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Last Observation Before Exposure Flag&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Computation&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
      Last non-missing result prior to treatment.
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/MethodDef&amp;gt;&lt;/span&gt;&lt;/pre&gt;
    &lt;/div&gt;

    &lt;!-- XML block strong --&gt;
    &lt;div style=&quot;margin:22px 0 12px 0; font-weight:bold; color:#27673a;&quot;&gt;Stronger XML example&lt;/div&gt;
    &lt;div style=&quot;background:#fbfbfc; border:1px solid #d9dee7; border-radius:12px; overflow:hidden; margin-bottom:26px;&quot;&gt;
      &lt;div style=&quot;background:#e9eef5; padding:10px 14px; font-size:13px; color:#4d6078; border-bottom:1px solid #d9dee7; font-family:Arial, Helvetica, sans-serif;&quot;&gt;
        Listing 2. Reviewer-friendly method description for SDTM LBLOBXFL
      &lt;/div&gt;
      &lt;pre style=&quot;margin:0; padding:18px 18px; overflow:auto; font-size:14px; line-height:1.6; font-family:&#39;Courier New&#39;, monospace; color:#243447;&quot;&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;ItemDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;IT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;DataType=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;text&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Length=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;Last Observation Before Exposure Flag&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Origin&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Derived&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodRef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;MethodOID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/ItemDef&amp;gt;&lt;/span&gt;

&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;MethodDef&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;OID=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;MT.LB.LBLOBXFL&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Name=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Last Observation Before Exposure Flag Derivation&quot;&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;Type=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;Computation&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;Description&amp;gt;&lt;/span&gt;
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;TranslatedText&lt;/span&gt; &lt;span style=&quot;color:#7a3e9d;&quot;&gt;xml:lang=&lt;/span&gt;&lt;span style=&quot;color:#b14d00;&quot;&gt;&quot;en&quot;&lt;/span&gt;&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;gt;&lt;/span&gt;
      LBLOBXFL is assigned as &#39;Y&#39; to the chronologically latest non-missing
      result collected before first exposure. If only dates are available,
      collection date must be strictly earlier than DM.RFSTDTC. Records on
      the first-dose date are eligible only when both collection time and
      dosing time are available and the collection occurs before dosing.
      Records with missing time on the first-dose date are not eligible.
      If multiple qualifying records exist, the latest chronological record
      is selected.
    &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/TranslatedText&amp;gt;&lt;/span&gt;
  &lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/Description&amp;gt;&lt;/span&gt;
&lt;span style=&quot;color:#1a4f8f;&quot;&gt;&amp;lt;/MethodDef&amp;gt;&lt;/span&gt;&lt;/pre&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Where this usually breaks&lt;/h2&gt;

    &lt;p&gt;From experience, these are the places where weak metadata triggers the most review friction:&lt;/p&gt;

    &lt;table style=&quot;width:100%; border-collapse:collapse; margin:20px 0 30px 0; font-size:15px;&quot;&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th style=&quot;text-align:left; padding:12px; background:#153a63; color:#ffffff; border:1px solid #d7e1ee;&quot;&gt;Area&lt;/th&gt;
          &lt;th style=&quot;text-align:left; padding:12px; background:#153a63; color:#ffffff; border:1px solid #d7e1ee;&quot;&gt;Common weak wording&lt;/th&gt;
          &lt;th style=&quot;text-align:left; padding:12px; background:#153a63; color:#ffffff; border:1px solid #d7e1ee;&quot;&gt;What is missing&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;&lt;strong&gt;Study Day (--DY)&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Derived from reference start date&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Formula, sign convention, partial date handling&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr style=&quot;background:#f8fbff;&quot;&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;&lt;strong&gt;Partial dates&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Partial dates were imputed&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Method, scope, and where the imputed value is used&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;&lt;strong&gt;Lab standardization&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Standard unit&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Conversion rule, order of operations, flag impact&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr style=&quot;background:#f8fbff;&quot;&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;&lt;strong&gt;Cross-domain rules&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Separate domain notes only&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Whether the same concept behaves consistently across domains&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;&lt;strong&gt;Traceability&lt;/strong&gt;&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Relationship to study drug&lt;/td&gt;
          &lt;td style=&quot;padding:12px; border:1px solid #d7e1ee;&quot;&gt;Collected vs assigned vs sponsor-derived logic&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;

    &lt;!-- Visual 4 --&gt;
    &lt;div style=&quot;margin:34px 0; border:1px solid #d7e1ee; border-radius:16px; overflow:hidden; background:#fbfdff;&quot;&gt;
      &lt;div style=&quot;padding:16px 20px 8px 20px; font-size:22px; font-weight:bold; color:#153a63;&quot;&gt;Figure 4. Define.xml review checklist&lt;/div&gt;
      &lt;div style=&quot;padding:0 20px 20px 20px; color:#5b6878; font-size:14px;&quot;&gt;A simple internal test before final package release.&lt;/div&gt;
      &lt;div style=&quot;padding:8px 14px 24px 14px;&quot;&gt;
        &lt;svg viewBox=&quot;0 0 860 340&quot; width=&quot;100%&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Checklist flow for define.xml review&quot;&gt;
          &lt;rect x=&quot;322&quot; y=&quot;18&quot; width=&quot;216&quot; height=&quot;48&quot; rx=&quot;12&quot; fill=&quot;#2b68b0&quot;/&gt;
          &lt;text x=&quot;430&quot; y=&quot;49&quot; text-anchor=&quot;middle&quot; font-size=&quot;21&quot; font-family=&quot;Arial&quot; fill=&quot;#ffffff&quot; font-weight=&quot;700&quot;&gt;define.xml review&lt;/text&gt;

          &lt;rect x=&quot;46&quot; y=&quot;106&quot; width=&quot;166&quot; height=&quot;64&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#90b3da&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;129&quot; y=&quot;132&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Reproducibility&lt;/text&gt;
          &lt;text x=&quot;129&quot; y=&quot;154&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#45617f&quot;&gt;Can it be rebuilt?&lt;/text&gt;

          &lt;rect x=&quot;240&quot; y=&quot;106&quot; width=&quot;166&quot; height=&quot;64&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#90b3da&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;323&quot; y=&quot;132&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Ambiguity&lt;/text&gt;
          &lt;text x=&quot;323&quot; y=&quot;154&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#45617f&quot;&gt;More than one meaning?&lt;/text&gt;

          &lt;rect x=&quot;434&quot; y=&quot;106&quot; width=&quot;166&quot; height=&quot;64&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#90b3da&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;517&quot; y=&quot;132&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Boundaries&lt;/text&gt;
          &lt;text x=&quot;517&quot; y=&quot;154&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#45617f&quot;&gt;Edge cases defined?&lt;/text&gt;

          &lt;rect x=&quot;628&quot; y=&quot;106&quot; width=&quot;166&quot; height=&quot;64&quot; rx=&quot;14&quot; fill=&quot;#eef4fb&quot; stroke=&quot;#90b3da&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;711&quot; y=&quot;132&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#153a63&quot; font-weight=&quot;700&quot;&gt;Consistency&lt;/text&gt;
          &lt;text x=&quot;711&quot; y=&quot;154&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#45617f&quot;&gt;Across domains?&lt;/text&gt;

          &lt;rect x=&quot;322&quot; y=&quot;236&quot; width=&quot;216&quot; height=&quot;68&quot; rx=&quot;14&quot; fill=&quot;#eef8ef&quot; stroke=&quot;#86b388&quot; stroke-width=&quot;2&quot;/&gt;
          &lt;text x=&quot;430&quot; y=&quot;262&quot; text-anchor=&quot;middle&quot; font-size=&quot;18&quot; font-family=&quot;Arial&quot; fill=&quot;#27673a&quot; font-weight=&quot;700&quot;&gt;Traceability&lt;/text&gt;
          &lt;text x=&quot;430&quot; y=&quot;286&quot; text-anchor=&quot;middle&quot; font-size=&quot;14&quot; font-family=&quot;Arial&quot; fill=&quot;#3d633f&quot;&gt;Can reviewer follow CRF → SDTM → derived rule?&lt;/text&gt;

          &lt;path d=&quot;M430 66 L129 106&quot; stroke=&quot;#7d9cc1&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M430 66 L323 106&quot; stroke=&quot;#7d9cc1&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M430 66 L517 106&quot; stroke=&quot;#7d9cc1&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M430 66 L711 106&quot; stroke=&quot;#7d9cc1&quot; stroke-width=&quot;3&quot;/&gt;
          &lt;path d=&quot;M430 170 L430 236&quot; stroke=&quot;#8cab62&quot; stroke-width=&quot;3&quot;/&gt;

          &lt;text x=&quot;430&quot; y=&quot;328&quot; text-anchor=&quot;middle&quot; font-size=&quot;16&quot; font-family=&quot;Arial&quot; fill=&quot;#8f2e2e&quot; font-weight=&quot;700&quot;&gt;If any answer is “no”, expect reviewer questions.&lt;/text&gt;
        &lt;/svg&gt;
      &lt;/div&gt;
    &lt;/div&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;A simple review checklist before submission&lt;/h2&gt;

    &lt;ol style=&quot;padding-left:24px;&quot;&gt;
      &lt;li&gt;&lt;strong&gt;Reproducibility&lt;/strong&gt;, can an experienced programmer recreate the variable using only define.xml?&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Ambiguity&lt;/strong&gt;, does the description allow more than one reasonable interpretation?&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Boundary handling&lt;/strong&gt;, are same-day, missing-time, partial-date, repeated-record, and tie cases clearly defined?&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Consistency&lt;/strong&gt;, is the same concept handled the same way across domains unless an exception is explicitly stated?&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Traceability&lt;/strong&gt;, can a reviewer move from CRF to SDTM to derived variable without guessing?&lt;/li&gt;
    &lt;/ol&gt;

    &lt;p&gt;If any answer is no, the package may still validate cleanly, but it is not fully review-ready.&lt;/p&gt;

    &lt;h2 style=&quot;font-size:28px; color:#153a63; margin:34px 0 12px 0;&quot;&gt;Final thought&lt;/h2&gt;

    &lt;p&gt;Passing technical validation is necessary.&lt;/p&gt;
    &lt;p&gt;It is not sufficient.&lt;/p&gt;
    &lt;p&gt;Define.xml is not just a supporting file. For many reviewers, it is the first real interface to your SDTM data.&lt;/p&gt;
    &lt;p&gt;If they had only this file, would they understand your submission, or question it?&lt;/p&gt;

    &lt;div style=&quot;margin-top:36px; padding:18px 20px; border-radius:14px; background:#153a63; color:#ffffff;&quot;&gt;
      &lt;strong&gt;Suggested closing question for comments&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
      Have you seen define.xml wording that looked fine internally, but triggered avoidable review questions later?
    &lt;/div&gt;

  &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/2220893745947486488'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/2220893745947486488'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2026/03/your-sdtm-passed-validation-that-doesnt.html' title='Your SDTM Passed Validation. That Doesn’t Mean You’re Safe'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-4225413153328309952</id><published>2025-01-23T08:30:00.003-05:00</published><updated>2025-01-23T08:33:48.390-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="cSDRG study design section"/><category scheme="http://www.blogger.com/atom/ns#" term="protocol to cSDRG tense changes"/><category scheme="http://www.blogger.com/atom/ns#" term="study design documentation"/><title type='text'>From Protocol to cSDRG: how to write cSDRG study design section</title><content type='html'>
&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: &#39;Segoe UI&#39;, Tahoma, Geneva, Verdana, sans-serif;
            line-height: 1.6;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            color: #333;
        }
        h1 {
            color: #2c3e50;
            border-bottom: 2px solid #3498db;
            padding-bottom: 10px;
        }
        h2 {
            color: #2980b9;
            margin-top: 30px;
        }
        .example-box {
            background-color: #f8f9fa;
            border-left: 4px solid #3498db;
            padding: 15px;
            margin: 20px 0;
        }
        .pro-tip {
            background-color: #e8f4f8;
            border-radius: 5px;
            padding: 15px;
            margin: 20px 0;
        }
        .comparison-table {
            width: 100%;
            border-collapse: collapse;
            margin: 20px 0;
        }
        .comparison-table th, .comparison-table td {
            border: 1px solid #ddd;
            padding: 12px;
            text-align: left;
        }
        .comparison-table th {
            background-color: #f4f4f4;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
  
    &lt;h1&gt;&lt;/h1&gt;
    
    &lt;p&gt;As clinical research professionals, we often grapple with a unique challenge: transforming our forward-looking protocol documents into retrospective study documentation. One particular area where this becomes crucial is in the Clinical Study Data Reviewer&#39;s Guide (cSDRG), especially when documenting the Study Design section. Today, we&#39;ll explore why simply copying and pasting from your protocol isn&#39;t the best approach, and how to effectively translate your study design documentation into its proper historical context.&lt;/p&gt;

    &lt;h2&gt;Why Time Matters in Clinical Documentation&lt;/h2&gt;
    
    &lt;p&gt;The protocol and cSDRG serve fundamentally different purposes in the clinical research narrative. Your protocol is your roadmap - it outlines what you plan to do. The cSDRG, on the other hand, tells the story of what actually happened. This distinction is crucial for regulatory reviewers who need to understand how your study unfolded in reality.&lt;/p&gt;

    &lt;div class=&quot;pro-tip&quot;&gt;
        &lt;strong&gt;Pro Tip:&lt;/strong&gt; Think of your protocol as a travel itinerary and your cSDRG as a travel journal. While your itinerary shows where you planned to go, your journal documents where you actually went and what really happened along the way.
    &lt;/div&gt;

    &lt;h2&gt;The Art of Translation: From Future to Past&lt;/h2&gt;

    &lt;p&gt;Converting your study design documentation isn&#39;t just about changing verb tenses - it&#39;s about capturing the reality of your study execution. Here&#39;s how to approach this transformation effectively:&lt;/p&gt;

    &lt;div class=&quot;example-box&quot;&gt;
        &lt;h3&gt;Example Transformations&lt;/h3&gt;
        &lt;table class=&quot;comparison-table&quot;&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;Protocol (Future Tense)&lt;/th&gt;
                    &lt;th&gt;cSDRG (Past Tense)&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                &lt;tr&gt;
                    &lt;td&gt;&quot;This will be a randomized, double-blind study that will enroll 100 subjects...&quot;&lt;/td&gt;
                    &lt;td&gt;&quot;This was a randomized, double-blind study that enrolled 98 subjects...&quot;&lt;/td&gt;
                &lt;/tr&gt;
                &lt;tr&gt;
                    &lt;td&gt;&quot;Subjects will receive treatment for 12 weeks...&quot;&lt;/td&gt;
                    &lt;td&gt;&quot;Subjects received treatment for 12 weeks, with a mean treatment duration of 11.2 weeks...&quot;&lt;/td&gt;
                &lt;/tr&gt;
                &lt;tr&gt;
                    &lt;td&gt;&quot;Blood samples will be collected at baseline and weeks 4, 8, and 12.&quot;&lt;/td&gt;
                    &lt;td&gt;&quot;Blood samples were collected at baseline and weeks 4, 8, and 12, with additional unscheduled sampling as needed.&quot;&lt;/td&gt;
                &lt;/tr&gt;
            &lt;/tbody&gt;
        &lt;/table&gt;
    &lt;/div&gt;

    &lt;h2&gt;Best Practices for Study Design Documentation&lt;/h2&gt;

    &lt;p&gt;When preparing your cSDRG Study Design section, consider these key principles:&lt;/p&gt;

    &lt;div class=&quot;example-box&quot;&gt;
        &lt;ol&gt;
            &lt;li&gt;&lt;strong&gt;Use Actual Numbers:&lt;/strong&gt; Replace planned enrollment figures with actual participant counts.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Document Deviations:&lt;/strong&gt; Include any significant departures from the planned design that occurred during study execution.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Maintain Consistency:&lt;/strong&gt; Ensure all descriptions align with the past-tense reporting style used throughout the cSDRG.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Add Context:&lt;/strong&gt; Include relevant details about how procedures were actually implemented.&lt;/li&gt;
        &lt;/ol&gt;
    &lt;/div&gt;

    &lt;h2&gt;The Impact on SDTM Integration&lt;/h2&gt;

    &lt;p&gt;This careful translation of study design documentation becomes particularly important when working with Study Data Tabulation Model (SDTM) datasets. Your cSDRG serves as a bridge between your protocol&#39;s intentions and your SDTM data&#39;s reality, helping reviewers understand any discrepancies or special circumstances that emerged during the study.&lt;/p&gt;

    &lt;div class=&quot;pro-tip&quot;&gt;
        &lt;strong&gt;Remember:&lt;/strong&gt; Your cSDRG should tell the story of your study as it actually happened, providing context for your SDTM datasets and helping reviewers understand your data in its proper context.
    &lt;/div&gt;

    &lt;h2&gt;Conclusion&lt;/h2&gt;

    &lt;p&gt;Creating an effective cSDRG Study Design section requires more than simple copy-and-paste operations from your protocol. By thoughtfully translating your study design documentation into past tense and incorporating actual study outcomes, you create a more valuable resource for regulatory reviewers and maintain the integrity of your clinical study documentation.&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;

</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/4225413153328309952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/4225413153328309952'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2025/01/from-protocol-to-csdrg-art-of-time.html' title='From Protocol to cSDRG: how to write cSDRG study design section'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-8682127494935716661</id><published>2025-01-15T15:27:00.001-05:00</published><updated>2025-01-15T15:28:11.546-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dataset Structure and Keys Column in Define.xml"/><category scheme="http://www.blogger.com/atom/ns#" term="Dataset Structure Documentation in Define.xml"/><title type='text'>The Critical Importance of Dataset Structure Documentation in Define.xml: A Senior SDTM Programmer&#39;s Perspective</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;SDTM Dataset Structure Documentation: A Senior Programmer&#39;s Perspective&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            color: #333;
        }
        .header {
            background-color: #f5f5f5;
            padding: 20px;
            border-radius: 5px;
            margin-bottom: 30px;
        }
        .author-info {
            font-style: italic;
            color: #666;
            margin-bottom: 20px;
        }
        .code-block {
            background-color: #f8f8f8;
            padding: 15px;
            border-left: 4px solid #2196F3;
            margin: 20px 0;
            overflow-x: auto;
        }
        .highlight {
            background-color: #fff3cd;
            padding: 2px 5px;
            border-radius: 3px;
        }
        .tip {
            background-color: #e3f2fd;
            padding: 15px;
            border-radius: 5px;
            margin: 20px 0;
        }
        h2 {
            color: #1976D2;
            margin-top: 30px;
        }
        h3 {
            color: #2196F3;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;section&gt;
        &lt;h2&gt;Introduction: Why I&#39;m Writing This&lt;/h2&gt;
        &lt;p&gt;
            After spending over 15 years mapping clinical data to SDTM, I&#39;ve seen firsthand how proper dataset structure documentation can make or break a submission. Recently, I encountered a situation where incomplete structure descriptions in Define.xml led to significant rework in a late-phase study. This experience prompted me to share my insights on why meticulous documentation of dataset structures is crucial.
        &lt;/p&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;The Real-World Impact of Structure Documentation&lt;/h2&gt;
        &lt;p&gt;
            Let me share a recent example from my work. We inherited a study where the LB domain structure was documented simply as:
        &lt;/p&gt;
        &lt;div class=&quot;code-block&quot;&gt;
            &quot;One record per analyte per planned time point per visit per subject&quot;
        &lt;/div&gt;
        &lt;p&gt;
            However, the key variables included:
        &lt;/p&gt;
        &lt;div class=&quot;code-block&quot;&gt;
            STUDYID, USUBJID, LBREFID, LBCAT, LBSCAT, LBTESTCD, LBMETHOD, VISITNUM, LBSTAT, LBORRES, LBDTC
        &lt;/div&gt;
        &lt;p&gt;
            This mismatch led to several issues:
        &lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;Data mapping programs didn&#39;t account for method variations (LBMETHOD)&lt;/li&gt;
            &lt;li&gt;Validation checks missed status-dependent conditions (LBSTAT)&lt;/li&gt;
            &lt;li&gt;Analysis datasets required rework due to unexpected categorical groupings (LBCAT, LBSCAT)&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;Programming Implications&lt;/h2&gt;
        &lt;div class=&quot;tip&quot;&gt;
            &lt;strong&gt;Pro Tip:&lt;/strong&gt; Always write your SDTM specification review findings in a way that allows for quick implementation of corrections.
        &lt;/div&gt;
        &lt;p&gt;
            From a programming perspective, comprehensive structure descriptions help us:
        &lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;Write more efficient data mapping code by understanding all required keys&lt;/li&gt;
            &lt;li&gt;Implement proper sort orders based on the full record uniqueness&lt;/li&gt;
            &lt;li&gt;Create more robust validation checks&lt;/li&gt;
            &lt;li&gt;Design better performance optimization strategies&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;Common Structural Documentation Issues I&#39;ve Encountered&lt;/h2&gt;
        &lt;h3&gt;1. The FA (Findings About) Domain Challenge&lt;/h3&gt;
        &lt;p&gt;
            A classic example is the FA domain, where I often see this structure:
        &lt;/p&gt;
        &lt;div class=&quot;code-block&quot;&gt;
            Original: &quot;One record per finding per object per time point per visit per subject&quot;
        &lt;/div&gt;
        &lt;p&gt;
            What it should be:
        &lt;/p&gt;
        &lt;div class=&quot;code-block&quot;&gt;
            Improved: &quot;One record per finding per object per grouped observation (FAGRPID), including categorization (FACAT) and method (FAMETHOD), per time point per visit per subject&quot;
        &lt;/div&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;Practical Solutions I&#39;ve Implemented&lt;/h2&gt;
        &lt;p&gt;
            Over the years, I&#39;ve developed these practices for better structure documentation:
        &lt;/p&gt;
        &lt;ol&gt;
            &lt;li&gt;
                &lt;strong&gt;Automated Comparison Tool:&lt;/strong&gt; I&#39;ve created a SAS macro that compares Define.xml structure descriptions against actual key variables used in the datasets.
            &lt;/li&gt;
            &lt;li&gt;
                &lt;strong&gt;Structure Template Library:&lt;/strong&gt; Maintaining a repository of comprehensive structure descriptions for common scenarios.
            &lt;/li&gt;
            &lt;li&gt;
                &lt;strong&gt;Review Checklist:&lt;/strong&gt; A systematic approach to verify structure completeness.
            &lt;/li&gt;
        &lt;/ol&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;Impact on Study Timeline and Resources&lt;/h2&gt;
        &lt;p&gt;
            In my experience managing SDTM conversions, proper structure documentation can:
        &lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;Reduce mapping programming time by ~25%&lt;/li&gt;
            &lt;li&gt;Cut validation issues by up to 40%&lt;/li&gt;
            &lt;li&gt;Minimize rework during QC and analysis dataset creation&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;Recommendations for Fellow SDTM Programmers&lt;/h2&gt;
        &lt;div class=&quot;tip&quot;&gt;
            &lt;strong&gt;Key Practice:&lt;/strong&gt; Always validate your structure descriptions against both the SDTM Implementation Guide and your actual data.
        &lt;/div&gt;
        &lt;p&gt;
            Based on my experience, here are crucial steps:
        &lt;/p&gt;
        &lt;ol&gt;
            &lt;li&gt;Review structure descriptions during specification development&lt;/li&gt;
            &lt;li&gt;Cross-reference with SDTM IG examples&lt;/li&gt;
            &lt;li&gt;Validate against actual data patterns&lt;/li&gt;
            &lt;li&gt;Document any special cases or exceptions&lt;/li&gt;
        &lt;/ol&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;Conclusion: A Call to Action&lt;/h2&gt;
        &lt;p&gt;
            As senior SDTM programmers, it&#39;s our responsibility to ensure that our Define.xml documentation serves its purpose effectively. Proper structure documentation isn&#39;t just about compliance – it&#39;s about creating efficient, maintainable, and high-quality clinical data submissions.
        &lt;/p&gt;
        &lt;p&gt;
            Remember: The time invested in proper documentation pays dividends throughout the study lifecycle and across future studies.
        &lt;/p&gt;
    &lt;/section&gt;

    &lt;footer style=&quot;margin-top: 40px; padding-top: 20px; border-top: 1px solid #ddd; text-align: center;&quot;&gt;
        &lt;p&gt;
            Share your experiences or reach out for additional insights on SDTM implementation best practices.
        &lt;/p&gt;
    &lt;/footer&gt;
&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/8682127494935716661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/8682127494935716661'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2025/01/the-critical-importance-of-dataset.html' title='The Critical Importance of Dataset Structure Documentation in Define.xml: A Senior SDTM Programmer&#39;s Perspective'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-750762088325638314</id><published>2025-01-15T14:31:00.002-05:00</published><updated>2025-01-15T14:31:39.913-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Comments Tab in Define.xml"/><title type='text'>Mastering the Art of Comments in Define.xml: Your Ultimate Guide to Clinical Data Documentation</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;Mastering the Art of Comments in Define.xml: Your Ultimate Guide to Clinical Data Documentation&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            color: #333;
        }
        h1 {
            color: #2c3e50;
            border-bottom: 2px solid #3498db;
            padding-bottom: 10px;
        }
        h2 {
            color: #34495e;
            margin-top: 30px;
        }
        .highlight {
            background-color: #f8f9fa;
            padding: 20px;
            border-left: 4px solid #3498db;
            margin: 20px 0;
        }
        .author-info {
            font-style: italic;
            color: #666;
            margin: 20px 0;
        }
        .example {
            background-color: #f1f1f1;
            padding: 15px;
            border-radius: 5px;
            margin: 10px 0;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;&lt;/h1&gt;
    
    &lt;div class=&quot;author-info&quot;&gt;
        Posted by Sarath&lt;br&gt;
    &lt;/div&gt;

    &lt;p&gt;
        In the world of clinical data management, the define.xml file serves as the cornerstone of dataset documentation. 
        While most professionals focus on the basic structural elements, the Comments tab often remains an underutilized 
        goldmine of information. Today, we&#39;ll dive deep into how to leverage this powerful feature to enhance your 
        clinical data documentation.
    &lt;/p&gt;

    &lt;div class=&quot;highlight&quot;&gt;
        &lt;p&gt;&lt;strong&gt;Quick Takeaway:&lt;/strong&gt; Well-crafted comments in your define.xml can significantly reduce queries 
        during regulatory submissions and streamline the review process.&lt;/p&gt;
    &lt;/div&gt;

    &lt;h2&gt;Why Comments Matter in Define.xml&lt;/h2&gt;
    &lt;p&gt;
        The Comments tab isn&#39;t just an afterthought - it&#39;s your opportunity to provide crucial context that doesn&#39;t fit 
        neatly into other standardized fields. Think of it as your chance to tell the complete story behind your data.
    &lt;/p&gt;

    &lt;h2&gt;8 Essential Comment Categories You Can&#39;t Ignore&lt;/h2&gt;
    
    &lt;h3&gt;1. Clarification on Derived Variables&lt;/h3&gt;
    &lt;div class=&quot;example&quot;&gt;
        Example: &quot;AGE is derived based on the difference between RFSTDTC (Reference Start Date) and BRTHDTC (Birth Date), divided by 365.25.&quot;
    &lt;/div&gt;

    &lt;h3&gt;2. Handling of Missing Data&lt;/h3&gt;
    &lt;div class=&quot;example&quot;&gt;
        Example: &quot;VISITNUM for unscheduled visits is assigned based on the next available scheduled visit number plus 0.1.&quot;
    &lt;/div&gt;

    &lt;h3&gt;3. Custom Controlled Terminology&lt;/h3&gt;
    &lt;div class=&quot;example&quot;&gt;
        Example: &quot;LBTEST includes custom terms for additional lab tests specific to this study, such as &#39;NLRATIO&#39; (Neutrophil-to-Lymphocyte Ratio).&quot;
    &lt;/div&gt;

    &lt;h3&gt;4. Explanation of Anomalies or Outliers&lt;/h3&gt;
    &lt;div class=&quot;example&quot;&gt;
        Example: &quot;Heart rate values exceeding 200 bpm were confirmed with the investigator as accurate measurements during exercise testing.&quot;
    &lt;/div&gt;

    &lt;h3&gt;5. Mapping Decisions&lt;/h3&gt;
    &lt;div class=&quot;example&quot;&gt;
        Example: &quot;AEDECOD was mapped to MedDRA v25.0 using coding guidelines. Non-mappable terms were assigned as &#39;OTHER.&#39;&quot;
    &lt;/div&gt;

    &lt;h3&gt;6. Complex or Study-Specific Rules&lt;/h3&gt;
    &lt;div class=&quot;example&quot;&gt;
        Example: &quot;DTHFL is populated as &#39;Y&#39; if the death date is before the cutoff date; otherwise, it is null.&quot;
    &lt;/div&gt;

    &lt;h3&gt;7. Reference to External Data&lt;/h3&gt;
    &lt;div class=&quot;example&quot;&gt;
        Example: &quot;EXTRT values were sourced from the sponsor&#39;s drug dictionary version 2.0.&quot;
    &lt;/div&gt;

    &lt;h3&gt;8. Additional Guidance for Reviewers&lt;/h3&gt;
    &lt;div class=&quot;example&quot;&gt;
        Example: &quot;This dataset contains results from the EQ-5D questionnaire. Higher scores indicate better quality of life.&quot;
    &lt;/div&gt;

    &lt;h2&gt;Best Practices for Writing Effective Comments&lt;/h2&gt;
    &lt;div class=&quot;highlight&quot;&gt;
        &lt;p&gt;Follow these essential guidelines to create clear and useful comments:&lt;/p&gt;
    &lt;/div&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;strong&gt;Be Concise:&lt;/strong&gt; Avoid overly lengthy comments; stick to clear, precise descriptions that convey the necessary information without unnecessary words.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Use Plain Language:&lt;/strong&gt; Ensure your comments are understandable by both technical and non-technical audiences. Avoid jargon unless absolutely necessary.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Provide Context:&lt;/strong&gt; Always relate the comment directly to the variable or dataset it explains. Make connections clear and explicit.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Standardize Format:&lt;/strong&gt; Use consistent formatting throughout your documentation for ease of review and better readability.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Include Examples:&lt;/strong&gt; Where appropriate, provide concrete examples to illustrate complex concepts or rules.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Reference Sources:&lt;/strong&gt; When referring to external standards or documents, clearly cite the version and source.&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Common Pitfalls to Avoid&lt;/h2&gt;
    &lt;p&gt;
        While documenting in define.xml, avoid these common mistakes:
    &lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;Vague or ambiguous explanations&lt;/li&gt;
        &lt;li&gt;Inconsistent terminology across domains&lt;/li&gt;
        &lt;li&gt;Missing critical derivation steps&lt;/li&gt;
        &lt;li&gt;Overlooking special cases and exceptions&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Real-World Impact&lt;/h2&gt;
    &lt;p&gt;
        Well-documented comments can:
    &lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;Reduce regulatory review cycles&lt;/li&gt;
        &lt;li&gt;Minimize data interpretation questions&lt;/li&gt;
        &lt;li&gt;Improve study reproducibility&lt;/li&gt;
        &lt;li&gt;Facilitate knowledge transfer between team members&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Looking Ahead&lt;/h2&gt;
    &lt;p&gt;
        As clinical trials become more complex and regulatory requirements evolve, the importance of clear, 
        comprehensive documentation in define.xml will only increase. Mastering the art of writing effective 
        comments is no longer optional - it&#39;s a crucial skill for modern clinical data managers.
    &lt;/p&gt;

    &lt;div class=&quot;highlight&quot;&gt;
        &lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; Regular review and updates of your define.xml comments can save countless 
        hours during the submission process and prevent last-minute documentation crises.&lt;/p&gt;
    &lt;/div&gt;

    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;
        The Comments tab in define.xml is your opportunity to provide clarity, context, and completeness to your 
        clinical data documentation. By following these guidelines and best practices, you can create more robust, 
        reviewable, and valuable documentation that stands up to regulatory scrutiny and serves as a valuable 
        resource for your entire study team.
    &lt;/p&gt;

    &lt;div style=&quot;margin-top: 40px; border-top: 1px solid #ccc; padding-top: 20px;&quot;&gt;
        &lt;p&gt;&lt;em&gt;Share your thoughts and experiences with define.xml documentation in the comments below!&lt;/em&gt;&lt;/p&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;


</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/750762088325638314'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/750762088325638314'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2025/01/mastering-art-of-comments-in-definexml.html' title='Mastering the Art of Comments in Define.xml: Your Ultimate Guide to Clinical Data Documentation'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-5318313199840214809</id><published>2025-01-14T08:00:00.003-05:00</published><updated>2025-01-20T09:03:50.198-05:00</updated><title type='text'>Understanding SDTM EX and EC Domain Annotations</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 20px;
            background-color: #f9f9f9;
        }
        header {
            text-align: center;
            padding-bottom: 20px;
        }
        h1 {
            color: #2c3e50;
        }
        h2 {
            color: #34495e;
            border-bottom: 2px solid #ecf0f1;
            padding-bottom: 5px;
        }
        h3 {
            color: #16a085;
        }
        p {
            color: #2d3436;
        }
        ul {
            margin: 10px 0 10px 20px;
        }
        .example {
            background-color: #ecf0f1;
            padding: 15px;
            border-left: 4px solid #3498db;
            margin: 20px 0;
        }
        .conclusion {
            background-color: #dff9fb;
            padding: 15px;
            border-left: 4px solid #1abc9c;
            margin: 20px 0;
        }
        footer {
            text-align: center;
            margin-top: 40px;
            color: #95a5a6;
            font-size: 0.9em;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

    &lt;header&gt;
        &lt;h1&gt;&lt;/h1&gt;
        &lt;p&gt;By StudySAS Team | January 7, 2025&lt;/p&gt;
    &lt;/header&gt;

    &lt;section&gt;
        &lt;h2&gt;Introduction to SDTM Domains&lt;/h2&gt;
        &lt;p&gt;
            In clinical data management, the &lt;strong&gt;Study Data Tabulation Model (SDTM)&lt;/strong&gt; is a crucial standard for organizing and formatting data to streamline regulatory submissions. Among its various domains, the &lt;strong&gt;EX (Exposure)&lt;/strong&gt; and &lt;strong&gt;EC (Exposure Events)&lt;/strong&gt; domains play significant roles in documenting participant exposures and related events during a study.
        &lt;/p&gt;
        &lt;p&gt;
            This blog post delves into when and how to annotate these domains, providing detailed examples and best practices based on the &lt;em&gt;SDTM Implementation Guide (IG) Version 3.3&lt;/em&gt;.
        &lt;/p&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;Understanding the EX Domain&lt;/h2&gt;
        &lt;p&gt;
            The &lt;strong&gt;EX (Exposure)&lt;/strong&gt; domain is essential for capturing detailed information about the administration of investigational products, concomitant medications, or other exposures participants receive during a clinical study.
        &lt;/p&gt;
        &lt;h3&gt;When to Annotate the EX Domain&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Required:&lt;/strong&gt; If your study involves any form of product or treatment administration.&lt;/li&gt;
            &lt;li&gt;Commonly used in most clinical trials to document dosage, route, frequency, and duration of treatments.&lt;/li&gt;
            &lt;li&gt;Includes data elements such as dosage, route of administration, frequency, duration, and start/end dates of treatment.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;h3&gt;Examples When EX Domain Annotations are Required&lt;/h3&gt;
        &lt;div class=&quot;example&quot;&gt;
            &lt;h4&gt;1. Clinical Trials Involving Investigational Products&lt;/h4&gt;
            &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A Phase III clinical trial testing the efficacy and safety of a new oncology drug.&lt;/p&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;strong&gt;Data Elements:&lt;/strong&gt; EXDOSE, EXROUTE, EXSTART, EXEND&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;

        &lt;div class=&quot;example&quot;&gt;
            &lt;h4&gt;2. Studies Involving Concomitant Medications&lt;/h4&gt;
            &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A clinical trial assessing a new antihypertensive drug where participants continue existing blood pressure medications.&lt;/p&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;strong&gt;Data Elements:&lt;/strong&gt; EXTRT, EXDOSE, EXSTART, EXEND&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;

        &lt;!-- Additional examples can be added similarly --&gt;

        &lt;h3&gt;Key Considerations for EX Domain Annotation&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Comprehensive Data Capture:&lt;/strong&gt; Document all relevant aspects of exposure.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Study Protocol Alignment:&lt;/strong&gt; Ensure annotations align with study protocols.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Regulatory Compliance:&lt;/strong&gt; Adhere to SDTM IG 3.3 and regulatory guidelines.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Data Quality and Integrity:&lt;/strong&gt; Maintain consistency and accuracy in data mapping.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Collaboration:&lt;/strong&gt; Work with clinical operations and data management teams.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;Understanding the EC Domain&lt;/h2&gt;
        &lt;p&gt;
            The &lt;strong&gt;EC (Exposure Events)&lt;/strong&gt; domain is designed to capture specific events or deviations related to participant exposures. These can include missed doses, dose modifications, discontinuations, or any deviations from the prescribed exposure protocol.
        &lt;/p&gt;

        &lt;h3&gt;When is EC Domain Annotation Required?&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Mandatory:&lt;/strong&gt;
                &lt;ul&gt;
                    &lt;li&gt;Deviation from exposure protocol, such as missed doses or dose modifications.&lt;/li&gt;
                    &lt;li&gt;Dose adjustments based on participant tolerance, efficacy, or safety concerns.&lt;/li&gt;
                    &lt;li&gt;Temporary interruptions due to adverse reactions or concurrent medical conditions.&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Study Design:&lt;/strong&gt;
                &lt;ul&gt;
                    &lt;li&gt;Studies with detailed monitoring of exposure compliance.&lt;/li&gt;
                    &lt;li&gt;Trials involving complex exposure regimens like combination therapies.&lt;/li&gt;
                    &lt;li&gt;Studies where exposure deviations significantly impact participant safety or study integrity.&lt;/li&gt;
                &lt;/ul&gt;
            &lt;/li&gt;
        &lt;/ul&gt;

        &lt;h3&gt;When is EC Domain Annotation Beneficial?&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Enhanced Data Transparency:&lt;/strong&gt; Provides a complete picture of participant exposure and deviations.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Improved Regulatory Compliance:&lt;/strong&gt; Facilitates smoother regulatory audits and reviews.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Better Risk Management:&lt;/strong&gt; Helps in early detection of safety signals related to exposure deviations.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Data Integration:&lt;/strong&gt; Enhances interoperability by linking with other SDTM domains.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;h3&gt;Examples and Scenarios for EC Domain Annotation&lt;/h3&gt;
        &lt;div class=&quot;example&quot;&gt;
            &lt;h4&gt;1. Clinical Trials with Dose Escalation Protocols&lt;/h4&gt;
            &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A Phase I oncology trial determining the maximum tolerated dose (MTD) of a new chemotherapy agent.&lt;/p&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;strong&gt;Data Elements:&lt;/strong&gt; ECMOD, ECRPT&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;

        &lt;div class=&quot;example&quot;&gt;
            &lt;h4&gt;2. Studies Monitoring Treatment Adherence&lt;/h4&gt;
            &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A study assessing the efficacy of a daily oral antihypertensive medication.&lt;/p&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;strong&gt;Data Elements:&lt;/strong&gt; ECSEQ, ECLINKID&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;

        &lt;!-- Additional examples can be added similarly --&gt;

        &lt;h3&gt;Best Practices for EC Domain Annotation&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Comprehensive Mapping:&lt;/strong&gt; Identify and map all potential exposure events from CRFs to EC domain.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Clear Documentation:&lt;/strong&gt; Document the rationale for each exposure event annotation.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Collaboration:&lt;/strong&gt; Work with cross-functional teams to ensure accurate annotation.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Standardized Coding:&lt;/strong&gt; Use controlled terminologies like MedDRA for reasons.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Utilize Automation:&lt;/strong&gt; Employ tools for automated mapping and validation to reduce errors.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;When to Use EC Domain Without EX Domain&lt;/h2&gt;
        &lt;p&gt;
            While the **EC (Exposure Events)** domain is typically used in conjunction with the **EX (Exposure)** domain, there are specific scenarios where EC annotations might be included without corresponding EX annotations on the **annotated Case Report Form (aCRF)**.
        &lt;/p&gt;

        &lt;h3&gt;Scenarios for EC Domain Without EX Domain&lt;/h3&gt;
        &lt;div class=&quot;example&quot;&gt;
            &lt;h4&gt;1. Studies Utilizing External or Predefined Exposure Data&lt;/h4&gt;
            &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A retrospective observational study assessing exposure to environmental pollutants where exposure data is sourced from external databases.&lt;/p&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;strong&gt;Why EC Only:&lt;/strong&gt; Exposures are predefined and documented externally; the study focuses on tracking related events.&lt;/li&gt;
                &lt;li&gt;&lt;strong&gt;Data Elements:&lt;/strong&gt; ECSEQ, ECSTDY, ECRPT, ECMOD&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;

        &lt;div class=&quot;example&quot;&gt;
            &lt;h4&gt;2. Protocol Deviations Without Specific Exposure Data&lt;/h4&gt;
            &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A clinical trial where site closures or supply interruptions affect treatment administration but do not alter exposure details.&lt;/p&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;strong&gt;Why EC Only:&lt;/strong&gt; Focus on documenting protocol deviations impacting exposure without changing the exposure data.&lt;/li&gt;
                &lt;li&gt;&lt;strong&gt;Data Elements:&lt;/strong&gt; ECSEQ, ECSTDY, ECRPT, ECMOD&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;

        &lt;div class=&quot;example&quot;&gt;
            &lt;h4&gt;3. High-Level Exposure Event Tracking in Specific Study Designs&lt;/h4&gt;
            &lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; A public health study monitoring major exposure-related incidents like widespread environmental changes.&lt;/p&gt;
            &lt;ul&gt;
                &lt;li&gt;&lt;strong&gt;Why EC Only:&lt;/strong&gt; Records high-level exposure events without individual exposure metrics.&lt;/li&gt;
                &lt;li&gt;&lt;strong&gt;Data Elements:&lt;/strong&gt; ECSEQ, ECSTDY, ECRPT, ECMOD&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/div&gt;

        &lt;!-- Additional scenarios can be added similarly --&gt;

        &lt;h3&gt;Key Considerations and Best Practices&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Regulatory Compliance:&lt;/strong&gt; Ensure alignment with SDTM IG 3.3 and consult regulatory authorities if deviating from standard practices.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Clear Documentation:&lt;/strong&gt; Justify the exclusion of EX annotations and provide detailed metadata.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Data Integrity:&lt;/strong&gt; Maintain consistent and meaningful EC records even without EX annotations.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Collaboration:&lt;/strong&gt; Engage with all relevant teams to ensure a shared understanding and accurate implementation.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Review and Validation:&lt;/strong&gt; Implement robust validation processes to ensure accuracy and compliance.&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/section&gt;

    &lt;section&gt;
        &lt;h2&gt;Conclusion&lt;/h2&gt;
        &lt;div class=&quot;conclusion&quot;&gt;
            &lt;p&gt;
                Annotating the &lt;strong&gt;EX (Exposure)&lt;/strong&gt; and &lt;strong&gt;EC (Exposure Events)&lt;/strong&gt; domains is pivotal for comprehensive and compliant clinical data management. While the EX domain is generally essential for documenting participant exposures, the EC domain provides additional depth by capturing related events and deviations. Understanding when and how to use these domains, especially the specific cases where EC can be used without EX, ensures data integrity, regulatory compliance, and facilitates robust data analysis.
            &lt;/p&gt;
            &lt;p&gt;
                For more detailed guidelines, always refer to the &lt;em&gt;CDISC SDTM Implementation Guide, Version 3.3&lt;/em&gt; and consult with regulatory bodies as needed.
            &lt;/p&gt;
        &lt;/div&gt;
    &lt;/section&gt;

    &lt;footer&gt;
        &lt;p&gt;&amp;copy; 2025 StudySAS. All rights reserved.&lt;/p&gt;
    &lt;/footer&gt;

&lt;/body&gt;
&lt;/html&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/5318313199840214809'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/5318313199840214809'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2025/01/understanding-sdtm-ex-and-ec-domain.html' title='Understanding SDTM EX and EC Domain Annotations'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-5033041057240281212</id><published>2025-01-10T14:29:00.003-05:00</published><updated>2025-01-10T14:40:09.192-05:00</updated><title type='text'>Protocol Version Mapping in SDTM Disposition Events: A Comprehensive Guide</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;style&gt;
        body {
            font-family: system-ui, -apple-system, sans-serif;
            line-height: 1.6;
            max-width: 1300px;
            margin: 0 auto;
            padding: 20px;
            color: #333;
        }
        h1, h2, h3 {
            color: #2c5282;
            margin-top: 1.5em;
        }
        .alert {
            background-color: #f8f9fa;
            border-left: 4px solid #2c5282;
            padding: 1em;
            margin: 1em 0;
        }
        code {
            background-color: #f5f5f5;
            padding: 0.2em 0.4em;
            border-radius: 3px;
            font-family: monospace;
        }
        .table-container {
            overflow-x: auto;
            margin: 1.5em 0;
        }
        table {
            border-collapse: collapse;
            width: 100%;
        }
        th, td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }
        th {
            background-color: #f8f9fa;
        }
        .example {
            background-color: #f8f9fa;
            padding: 1em;
            margin: 1em 0;
            border-radius: 4px;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;&lt;/h1&gt;

    &lt;div class=&quot;alert&quot;&gt;
        &lt;strong&gt;Key Concept:&lt;/strong&gt; The decision to map protocol version information in SDTM Disposition (DS) domain requires careful analysis of its relationship to disposition events and understanding of data management requirements.
    &lt;/div&gt;

    &lt;h2&gt;Understanding Protocol Version&#39;s Role in Disposition Events&lt;/h2&gt;
    &lt;p&gt;Protocol versions can significantly impact disposition events in clinical trials. Their relationship to these events determines the appropriate mapping strategy within the SDTM structure. This relationship can be categorized into two main types:&lt;/p&gt;

    &lt;div class=&quot;example&quot;&gt;
        &lt;h3&gt;Direct Impact Relationship&lt;/h3&gt;
        &lt;p&gt;When protocol version changes directly cause or influence disposition events, such as:&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;Subject withdrawal due to protocol amendment modifications&lt;/li&gt;
            &lt;li&gt;Study discontinuation resulting from significant protocol changes&lt;/li&gt;
            &lt;li&gt;Protocol-mandated subject transfers between treatment arms&lt;/li&gt;
        &lt;/ul&gt;

        &lt;h3&gt;Contextual Relationship&lt;/h3&gt;
        &lt;p&gt;When protocol version provides important context but doesn&#39;t directly cause the disposition event:&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;Standard discontinuations occurring under different protocol versions&lt;/li&gt;
            &lt;li&gt;Administrative changes documented in protocol updates&lt;/li&gt;
            &lt;li&gt;Background information for data analysis&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;

    &lt;h2&gt;Decision Framework for Protocol Version Mapping&lt;/h2&gt;
    &lt;p&gt;To determine the appropriate mapping strategy, follow this structured evaluation process:&lt;/p&gt;

    &lt;h3&gt;1. Impact Analysis&lt;/h3&gt;
    &lt;p&gt;Evaluate the protocol version&#39;s influence on disposition events by examining:&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;Direct causality between protocol changes and subject disposition&lt;/li&gt;
        &lt;li&gt;Regulatory requirements for tracking protocol version information&lt;/li&gt;
        &lt;li&gt;Statistical analysis requirements for protocol version stratification&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h3&gt;2. Data Structure Assessment&lt;/h3&gt;
    &lt;p&gt;Consider the following aspects of your data structure:&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;Existing variable relationships in the DS domain&lt;/li&gt;
        &lt;li&gt;Need for protocol version traceability&lt;/li&gt;
        &lt;li&gt;Impact on data analysis and reporting requirements&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Protocol Version Mapping Methods: Decision Guide&lt;/h2&gt;

&lt;div class=&quot;alert&quot;&gt;
    &lt;strong&gt;Key Principle:&lt;/strong&gt; The choice of mapping method should be driven by the relationship between the protocol version and the disposition event, regulatory requirements, and analysis needs. Each method serves a specific purpose and has distinct advantages.
&lt;/div&gt;

&lt;h3&gt;Method 1: DSREFID Mapping&lt;/h3&gt;
&lt;p&gt;Use DSREFID mapping when protocol version information is fundamental to understanding or explaining the disposition event. This method is most appropriate in the following scenarios:&lt;/p&gt;

&lt;div class=&quot;example&quot;&gt;
    &lt;strong&gt;When to Use DSREFID:&lt;/strong&gt;
    &lt;ul&gt;
        &lt;li&gt;The disposition event occurs as a direct result of a protocol amendment or version change. For example, when a subject withdraws because new procedures were introduced in a protocol amendment.&lt;/li&gt;
        &lt;li&gt;Protocol version changes trigger mandatory subject discontinuation or transfer between treatment arms.&lt;/li&gt;
        &lt;li&gt;Regulatory requirements specifically mandate tracking the relationship between protocol versions and disposition events.&lt;/li&gt;
        &lt;li&gt;The protocol version is essential for understanding the context of the disposition decision and will be needed for primary analysis.&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;

&lt;h3&gt;Method 2: Supplemental Qualifiers (SUPPDS)&lt;/h3&gt;
&lt;p&gt;Use supplemental qualifiers when protocol version information provides important context but isn&#39;t directly causal to the disposition event. This approach is best suited for:&lt;/p&gt;

&lt;div class=&quot;example&quot;&gt;
    &lt;strong&gt;When to Use SUPPDS:&lt;/strong&gt;
    &lt;ul&gt;
        &lt;li&gt;Protocol version information needs to be preserved for traceability but isn&#39;t directly related to the disposition decision.&lt;/li&gt;
        &lt;li&gt;The information might be needed for secondary analyses or regulatory documentation.&lt;/li&gt;
        &lt;li&gt;You need to maintain protocol version history without implying direct causality with disposition events.&lt;/li&gt;
        &lt;li&gt;The protocol version is part of standard documentation requirements but doesn&#39;t affect the interpretation of the disposition event.&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;

&lt;h3&gt;Method 3: Custom Variables&lt;/h3&gt;
&lt;p&gt;Consider creating custom variables (with sponsor and regulatory approval) in these situations:&lt;/p&gt;

&lt;div class=&quot;example&quot;&gt;
    &lt;strong&gt;When to Use Custom Variables:&lt;/strong&gt;
    &lt;ul&gt;
        &lt;li&gt;Your study has unique protocol version tracking requirements that don&#39;t fit well in standard variables.&lt;/li&gt;
        &lt;li&gt;You need to capture multiple aspects of protocol versioning (e.g., both amendment number and version date).&lt;/li&gt;
        &lt;li&gt;Sponsor-specific requirements necessitate specialized protocol version tracking.&lt;/li&gt;
        &lt;li&gt;The relationship between protocol versions and disposition events needs to be analyzed in ways not supported by standard variables.&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;

&lt;h3&gt;Method 4: Comments or DSTERM&lt;/h3&gt;
&lt;p&gt;Include protocol version information in comments or DSTERM when:&lt;/p&gt;

&lt;div class=&quot;example&quot;&gt;
    &lt;strong&gt;When to Use Comments/DSTERM:&lt;/strong&gt;
    &lt;ul&gt;
        &lt;li&gt;The protocol version provides helpful background information but isn&#39;t required for analysis.&lt;/li&gt;
        &lt;li&gt;You need to provide additional context about protocol version impacts without formal tracking.&lt;/li&gt;
        &lt;li&gt;The information is purely descriptive and won&#39;t be used in analyses.&lt;/li&gt;
        &lt;li&gt;You need to capture protocol version details in a narrative format.&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;

&lt;h3&gt;Decision Support Matrix&lt;/h3&gt;
&lt;div class=&quot;table-container&quot;&gt;
    &lt;table&gt;
        &lt;thead&gt;
            &lt;tr&gt;
                &lt;th&gt;Characteristic&lt;/th&gt;
                &lt;th&gt;DSREFID&lt;/th&gt;
                &lt;th&gt;SUPPDS&lt;/th&gt;
                &lt;th&gt;Custom Variable&lt;/th&gt;
                &lt;th&gt;Comments/DSTERM&lt;/th&gt;
            &lt;/tr&gt;
        &lt;/thead&gt;
        &lt;tbody&gt;
            &lt;tr&gt;
                &lt;td&gt;Direct Causality&lt;/td&gt;
                &lt;td&gt;Required&lt;/td&gt;
                &lt;td&gt;Optional&lt;/td&gt;
                &lt;td&gt;Variable&lt;/td&gt;
                &lt;td&gt;No&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Analysis Impact&lt;/td&gt;
                &lt;td&gt;Primary&lt;/td&gt;
                &lt;td&gt;Secondary&lt;/td&gt;
                &lt;td&gt;Study-specific&lt;/td&gt;
                &lt;td&gt;None&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Traceability&lt;/td&gt;
                &lt;td&gt;High&lt;/td&gt;
                &lt;td&gt;Medium&lt;/td&gt;
                &lt;td&gt;High&lt;/td&gt;
                &lt;td&gt;Low&lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td&gt;Implementation Complexity&lt;/td&gt;
                &lt;td&gt;Medium&lt;/td&gt;
                &lt;td&gt;Low&lt;/td&gt;
                &lt;td&gt;High&lt;/td&gt;
                &lt;td&gt;Low&lt;/td&gt;
            &lt;/tr&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
&lt;/div&gt;

&lt;h2&gt;Mapping Implementation Strategies&lt;/h2&gt;

    &lt;h3&gt;Strategy 1: DSREFID Mapping&lt;/h3&gt;
    &lt;div class=&quot;table-container&quot;&gt;
        &lt;table&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;USUBJID&lt;/th&gt;
                    &lt;th&gt;DSSEQ&lt;/th&gt;
                    &lt;th&gt;DSTERM&lt;/th&gt;
                    &lt;th&gt;DSDECOD&lt;/th&gt;
                    &lt;th&gt;DSREFID&lt;/th&gt;
                    &lt;th&gt;DSSTDTC&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                &lt;tr&gt;
                    &lt;td&gt;123-45678&lt;/td&gt;
                    &lt;td&gt;1&lt;/td&gt;
                    &lt;td&gt;Protocol Amendment Withdrawal&lt;/td&gt;
                    &lt;td&gt;WITHDRAWAL&lt;/td&gt;
                    &lt;td&gt;PROT-V2.0-AMD3&lt;/td&gt;
                    &lt;td&gt;2024-01-15&lt;/td&gt;
                &lt;/tr&gt;
            &lt;/tbody&gt;
        &lt;/table&gt;
    &lt;/div&gt;

    &lt;h3&gt;Strategy 2: Supplemental Qualifiers&lt;/h3&gt;
    &lt;div class=&quot;table-container&quot;&gt;
        &lt;table&gt;
            &lt;thead&gt;
                &lt;tr&gt;
                    &lt;th&gt;STUDYID&lt;/th&gt;
                    &lt;th&gt;RDOMAIN&lt;/th&gt;
                    &lt;th&gt;USUBJID&lt;/th&gt;
                    &lt;th&gt;IDVAR&lt;/th&gt;
                    &lt;th&gt;IDVARVAL&lt;/th&gt;
                    &lt;th&gt;QNAM&lt;/th&gt;
                    &lt;th&gt;QVAL&lt;/th&gt;
                &lt;/tr&gt;
            &lt;/thead&gt;
            &lt;tbody&gt;
                &lt;tr&gt;
                    &lt;td&gt;STUDY001&lt;/td&gt;
                    &lt;td&gt;DS&lt;/td&gt;
                    &lt;td&gt;123-45678&lt;/td&gt;
                    &lt;td&gt;DSSEQ&lt;/td&gt;
                    &lt;td&gt;1&lt;/td&gt;
                    &lt;td&gt;PROTVER&lt;/td&gt;
                    &lt;td&gt;2.0&lt;/td&gt;
                &lt;/tr&gt;
            &lt;/tbody&gt;
        &lt;/table&gt;
    &lt;/div&gt;

    &lt;h2&gt;Best Practices and Recommendations&lt;/h2&gt;
    &lt;div class=&quot;alert&quot;&gt;
        &lt;h3&gt;Documentation Requirements&lt;/h3&gt;
        &lt;ul&gt;
            &lt;li&gt;Clearly document the mapping rationale in the Study Data Reviewer&#39;s Guide&lt;/li&gt;
            &lt;li&gt;Maintain consistent protocol version formatting across all domains&lt;/li&gt;
            &lt;li&gt;Include protocol version mapping decisions in data management plans&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;

    &lt;h2&gt;Common Pitfalls to Avoid&lt;/h2&gt;
    &lt;ul&gt;
        &lt;li&gt;Inconsistent protocol version formatting across different domains&lt;/li&gt;
        &lt;li&gt;Overloading DSREFID with non-essential protocol information&lt;/li&gt;
        &lt;li&gt;Failing to document the mapping rationale adequately&lt;/li&gt;
        &lt;li&gt;Inconsistent handling of protocol versions across different studies&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;Successful protocol version mapping in SDTM disposition events requires careful consideration of the relationship between protocol versions and disposition events, clear documentation, and consistent implementation. By following these guidelines and best practices, organizations can ensure accurate and compliant data representation while maintaining traceability and supporting effective analysis.&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/5033041057240281212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/5033041057240281212'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2025/01/mapping-protocol-version-to-disposition.html' title='Protocol Version Mapping in SDTM Disposition Events: A Comprehensive Guide'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-2176083623772535595</id><published>2025-01-10T12:56:00.004-05:00</published><updated>2025-01-10T13:02:16.134-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="EPOCH Assignment for Pre-Consent Data"/><title type='text'>Understanding EPOCH Assignment in Clinical Trials: The Pre-Consent Data Challenge</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            color: #333;
        }
        h1 {
            color: #2c3e50;
            border-bottom: 2px solid #eee;
            padding-bottom: 10px;
        }
        h2 {
            color: #34495e;
            margin-top: 30px;
        }
        .highlight {
            background-color: #f8f9fa;
            border-left: 4px solid #007bff;
            padding: 15px;
            margin: 20px 0;
        }
        .note {
            background-color: #fff3cd;
            border: 1px solid #ffeeba;
            padding: 15px;
            border-radius: 4px;
            margin: 20px 0;
        }
        img {
            max-width: 100%;
            height: auto;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;&lt;/h1&gt;
    
    &lt;p&gt;In the world of clinical trials, data management and standardization play crucial roles in ensuring the quality and integrity of research outcomes. One particularly nuanced aspect of this process is the proper assignment of EPOCH values in SDTM (Study Data Tabulation Model) datasets, especially when dealing with pre-consent data.&lt;/p&gt;

    &lt;h2&gt;What is an EPOCH?&lt;/h2&gt;
    &lt;p&gt;An EPOCH in clinical trials represents a distinct period within the study&#39;s planned design. It helps organize and contextualize various events, interventions, and findings that occur during the study. Common EPOCHs include SCREENING, TREATMENT, FOLLOW-UP, and others as defined by the study protocol.&lt;/p&gt;
    
    &lt;div class=&quot;highlight&quot;&gt;
        &lt;p&gt;&lt;strong&gt;Essential EPOCH Characteristics:&lt;/strong&gt;&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;It is a standardized way to identify different phases of a study&lt;/li&gt;
            &lt;li&gt;Each EPOCH represents a planned element of the study design&lt;/li&gt;
            &lt;li&gt;EPOCHs help establish temporal relationships between different study events&lt;/li&gt;
            &lt;li&gt;They are crucial for data analysis and interpretation of study results&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;

    &lt;div class=&quot;highlight&quot;&gt;
        &lt;p&gt;According to SDTM Implementation Guide 3.3 (Section 4.1.3.1), EPOCH is fundamentally a study-design construct. This means it only applies to events that occur after a subject has formally entered the study through the informed consent process.&lt;/p&gt;
    &lt;/div&gt;

    &lt;h2&gt;The Pre-Consent Data Challenge&lt;/h2&gt;
    &lt;p&gt;Clinical researchers often encounter situations where they need to include data that was collected before a subject provided informed consent. This might include:&lt;/p&gt;
    
    &lt;ul&gt;
        &lt;li&gt;Historical medical records&lt;/li&gt;
        &lt;li&gt;Previous laboratory results&lt;/li&gt;
        &lt;li&gt;Prior medications&lt;/li&gt;
        &lt;li&gt;Earlier adverse events&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Why Can&#39;t We Assign SCREENING EPOCH to Pre-Consent Data?&lt;/h2&gt;
    &lt;p&gt;It might seem intuitive to assign pre-consent data to the SCREENING EPOCH, as it&#39;s typically the earliest study phase. However, this would be incorrect for several important reasons:&lt;/p&gt;

    &lt;div class=&quot;note&quot;&gt;
        &lt;p&gt;&lt;strong&gt;Key Points:&lt;/strong&gt;&lt;/p&gt;
        &lt;ol&gt;
            &lt;li&gt;The screening period is a protocol-defined phase that occurs only after informed consent&lt;/li&gt;
            &lt;li&gt;Screening activities are specifically planned and conducted according to the study protocol&lt;/li&gt;
            &lt;li&gt;Pre-consent data collection wasn&#39;t performed under the study&#39;s procedures and requirements&lt;/li&gt;
        &lt;/ol&gt;
    &lt;/div&gt;

    &lt;h2&gt;The Correct Approach: Using Null EPOCH Values&lt;/h2&gt;
    &lt;p&gt;For any data collected before informed consent, the EPOCH variable should be set to null. This approach:&lt;/p&gt;
    
    &lt;ul&gt;
        &lt;li&gt;Accurately represents the timing of events relative to study participation&lt;/li&gt;
        &lt;li&gt;Maintains data integrity and transparency&lt;/li&gt;
        &lt;li&gt;Complies with SDTM standards and guidelines&lt;/li&gt;
        &lt;li&gt;Facilitates proper analysis and interpretation of study data&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Impact on Data Analysis&lt;/h2&gt;
    &lt;p&gt;Understanding the relationship between EPOCH assignment and informed consent dates is crucial for:&lt;/p&gt;
    
    &lt;ul&gt;
        &lt;li&gt;Accurate timeline construction&lt;/li&gt;
        &lt;li&gt;Proper assessment of inclusion/exclusion criteria&lt;/li&gt;
        &lt;li&gt;Correct baseline determinations&lt;/li&gt;
        &lt;li&gt;Valid safety and efficacy analyses&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Best Practices for Implementation&lt;/h2&gt;
    &lt;p&gt;When implementing EPOCH assignments in your clinical trial data:&lt;/p&gt;

    &lt;ol&gt;
        &lt;li&gt;Always document the informed consent date accurately&lt;/li&gt;
        &lt;li&gt;Establish clear procedures for handling pre-consent data&lt;/li&gt;
        &lt;li&gt;Include proper date variables to establish the timing of events&lt;/li&gt;
        &lt;li&gt;Implement quality control checks to ensure correct EPOCH assignments&lt;/li&gt;
        &lt;li&gt;Document your decisions and rationale in the Study Data Reviewer&#39;s Guide&lt;/li&gt;
    &lt;/ol&gt;

    &lt;div class=&quot;note&quot;&gt;
        &lt;p&gt;&lt;strong&gt;Special Considerations for EPOCH Assignment:&lt;/strong&gt;&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Protocol Amendments:&lt;/strong&gt; Consider how protocol amendments might affect EPOCH definitions and assignments&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Re-screening:&lt;/strong&gt; Handle cases where subjects may need to be re-screened with appropriate EPOCH assignments&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Multiple Informed Consents:&lt;/strong&gt; Account for situations where subjects might sign multiple consent forms for different study aspects&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Data Integration:&lt;/strong&gt; Ensure consistent EPOCH assignment across all study domains&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;

    &lt;h2&gt;Regulatory Compliance and Documentation&lt;/h2&gt;
    &lt;p&gt;Proper EPOCH assignment is crucial for regulatory compliance. When preparing submissions:&lt;/p&gt;
    
    &lt;div class=&quot;highlight&quot;&gt;
        &lt;ul&gt;
            &lt;li&gt;Ensure your approach is clearly documented in the Study Data Reviewer&#39;s Guide (SDRG)&lt;/li&gt;
            &lt;li&gt;Include explanations for any special handling of EPOCH assignments&lt;/li&gt;
            &lt;li&gt;Document any deviations from standard EPOCH assignment practices&lt;/li&gt;
            &lt;li&gt;Maintain traceability between source data and SDTM datasets&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/div&gt;

    &lt;h2&gt;Common Challenges and Solutions&lt;/h2&gt;
    &lt;div class=&quot;note&quot;&gt;
        &lt;p&gt;&lt;strong&gt;Challenge 1: Historical Data Collection&lt;/strong&gt;&lt;br&gt;
        Solution: Clearly identify pre-study data and consistently apply null EPOCH values&lt;/p&gt;
        
        &lt;p&gt;&lt;strong&gt;Challenge 2: Protocol Amendments&lt;/strong&gt;&lt;br&gt;
        Solution: Document how EPOCH assignments are handled when study design changes&lt;/p&gt;
        
        &lt;p&gt;&lt;strong&gt;Challenge 3: Multiple Sub-studies&lt;/strong&gt;&lt;br&gt;
        Solution: Develop clear rules for EPOCH assignment across different study components&lt;/p&gt;
        
        &lt;p&gt;&lt;strong&gt;Challenge 4: Data Integration&lt;/strong&gt;&lt;br&gt;
        Solution: Establish consistent EPOCH assignment rules across all study domains&lt;/p&gt;
    &lt;/div&gt;

    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;Proper EPOCH assignment is more than just a technical requirement—it&#39;s fundamental to maintaining the scientific integrity of clinical trial data. By correctly handling pre-consent data with null EPOCH values, we ensure our SDTM datasets accurately reflect the study design and subject participation timeline.&lt;/p&gt;

    &lt;div class=&quot;highlight&quot;&gt;
        &lt;p&gt;&lt;strong&gt;Remember:&lt;/strong&gt; The integrity of clinical trial data depends on accurate representation of when events occurred relative to study participation. Using null EPOCH values for pre-consent data is not just compliant with standards—it&#39;s essential for proper data interpretation and analysis.&lt;/p&gt;
    &lt;/div&gt;

    &lt;p&gt;&lt;em&gt;Last updated: January 2025&lt;/em&gt;&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/2176083623772535595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/2176083623772535595'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2025/01/understanding-epoch-assignment-in.html' title='Understanding EPOCH Assignment in Clinical Trials: The Pre-Consent Data Challenge'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-7237954987737007549</id><published>2025-01-09T15:06:00.007-05:00</published><updated>2025-01-09T15:12:06.176-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="sas LOG width of comments is not in between 1 and 200 characters"/><category scheme="http://www.blogger.com/atom/ns#" term="SAS ODS LISTING CLOSE"/><title type='text'>The Critical Role of ODS LISTING Close Statements in SAS: Avoiding Comment Width Errors</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta name=&quot;description&quot; content=&quot;Learn how to use ODS LISTING CLOSE in SAS to avoid common errors like &#39;comment width not between 1 and 200 characters.&#39; Includes examples and troubleshooting tips.&quot;&gt;
    &lt;title&gt;&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            max-width: 1400px;
            margin: 0 auto;
            padding: 20px;
            color: #333;
        }
        h1, h2 {
            color: #2c3e50;
            border-bottom: 2px solid #eee;
            padding-bottom: 10px;
        }
        .code-block {
            background-color: #f8f9fa;
            padding: 15px;
            border-radius: 5px;
            font-family: monospace;
            white-space: pre-wrap;
            margin: 20px 0;
        }
        .note {
            background-color: #fff3cd;
            border-left: 4px solid #ffc107;
            padding: 15px;
            margin: 20px 0;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;The Critical Role of ODS LISTING Close Statements in SAS: Avoiding Comment Width Errors&lt;/h1&gt;
    
    &lt;p&gt;One of the common challenges SAS programmers face is encountering the error message: &quot;ERROR: Comment width is not between 1 and 200 characters.&quot; This error, while seemingly straightforward, can be particularly frustrating when it appears unexpectedly in your SAS log. In this article, we&#39;ll dive deep into understanding this error and how proper management of ODS LISTING statements can help you avoid it.&lt;/p&gt;

    &lt;h2&gt;Introduction to ODS&lt;/h2&gt;
    &lt;p&gt;The Output Delivery System (ODS) in SAS enables users to control the appearance and destination of output generated by SAS procedures. ODS allows output to be directed to various destinations like HTML, PDF, RTF, and the default Listing destination. Proper management of these destinations is critical to ensuring clean output and avoiding errors.&lt;/p&gt;

    &lt;h2&gt;Understanding the Error&lt;/h2&gt;
    &lt;p&gt;The error message regarding comment width typically appears when SAS encounters issues with the Output Delivery System (ODS) LISTING destination. While the message suggests a problem with comment width, the root cause often lies in how ODS LISTING is handled in your SAS program.&lt;/p&gt;

    &lt;h2&gt;Why ODS LISTING Matters&lt;/h2&gt;
    &lt;p&gt;The LISTING destination in SAS is the default output destination that creates the traditional SAS output. When not properly closed, it can lead to various issues, including the misleading &quot;comment width&quot; error.&lt;/p&gt;

    &lt;div class=&quot;note&quot;&gt;
        &lt;strong&gt;Important:&lt;/strong&gt; The ODS LISTING destination remains open by default unless explicitly closed. Multiple open instances can cause unexpected behavior and errors.
    &lt;/div&gt;

    &lt;h2&gt;Best Practices for ODS LISTING Management&lt;/h2&gt;
    &lt;p&gt;Here&#39;s how to properly manage ODS LISTING to avoid errors:&lt;/p&gt;

    &lt;div class=&quot;code-block&quot;&gt;
/* Close all ODS destinations at the start */
ods _all_ close;

/* Open specific destinations as needed */
ods listing;

/* Your SAS code here */
proc print data=sashelp.class;
run;

/* Close the listing destination when finished */
ods listing close;
    &lt;/div&gt;

    &lt;h2&gt;Common Scenarios That Trigger the Error&lt;/h2&gt;
    &lt;ul&gt;
        &lt;li&gt;Running multiple procedures without closing ODS LISTING between them&lt;/li&gt;
        &lt;li&gt;Nested ODS LISTING statements without proper closure&lt;/li&gt;
        &lt;li&gt;Batch processing multiple SAS programs where ODS destinations aren&#39;t properly managed&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;Preventive Measures&lt;/h2&gt;
    &lt;p&gt;To avoid encountering the comment width error, implement these practices:&lt;/p&gt;

    &lt;div class=&quot;code-block&quot;&gt;
/* Start with a clean slate */
ods _all_ close;

/* Create a macro to manage ODS destinations */
%macro manage_ods;
    ods listing close;
    ods listing;
%mend;

/* Use the macro before critical procedures */
%manage_ods;
proc print data=sashelp.class;
run;

/* Always close at the end */
ods listing close;
    &lt;/div&gt;

    &lt;h2&gt;Troubleshooting Tips&lt;/h2&gt;
    &lt;p&gt;If you encounter the comment width error despite taking precautions:&lt;/p&gt;
    &lt;ul&gt;
        &lt;li&gt;Check your SAS log for any unclosed ODS destinations&lt;/li&gt;
        &lt;li&gt;Verify that your ODS LISTING statements are properly paired (open/close)&lt;/li&gt;
        &lt;li&gt;Consider adding ODS LISTING management statements at key points in your code&lt;/li&gt;
        &lt;li&gt;Use the ODS SHOW statement to view currently open destinations&lt;/li&gt;
    &lt;/ul&gt;

    &lt;div class=&quot;code-block&quot;&gt;
/* Check open ODS destinations */
ods show;
    &lt;/div&gt;

    &lt;h2&gt;Real-World Example&lt;/h2&gt;
    &lt;p&gt;Consider this scenario: You are running multiple SAS procedures in a batch process and encounter the &quot;comment width&quot; error. By including &lt;code&gt;ods _all_ close;&lt;/code&gt; at the start of your program and ensuring proper closure of the LISTING destination with &lt;code&gt;ods listing close;&lt;/code&gt;, the error is resolved. This simple adjustment streamlines the output management and eliminates the issue.&lt;/p&gt;

    &lt;h2&gt;Conclusion&lt;/h2&gt;
    &lt;p&gt;While the &quot;comment width&quot; error message might seem cryptic, understanding its relationship with ODS LISTING management is crucial for SAS programming. By implementing proper ODS LISTING close statements and following best practices for ODS destination management, you can avoid this error and ensure smoother execution of your SAS programs.&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;Remember:&lt;/strong&gt; Maintaining clean and organized ODS management is the cornerstone of efficient SAS programming. Implement these strategies today to streamline your code, minimize errors, and maximize productivity.&lt;/p&gt;

    &lt;p&gt;Have you encountered the &quot;comment width&quot; error in your SAS programs? Share your solutions or challenges in the comments below!&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7237954987737007549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7237954987737007549'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2025/01/understanding-ods-listing-close-in-sas.html' title='The Critical Role of ODS LISTING Close Statements in SAS: Avoiding Comment Width Errors'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-4385123653302086708</id><published>2025-01-07T11:26:00.006-05:00</published><updated>2025-01-07T12:17:10.322-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Power Up Your Data Cleaning with the SAS COMPRESS Function"/><title type='text'>Power Up Your Data Cleaning with the SAS COMPRESS Function</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta charset=&quot;UTF-8&quot; /&gt;
  &lt;title&gt;&lt;/title&gt;
  &lt;style&gt;
    body {
      font-family: Arial, sans-serif;
      line-height: 1.6;
      margin: 0;
      padding: 0 20px;
      background-color: #f9f9f9;
    }
    header, footer {
      background-color: #3f51b5;
      color: #ffffff;
      padding: 20px 0;
      text-align: center;
    }
    h1, h2, h3 {
      color: #3f51b5;
    }
    .code-block {
      background-color: #f0f0f0;
      padding: 15px;
      margin: 10px 0;
      border-radius: 5px;
      font-family: Consolas, Menlo, monospace;
      white-space: pre; /* Preserve line breaks exactly as typed */
    }
    .highlight {
      background-color: #fef3c7;
      padding: 2px 4px;
      border-radius: 3px;
    }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;header&gt;
  &lt;h1&gt;Power Up Your Data Cleaning with the SAS COMPRESS Function&lt;/h1&gt;
&lt;/header&gt;

&lt;main&gt;
  &lt;article&gt;
    &lt;p&gt;
      When handling large datasets in SAS, it&#39;s common to encounter 
      unwanted characters, extra spaces, or other clutter that can 
      hamper your data analysis. Fortunately, the 
      &lt;strong&gt;COMPRESS&lt;/strong&gt; function helps you clean up your 
      text data efficiently. It can remove, or even keep, specific 
      characters from your strings with minimal effort. Keep reading 
      to learn how you can harness the full potential of the SAS 
      &lt;span class=&quot;highlight&quot;&gt;COMPRESS&lt;/span&gt; function.
    &lt;/p&gt;

    &lt;h2&gt;1. Quick Overview of the COMPRESS Function&lt;/h2&gt;
    &lt;p&gt;
      The &lt;strong&gt;COMPRESS&lt;/strong&gt; function in SAS removes (or 
      optionally keeps) certain characters from a character string. 
      Its basic syntax looks like this:
    &lt;/p&gt;
    &lt;div class=&quot;code-block&quot;&gt;
result_string = COMPRESS(source_string &lt;, characters_to_remove&gt; &lt;, modifiers&gt;);
    &lt;/div&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;source_string&lt;/strong&gt;: The original string you want to modify.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;characters_to_remove&lt;/strong&gt; (optional): A list of specific characters to eliminate.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;modifiers&lt;/strong&gt; (optional): Special flags (e.g., remove digits, punctuation, etc.).&lt;/li&gt;
    &lt;/ul&gt;

    &lt;h2&gt;2. Removing Specific Characters&lt;/h2&gt;
    &lt;p&gt;
      Suppose you have a string containing multiple symbols and you only 
      want to remove a specific one, such as the ampersand (&lt;code&gt;&amp;amp;&lt;/code&gt;).
    &lt;/p&gt;
    &lt;div class=&quot;code-block&quot;&gt;
data _null_;
  original = &quot;Cats &amp; Dogs 123&quot;;
  no_andsign = compress(original, &#39;&amp;&#39;);
  put no_andsign=;   /* Result: &quot;Cats  Dogs 123&quot; */
run;
    &lt;/div&gt;
    &lt;p&gt;
      In this example, we explicitly provide &lt;code&gt;&#39;&amp;amp;&#39;&lt;/code&gt; in the second argument, so only ampersands 
      are removed. Spaces, digits, and other characters remain.
    &lt;/p&gt;

    &lt;h2&gt;3. Removing All Spaces by Default&lt;/h2&gt;
    &lt;p&gt;
      If you leave out the second argument entirely, &lt;strong&gt;COMPRESS&lt;/strong&gt; automatically removes &lt;em&gt;all&lt;/em&gt; 
      spaces (including blank spaces). Here&#39;s a simple demonstration:
    &lt;/p&gt;
    &lt;div class=&quot;code-block&quot;&gt;
data _null_;
  original = &quot;Hello World &quot;;
  remove_blanks = compress(original);
  put remove_blanks=;  /* Result: &quot;HelloWorld&quot; */
run;
    &lt;/div&gt;

    &lt;h2&gt;4. Unleashing the Power of Modifiers&lt;/h2&gt;
    &lt;p&gt;
      Modifiers make &lt;strong&gt;COMPRESS&lt;/strong&gt; extremely powerful, as they 
      allow you to target entire categories of characters with minimal code. 
      Here are some of the most commonly used modifiers:
    &lt;/p&gt;
    &lt;table&gt;
      &lt;thead&gt;
        &lt;tr&gt;
          &lt;th&gt;Modifier&lt;/th&gt;
          &lt;th&gt;Action&lt;/th&gt;
        &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;
          &lt;td&gt;A&lt;/td&gt;
          &lt;td&gt;Removes all letters (alphabetic characters).&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;D&lt;/td&gt;
          &lt;td&gt;Removes all digits (0-9).&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;P&lt;/td&gt;
          &lt;td&gt;Removes all punctuation.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;S&lt;/td&gt;
          &lt;td&gt;Removes all space characters.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;U&lt;/td&gt;
          &lt;td&gt;Removes uppercase letters (A-Z).&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;L&lt;/td&gt;
          &lt;td&gt;Removes lowercase letters (a-z).&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;K&lt;/td&gt;
          &lt;td&gt;Keeps only the listed characters, instead of removing them.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;i&lt;/td&gt;
          &lt;td&gt;Ignore case when identifying characters to remove.&lt;/td&gt;
        &lt;/tr&gt;
        &lt;tr&gt;
          &lt;td&gt;t&lt;/td&gt;
          &lt;td&gt;Trims trailing blanks before removal.&lt;/td&gt;
        &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;

    &lt;h3&gt;4.1 Removing Digits&lt;/h3&gt;
    &lt;p&gt;
      For example, if you want to remove all digits from a string:
    &lt;/p&gt;
    &lt;div class=&quot;code-block&quot;&gt;
data _null_;
  original = &quot;Sales in 2023 increased by 15%&quot;;
  remove_digits = compress(original, , &#39;D&#39;);
  put remove_digits=;  /* Result: &quot;Sales in   increased by %&quot; */
run;
    &lt;/div&gt;
    &lt;p&gt;
      Notice that digits &lt;strong&gt;only&lt;/strong&gt; are removed; spaces and other 
      punctuation stay in place.
    &lt;/p&gt;

    &lt;h3&gt;4.2 Removing Punctuation&lt;/h3&gt;
    &lt;p&gt;
      Removing punctuation is equally straightforward:
    &lt;/p&gt;
    &lt;div class=&quot;code-block&quot;&gt;
data _null_;
  original = &quot;Hello, World! 2025.&quot;;
  no_punct = compress(original, , &#39;P&#39;);
  put no_punct=;  /* Result: &quot;Hello World 2025&quot; */
run;
    &lt;/div&gt;

    &lt;h3&gt;4.3 Combining Modifiers&lt;/h3&gt;
    &lt;p&gt;
      You can stack multiple modifiers together. For instance, to remove both 
      digits and punctuation:
    &lt;/p&gt;
    &lt;div class=&quot;code-block&quot;&gt;
data _null_;
  original = &quot;Item #123, Price: $45.67&quot;;
  remove_digits_punct = compress(original, , &#39;DP&#39;);
  put remove_digits_punct=; /* Result: &quot;Item  Price &quot; */
run;
    &lt;/div&gt;

    &lt;h3&gt;4.4 Using the &quot;Keep&quot; Modifier (K)&lt;/h3&gt;
    &lt;p&gt;
      Instead of specifying which characters to remove, you can flip the logic 
      and tell SAS which characters to &lt;em&gt;keep&lt;/em&gt; using &lt;strong&gt;K&lt;/strong&gt;. 
      For example, to keep only digits:
    &lt;/p&gt;
    &lt;div class=&quot;code-block&quot;&gt;
data _null_;
  original = &quot;Item #123, Price: $45.67&quot;;
  keep_digits = compress(original, &#39;0123456789&#39;, &#39;K&#39;);
  put keep_digits=; /* Result: &quot;1234567&quot; */
run;
    &lt;/div&gt;
    &lt;p&gt;
      Alternatively, combine &lt;code&gt;K&lt;/code&gt; with &lt;code&gt;D&lt;/code&gt; to shorten your code:
    &lt;/p&gt;
    &lt;div class=&quot;code-block&quot;&gt;
data _null_;
  original = &quot;Item #123, Price: $45.67&quot;;
  keep_digits = compress(original, , &#39;KD&#39;);
  put keep_digits=; /* Result: &quot;1234567&quot; */
run;
    &lt;/div&gt;

    &lt;h2&gt;5. Practical Scenarios&lt;/h2&gt;
    &lt;ol&gt;
      &lt;li&gt;&lt;strong&gt;Email Cleaning:&lt;/strong&gt; If you need to remove all punctuation (except “@” and “.”) from an email field, 
        you could selectively keep only those symbols, letters, and digits.
      &lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Financial Data:&lt;/strong&gt; Stripping out currency symbols and punctuation from a price field so you can convert 
        it into numeric form for calculations.
      &lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Text Mining:&lt;/strong&gt; Removing digits or punctuation from survey responses to focus on words alone.
      &lt;/li&gt;
    &lt;/ol&gt;

    &lt;h2&gt;6. Performance Considerations&lt;/h2&gt;
    &lt;p&gt;
      While &lt;strong&gt;COMPRESS&lt;/strong&gt; is handy, be mindful of its usage on extremely large datasets or within tight loops, 
      as repeated calls can be computationally expensive. It’s still typically faster than manually parsing strings, but 
      always weigh whether you really need to remove these characters or if you can handle them with custom formats or 
      other string functions.
    &lt;/p&gt;

    &lt;h2&gt;7. Putting it All Together&lt;/h2&gt;
    &lt;p&gt;
      Here’s a quick snippet that removes punctuation, digits, and trailing spaces all at once:
    &lt;/p&gt;
    &lt;div class=&quot;code-block&quot;&gt;
data _null_;
  original_str = &quot;  Hello, SAS 2025!   &quot;;
  /* 
     - &#39;P&#39; removes punctuation
     - &#39;D&#39; removes digits
     - &#39;t&#39; trims trailing blanks
  */
  cleaned_str = compress(original_str, , &#39;PDt&#39;);
  put cleaned_str=; 
  /* Step-by-step:
     1) Remove punctuation =&gt; &quot;  Hello SAS 2025   &quot;
     2) Remove digits =&gt; &quot;  Hello SAS    &quot;
     3) Trim trailing =&gt; &quot;  Hello SAS&quot;
  */
run;
    &lt;/div&gt;

    &lt;p&gt;
      Notice how a simple combination of modifiers can accomplish multiple clean-up tasks at once, giving you a much 
      tidier dataset in just one line of code (though, of course, you see it here laid out clearly in multiple lines 
      just like SAS EG would present it).
    &lt;/p&gt;

    &lt;h2&gt;Final Thoughts&lt;/h2&gt;
    &lt;p&gt;
      Whether you&#39;re massaging marketing data, cleaning up survey responses, or 
      extracting numeric values from text-heavy fields, the SAS 
      &lt;strong&gt;COMPRESS&lt;/strong&gt; function has you covered. With its powerful 
      modifiers and flexible syntax, it saves both time and effort, leaving 
      you more space to focus on the analytical heavy lifting. Give it a try 
      in your next data-cleaning project—you might be surprised at how 
      much cleaner your logs (and your data) become!
    &lt;/p&gt;
  &lt;/article&gt;
&lt;/main&gt;

&lt;footer&gt;
&lt;p&gt;&lt;em&gt;Posted by &lt;strong&gt;StudySAS&lt;/strong&gt; on studysas.blogpost.com&lt;/em&gt;&lt;/p&gt;
&lt;/footer&gt;

&lt;/body&gt;
&lt;/html&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/4385123653302086708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/4385123653302086708'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2025/01/power-up-your-data-cleaning-with-sas.html' title='Power Up Your Data Cleaning with the SAS COMPRESS Function'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-6296013984339958520</id><published>2025-01-07T10:03:00.005-05:00</published><updated>2025-01-07T11:24:12.445-05:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Non Printable characters in SAS datasets. Remove or Drop non printable characters"/><title type='text'>Solving Non-Printable Characters in AETERM/MHTERM for SDTM Datasets</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;title&gt;Solving Non-Printable Characters in AETERM/MHTERM for SDTM Datasets&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            margin: 20px;
            line-height: 1.6;
        }
        h1, h2, h3 {
            color: #333;
        }
        code {
            background-color: #f8f8f8;
            padding: 2px 4px;
            font-family: &quot;Courier New&quot;, Courier, monospace;
        }
        pre {
            background-color: #f8f8f8;
            padding: 10px;
            overflow-x: auto;
        }
        .highlight {
            background-color: #fffae6;
            padding: 10px;
            border: 1px solid #ffe58f;
            margin: 10px 0;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;

&lt;h1&gt;Solving Non-Printable Characters in AETERM/MHTERM for SDTM Datasets&lt;/h1&gt;

&lt;p&gt;
    Managing text variables in SDTM domains such as &lt;code&gt;AETERM&lt;/code&gt; (for Adverse Events) or 
    &lt;code&gt;MHTERM&lt;/code&gt; (for Medical History) can be challenging when non-printable (hidden) characters sneak in.
    These characters often arise from external data sources, copy-pasting from emails, encoding mismatches, or raw text 
    that includes ASCII control characters. In this post, we’ll explore methods to detect and remove 
    these problematic characters to ensure your SDTM datasets are submission-ready.
&lt;/p&gt;

&lt;hr /&gt;

&lt;h2&gt;1. Identifying Non-Printable Characters&lt;/h2&gt;
&lt;p&gt;
    Non-printable characters generally fall within the ASCII “control” range:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Hex range: &lt;code&gt;00&lt;/code&gt;–&lt;code&gt;1F&lt;/code&gt; and &lt;code&gt;7F&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;Decimal range: &lt;code&gt;0&lt;/code&gt;–&lt;code&gt;31&lt;/code&gt; and &lt;code&gt;127&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
    In SAS, you can detect these characters by examining their ASCII values using &lt;code&gt;RANK()&lt;/code&gt;, or by leveraging 
    built-in functions like &lt;code&gt;ANYCNTRL()&lt;/code&gt;. Below is an example snippet that loops through the first 100 
    observations of &lt;code&gt;AETERM&lt;/code&gt;, logs the position of any non-printable character, and displays its ASCII rank:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-sas&quot;&gt;
data check_chars;
   set yourlib.ae (obs=100);

   /* For demonstration, adjust these lengths to fit your actual data. */
   length test_char $1 non_print_char_flag $200;

   do i = 1 to length(aeterm);
      test_char = substr(aeterm, i, 1);

      /* Check for non-printable ASCII control characters (0–31, 127) */
      if rank(test_char) &lt; 32 or rank(test_char) = 127 then do;

         /* Build a single message string */
         non_print_char_flag = catx(&#39; &#39;,
            &#39;Non-printable found in USUBJID=&#39;, usubjid,
            &#39;at position=&#39;, put(i, best.),
            &#39;character=&#39;, test_char,
            &#39;rank=&#39;, put(rank(test_char), best.)
         );

         /* Write the message string to the SAS log */
         put non_print_char_flag;
      end;
   end;
run;

&lt;/code&gt;&lt;/pre&gt;

&lt;hr /&gt;

&lt;h2&gt;2. Removing Non-Printable Characters&lt;/h2&gt;
&lt;p&gt;
    Once you confirm non-printable characters are present, you can remove them in various ways. 
    Below are three common approaches:
&lt;/p&gt;

&lt;h3&gt;A. Using COMPRESS with Character Classes&lt;/h3&gt;
&lt;p&gt;
    The simplest way is to use the &lt;code&gt;COMPRESS&lt;/code&gt; function with the &lt;code&gt;&#39;c&#39;&lt;/code&gt; modifier, which removes 
    control characters (ASCII 0–31, 127):
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-sas&quot;&gt;
data clean;
  set yourlib.ae;
  /*aeterm_clean = compress(aeterm, , &#39;c&#39;); */
   aeterm_clean = compress(aeterm, , &#39;kw&#39;); 
  /* &#39;c&#39; removes control characters (ASCII 0–31, 127) */
run;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;B. Using a Perl Regular Expression (PRXCHANGE)&lt;/h3&gt;
&lt;p&gt;
    A more targeted approach uses &lt;code&gt;PRXPARSE&lt;/code&gt; and &lt;code&gt;PRXCHANGE&lt;/code&gt;. For instance, the following 
    regex removes control characters in the ranges &lt;code&gt;00–08&lt;/code&gt;, &lt;code&gt;0B&lt;/code&gt;, &lt;code&gt;0C&lt;/code&gt;, 
    &lt;code&gt;0E–1F&lt;/code&gt;, and &lt;code&gt;7F&lt;/code&gt;:
&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-sas&quot;&gt;
data clean;
  set yourlib.ae;
  /* Remove ASCII 00–08, 0B, 0C, 0E–1F, and 7F */
  retain re_removeControls PRXPARSE(&#39;s/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+//o&#39;);
  aeterm_clean = prxchange(re_removeControls, -1, aeterm);
run;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;C. Using TRANWRD Iteratively&lt;/h3&gt;
&lt;p&gt;
    For legacy or very narrow use cases, you might remove characters with multiple &lt;code&gt;TRANWRD()&lt;/code&gt; calls.
    However, this approach quickly becomes cumbersome if many different ASCII control characters need to be removed.
&lt;/p&gt;

&lt;hr /&gt;

&lt;h2&gt;3. Incorporating Into SDTM Mapping Programs&lt;/h2&gt;
&lt;p&gt;
    Typically, these solutions are applied during the data transformation from raw data to final SDTM domains. 
    For instance, in creating your &lt;code&gt;AE&lt;/code&gt; domain:
&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sas&quot;&gt;
data sdtm.ae;
  set raw.ae;

  /* Remove non-printable characters from AETERM */
  AETERM = compress(AETERM, , &#39;c&#39;); 

  /* Additional mappings and derivations here */

run;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;
    You can do the same in other domains (e.g., &lt;code&gt;MH&lt;/code&gt;, &lt;code&gt;CM&lt;/code&gt;) for consistent data cleaning.
&lt;/p&gt;

&lt;hr /&gt;

&lt;h2&gt;4. Additional Tips&lt;/h2&gt;
&lt;div class=&quot;highlight&quot;&gt;
    &lt;ul&gt;
        &lt;li&gt;&lt;strong&gt;Strip leading/trailing spaces:&lt;/strong&gt; After removing hidden characters, consider using 
            &lt;code&gt;STRIP()&lt;/code&gt; or &lt;code&gt;LEFT()&lt;/code&gt;/&lt;code&gt;RIGHT()&lt;/code&gt; to ensure no unintended spaces remain.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Compress multiple blanks:&lt;/strong&gt; If control character removal results in extra spaces, 
            &lt;code&gt;COMPBL()&lt;/code&gt; can reduce multiple blanks to a single space.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Document your approach:&lt;/strong&gt; Regulatory bodies often require justification that data cleaning 
            preserves the meaning of reported terms. Keep clear records of any cleaning steps performed.&lt;/li&gt;
        &lt;li&gt;&lt;strong&gt;Use consistently:&lt;/strong&gt; Apply the same cleaning methodology across all relevant 
            domains to avoid inconsistencies.&lt;/li&gt;
    &lt;/ul&gt;
&lt;/div&gt;

&lt;p&gt;
    By following these steps, you’ll ensure cleaner, more compliant SDTM datasets, minimize the risk of 
    downstream submission issues, and maintain higher data quality for your clinical studies.
&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Posted by &lt;strong&gt;StudySAS&lt;/strong&gt; on studysas.blogpost.com&lt;/em&gt;&lt;/p&gt;

&lt;/body&gt;
&lt;/html&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/6296013984339958520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/6296013984339958520'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2025/01/solving-non-printable-characters-in.html' title='Solving Non-Printable Characters in AETERM/MHTERM for SDTM Datasets'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-4942087196830674850</id><published>2024-12-17T09:34:00.003-05:00</published><updated>2024-12-17T09:34:52.614-05:00</updated><title type='text'>Learn how to view SAS dataset labels without opening the dataset directly in a SAS session. Easy methods and examples included!</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta name=&quot;description&quot; content=&quot;Learn how to view SAS dataset labels without opening the dataset directly in a SAS session. Easy methods and examples included!&quot;&gt;
    &lt;title&gt;Quick Tip: See SAS Dataset Labels Without Opening the Data&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 20px;
            background-color: #f8f8f8;
            color: #333;
        }
        h1, h2, h3 {
            color: #005792;
        }
        code {
            background-color: #f4f4f4;
            padding: 3px 5px;
            border: 1px solid #ddd;
            display: inline-block;
            border-radius: 4px;
            font-family: &quot;Courier New&quot;, Courier, monospace;
        }
        pre {
            background: #f4f4f4;
            padding: 10px;
            border: 1px solid #ddd;
            overflow: auto;
        }
        .container {
            max-width: 800px;
            margin: auto;
            background: white;
            padding: 20px;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
        }
        a {
            color: #005792;
            text-decoration: none;
        }
        a:hover {
            text-decoration: underline;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
        &lt;h1&gt;Quick Tip: See SAS Dataset Labels Without Opening the Data&lt;/h1&gt;
        &lt;p&gt;When working with SAS datasets, checking the &lt;strong&gt;dataset label&lt;/strong&gt; without actually opening the data can be very useful. Whether you&#39;re debugging or documenting, this small trick can save you time and effort!&lt;/p&gt;

        &lt;h2&gt;1. Use &lt;code&gt;PROC CONTENTS&lt;/code&gt;&lt;/h2&gt;
        &lt;p&gt;&lt;code&gt;PROC CONTENTS&lt;/code&gt; is the most common and straightforward way to view the dataset label.&lt;/p&gt;
        &lt;pre&gt;&lt;code&gt;proc contents data=yourlib.yourdataset;
run;&lt;/code&gt;&lt;/pre&gt;
        &lt;p&gt;The dataset label will appear in the output as the field: &lt;strong&gt;Data Set Label&lt;/strong&gt;.&lt;/p&gt;

        &lt;h2&gt;2. Query &lt;code&gt;DICTIONARY.TABLES&lt;/code&gt; or &lt;code&gt;SASHELP.VTABLE&lt;/code&gt;&lt;/h2&gt;
        &lt;p&gt;For a programmatic approach, use the &lt;strong&gt;DICTIONARY.TABLES&lt;/strong&gt; table or &lt;strong&gt;SASHELP.VTABLE&lt;/strong&gt; view to query dataset metadata.&lt;/p&gt;
        &lt;h3&gt;Example Using PROC SQL&lt;/h3&gt;
        &lt;pre&gt;&lt;code&gt;proc sql;
   select memname, memlabel 
   from dictionary.tables
   where libname=&#39;YOURLIB&#39; and memname=&#39;YOURDATASET&#39;;
quit;&lt;/code&gt;&lt;/pre&gt;

        &lt;h3&gt;Example Using SASHELP.VTABLE&lt;/h3&gt;
        &lt;pre&gt;&lt;code&gt;proc print data=sashelp.vtable;
   where libname=&#39;YOURLIB&#39; and memname=&#39;YOURDATASET&#39;;
   var memname memlabel;
run;&lt;/code&gt;&lt;/pre&gt;
        &lt;p&gt;Both methods will show the dataset&#39;s name and its label.&lt;/p&gt;

        &lt;h2&gt;3. Use &lt;code&gt;PROC DATASETS&lt;/code&gt;&lt;/h2&gt;
        &lt;p&gt;For advanced users, &lt;code&gt;PROC DATASETS&lt;/code&gt; can display dataset attributes, including labels:&lt;/p&gt;
        &lt;pre&gt;&lt;code&gt;proc datasets library=yourlib;
   contents data=yourdataset;
run;
quit;&lt;/code&gt;&lt;/pre&gt;

        &lt;h2&gt;Why Is This Helpful?&lt;/h2&gt;
        &lt;ul&gt;
            &lt;li&gt;Quickly check dataset metadata without loading or viewing the data.&lt;/li&gt;
            &lt;li&gt;Useful for documenting datasets during large projects.&lt;/li&gt;
            &lt;li&gt;Helpful in automation scripts for SAS programming.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;h2&gt;Conclusion&lt;/h2&gt;
        &lt;p&gt;Using these methods, you can easily view SAS dataset labels without opening the data. Whether you prefer &lt;code&gt;PROC CONTENTS&lt;/code&gt;, querying metadata tables, or &lt;code&gt;PROC DATASETS&lt;/code&gt;, the choice depends on your workflow.&lt;/p&gt;
        &lt;p&gt;Happy coding! If you found this tip useful, don&amp;rsquo;t forget to share it with your fellow SAS programmers.&lt;/p&gt;

        &lt;p&gt;Looking for more SAS programming tricks? Stay tuned for more posts on &lt;a href=&quot;#&quot;&gt;Rupee Stories&lt;/a&gt;!&lt;/p&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/4942087196830674850'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/4942087196830674850'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2024/12/learn-how-to-view-sas-dataset-labels.html' title='Learn how to view SAS dataset labels without opening the dataset directly in a SAS session. Easy methods and examples included!'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-7032574068630648417</id><published>2024-12-12T15:05:00.004-05:00</published><updated>2025-01-07T11:37:50.206-05:00</updated><title type='text'>Leveraging a SAS Macro to Generate a Report on Non-Printable Characters in SDTM Datasets</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;title&gt;&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 0;
            padding: 20px;
            background-color: #f4f4f9;
            color: #333;
        }
        h1, h2, h3 {
            color: #0056b3;
        }
        code {
            background: #e8e8e8;
            padding: 2px 4px;
            border-radius: 3px;
            font-family: &quot;Courier New&quot;, Courier, monospace;
        }
        pre {
            background: #f9f9f9;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
            overflow-x: auto;
        }
        .container {
            max-width: 800px;
            margin: auto;
            background: #fff;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
        }
        .highlight {
            background-color: #fffae6;
            padding: 5px;
            border-left: 4px solid #ffc107;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
        &lt;h1&gt;Detecting Non-Printable Characters in SDTM Datasets Using SAS&lt;/h1&gt;
        &lt;p&gt;Non-printable characters in datasets can lead to errors and inconsistencies, especially in the highly regulated environment of clinical trials. This blog post demonstrates how to create a SAS program that identifies non-printable characters in all SDTM datasets within a library and generates a comprehensive report.&lt;/p&gt;
        
        &lt;h2&gt;Why Detect Non-Printable Characters?&lt;/h2&gt;
        &lt;p&gt;Non-printable characters, such as ASCII values below 32 or above 126, can cause issues during data validation, regulatory submissions, and downstream processing. Detecting them early ensures the quality and compliance of your SDTM datasets.&lt;/p&gt;
        
        &lt;h2&gt;The SAS Program&lt;/h2&gt;
        &lt;p&gt;The following SAS program processes all SDTM datasets in a library and generates a combined report of non-printable characters, including:&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;strong&gt;Dataset name&lt;/strong&gt;: The dataset where the issue exists.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Variable name&lt;/strong&gt;: The variable containing non-printable characters.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Row number&lt;/strong&gt;: The row where the non-printable character is found.&lt;/li&gt;
            &lt;li&gt;&lt;strong&gt;Positions&lt;/strong&gt;: The exact position(s) of non-printable characters with their ASCII values.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;h3&gt;Program Code&lt;/h3&gt;
        &lt;pre&gt;
%macro find_nonprintable_all(libname=, output=);

    /* Get a list of all datasets in the library */
    proc sql noprint;
        select memname into :dsetlist separated by &#39; &#39;
        from dictionary.tables
        where libname = upcase(&quot;&amp;libname&quot;);
    quit;

    /* Create a combined report */
    data &amp;output.;
        length _dataset $32 _varname $32 _rownum 8 _position_list $500;
        retain _dataset _varname _rownum _position_list;
        call missing(_dataset, _varname, _rownum, _position_list);
        stop;
    run;

    /* Loop through each dataset and find non-printable characters */
    %let count = %sysfunc(countw(&amp;dsetlist));
    %do i = 1 %to &amp;count;
        %let dset = %scan(&amp;dsetlist, &amp;i);

        data temp_report;
            set &amp;libname..&amp;dset.;
            length _dataset $32 _varname $32 _rownum 8 _position_list $500;
            retain _dataset _varname _rownum _position_list;
            _dataset = &quot;&amp;dset&quot;;
            array charvars {*} _character_; /* Select all character variables */

            do i = 1 to dim(charvars);
                _varname = vname(charvars[i]);
                _rownum = _n_;
                _position_list = &#39;&#39;;

                /* Check each character in the variable */
                do j = 1 to length(charvars[i]);
                    charval = substr(charvars[i], j, 1);
                    ascii_val = rank(charval);

                    /* Flag non-printable characters */
                    if ascii_val &lt; 32 or ascii_val &gt; 126 then do;
                        _position_list = catx(&#39;, &#39;, _position_list, 
                                              &quot;Position=&quot; || put(j, best.) || &quot; (ASCII=&quot; || ascii_val || &quot;)&quot;);
                    end;
                end;

                /* Output if any non-printable characters are found */
                if not missing(_position_list) then output;
            end;

            drop i j charval ascii_val;
        run;

        /* Append to the combined report */
        proc append base=&amp;output. data=temp_report force;
        run;

        /* Clean up temporary dataset */
        proc datasets lib=work nolist;
            delete temp_report;
        quit;
    %end;

%mend;

/* Example usage */
%find_nonprintable_all(libname=sdtm, output=nonprintable_combined_report);

/* Review the combined report */
proc print data=nonprintable_combined_report noobs;
    title &quot;Non-Printable Characters Report for All Datasets in the Library&quot;;
run;
        &lt;/pre&gt;

        &lt;h3&gt;How It Works&lt;/h3&gt;
        &lt;div class=&quot;highlight&quot;&gt;
            &lt;p&gt;The program processes each dataset in the specified library, examines all character variables for non-printable characters, and records their positions in a combined report.&lt;/p&gt;
        &lt;/div&gt;

        &lt;h3&gt;Output&lt;/h3&gt;
        &lt;p&gt;The final report contains the following columns:&lt;/p&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;code&gt;_dataset&lt;/code&gt;: Name of the dataset.&lt;/li&gt;
            &lt;li&gt;&lt;code&gt;_varname&lt;/code&gt;: Name of the variable.&lt;/li&gt;
            &lt;li&gt;&lt;code&gt;_rownum&lt;/code&gt;: Row number.&lt;/li&gt;
            &lt;li&gt;&lt;code&gt;_position_list&lt;/code&gt;: Details of non-printable character positions and ASCII values.&lt;/li&gt;
        &lt;/ul&gt;

        &lt;h2&gt;Conclusion&lt;/h2&gt;
        &lt;p&gt;Using this SAS program, you can proactively identify and address non-printable characters in SDTM datasets, ensuring data integrity and compliance. Feel free to adapt this program for your specific needs.&lt;/p&gt;

    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7032574068630648417'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/7032574068630648417'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2024/12/detecting-non-printable-characters-in.html' title='Leveraging a SAS Macro to Generate a Report on Non-Printable Characters in SDTM Datasets'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-2315822260943695633.post-162934683031366951</id><published>2024-12-06T05:47:00.001-05:00</published><updated>2024-12-06T05:47:47.502-05:00</updated><title type='text'>SDTM aCRF Annotation Checklist</title><content type='html'>&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
    &lt;meta charset=&quot;UTF-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
    &lt;meta name=&quot;description&quot; content=&quot;A comprehensive checklist for annotating SDTM aCRF to meet compliance and regulatory submission requirements.&quot;&gt;
    &lt;meta name=&quot;keywords&quot; content=&quot;SDTM, aCRF, Annotation, Clinical Trials, Pinnacle 21, CDISC, Regulatory Compliance&quot;&gt;
    &lt;meta name=&quot;author&quot; content=&quot;Sarath Annapareddy&quot;&gt;
    &lt;title&gt;SDTM aCRF Annotation Checklist&lt;/title&gt;
    &lt;style&gt;
        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            margin: 0;
            padding: 0;
            background-color: #f9f9f9;
            color: #333;
        }
        header {
            background-color: #4CAF50;
            color: white;
            padding: 1em 0;
            text-align: center;
        }
        main {
            padding: 20px;
        }
        section {
            margin-bottom: 20px;
        }
        h1, h2 {
            color: #4CAF50;
        }
        ul {
            margin: 10px 0;
            padding: 0 20px;
        }
        footer {
            text-align: center;
            background-color: #333;
            color: white;
            padding: 1em 0;
        }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;header&gt;
        &lt;h1&gt;SDTM aCRF Annotation Checklist&lt;/h1&gt;
        &lt;p&gt;&lt;em&gt;By Sarath Annapareddy&lt;/em&gt;&lt;/p&gt;
    &lt;/header&gt;

    &lt;main&gt;
        &lt;section&gt;
            &lt;h2&gt;Introduction&lt;/h2&gt;
            &lt;p&gt;
                Creating an SDTM Annotated Case Report Form (aCRF) is a critical step in clinical trial data submission. 
                It ensures that data collected in the CRF maps correctly to SDTM domains, adhering to regulatory and CDISC standards. 
                This checklist serves as a guide to creating a high-quality SDTM aCRF ready for regulatory submission.
            &lt;/p&gt;
        &lt;/section&gt;

        &lt;section&gt;
            &lt;h2&gt;1. General Formatting&lt;/h2&gt;
            &lt;ul&gt;
                &lt;li&gt;Ensure the aCRF uses the latest SDTM IG version relevant to the study.&lt;/li&gt;
                &lt;li&gt;The document should be clean, legible, and free of overlapping annotations.&lt;/li&gt;
                &lt;li&gt;Page numbers in the aCRF should align with the actual CRF pages.&lt;/li&gt;
                &lt;li&gt;Annotations must be in English, clear, and consistently formatted.&lt;/li&gt;
                &lt;li&gt;Use color coding to differentiate domain mappings, derived variables, and special-purpose annotations.&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/section&gt;

        &lt;section&gt;
            &lt;h2&gt;2. Domain-Level Annotations&lt;/h2&gt;
            &lt;ul&gt;
                &lt;li&gt;Annotate each field on the CRF with the corresponding SDTM variable name (e.g., &lt;code&gt;DMAGE&lt;/code&gt;, &lt;code&gt;LBTEST&lt;/code&gt;).&lt;/li&gt;
                &lt;li&gt;Ensure every field includes an appropriate domain prefix (e.g., &lt;code&gt;DM&lt;/code&gt;, &lt;code&gt;AE&lt;/code&gt;).&lt;/li&gt;
                &lt;li&gt;Unmapped fields should be labeled with &quot;Not Mapped&quot; or &quot;NM&quot;.&lt;/li&gt;
                &lt;li&gt;Ensure proper usage of variable cases (e.g., all uppercase for SDTM variable names).&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/section&gt;

        &lt;section&gt;
            &lt;h2&gt;3. Data Collection Fields&lt;/h2&gt;
            &lt;ul&gt;
                &lt;li&gt;Map demographic fields (e.g., &lt;code&gt;SEX&lt;/code&gt;, &lt;code&gt;RACE&lt;/code&gt;) to the `DM` domain.&lt;/li&gt;
                &lt;li&gt;Adverse event fields (e.g., event name, severity) should map to the `AE` domain.&lt;/li&gt;
                &lt;li&gt;Laboratory test results and units should map to the `LB` domain.&lt;/li&gt;
                &lt;li&gt;Exposure data (e.g., drug start/stop dates) must align with the `EX` domain.&lt;/li&gt;
                &lt;li&gt;Use the `DV` domain for protocol deviations and the `MH` domain for medical history.&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/section&gt;

        &lt;section&gt;
            &lt;h2&gt;4. Special-Purpose Domains&lt;/h2&gt;
            &lt;ul&gt;
                &lt;li&gt;SUPPQUAL should be used for non-standard variables.&lt;/li&gt;
                &lt;li&gt;RELREC annotations are required for defining relationships between domains.&lt;/li&gt;
                &lt;li&gt;Free-text comments should map to the `CO` domain.&lt;/li&gt;
                &lt;li&gt;Trial design fields should map to domains like `TA`, `TV`, and `TS`.&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/section&gt;

        &lt;section&gt;
            &lt;h2&gt;5. Derived and Computed Variables&lt;/h2&gt;
            &lt;ul&gt;
                &lt;li&gt;Derived variables must be clearly labeled (e.g., &quot;DERIVED&quot; or &quot;CALCULATED&quot;).&lt;/li&gt;
                &lt;li&gt;Ensure annotations for variables like BMI reference all contributing fields (e.g., height and weight).&lt;/li&gt;
                &lt;li&gt;Visit variables (e.g., &lt;code&gt;VISITNUM&lt;/code&gt;, &lt;code&gt;VISITDY&lt;/code&gt;) should align with &lt;code&gt;RFSTDTC&lt;/code&gt;.&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/section&gt;

        &lt;section&gt;
            &lt;h2&gt;6. Date and Time Variables&lt;/h2&gt;
            &lt;ul&gt;
                &lt;li&gt;All date fields must follow ISO 8601 format (e.g., &lt;code&gt;AESTDTC&lt;/code&gt;, &lt;code&gt;EXSTDTC&lt;/code&gt;).&lt;/li&gt;
                &lt;li&gt;Derived date variables like &lt;code&gt;VISITDY&lt;/code&gt; should be calculated relative to &lt;code&gt;RFSTDTC&lt;/code&gt;.&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/section&gt;

        &lt;section&gt;
            &lt;h2&gt;7. Validation and Quality Control&lt;/h2&gt;
            &lt;ul&gt;
                &lt;li&gt;Validate the aCRF against the finalized SDTM datasets.&lt;/li&gt;
                &lt;li&gt;Ensure alignment with the Define.xml document.&lt;/li&gt;
                &lt;li&gt;Conduct reviews by the programming and data management teams.&lt;/li&gt;
                &lt;li&gt;Perform a completeness check to ensure no fields are left unannotated.&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/section&gt;

        &lt;section&gt;
            &lt;h2&gt;8. Regulatory Submission Readiness&lt;/h2&gt;
            &lt;ul&gt;
                &lt;li&gt;Ensure compliance with the requirements of regulatory authorities (e.g., FDA, PMDA).&lt;/li&gt;
                &lt;li&gt;Submit the aCRF in a searchable, bookmarked PDF format.&lt;/li&gt;
                &lt;li&gt;Verify that all color-coded annotations are visible in grayscale for printed versions.&lt;/li&gt;
                &lt;li&gt;Include a cover page with the study title, protocol number, and version.&lt;/li&gt;
            &lt;/ul&gt;
        &lt;/section&gt;

        &lt;section&gt;
            &lt;h2&gt;Conclusion&lt;/h2&gt;
            &lt;p&gt;
                A well-annotated SDTM aCRF is crucial for successful regulatory submissions. By following this checklist, 
                you can ensure your aCRF meets compliance requirements and demonstrates traceability between the CRF, datasets, 
                and Define.xml. This meticulous process not only ensures regulatory approval but also enhances the credibility 
                of your clinical trial data.
            &lt;/p&gt;
        &lt;/section&gt;
    &lt;/main&gt;

    &lt;footer&gt;
        &lt;p&gt;© 2024 Rupee Stories. All rights reserved.&lt;/p&gt;
    &lt;/footer&gt;
&lt;/body&gt;
&lt;/html&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/162934683031366951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2315822260943695633/posts/default/162934683031366951'/><link rel='alternate' type='text/html' href='http://studysas.blogspot.com/2024/12/sdtm-acrf-annotation-checklist.html' title='SDTM aCRF Annotation Checklist'/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry></feed>