library(tidyverse)
library(xml2)
dx <- "refs/DefineV2111_0"
schema <- read_xml(file.path(dx, "schema/cdisc-define-2.1/define2-1-0.xsd"))27 Exercise 8: Define-XML
27.1 Goal
Take the schema-valid but non-conformant document from the Define-XML session and make it conformant, then extend it to describe the one thing an SDTM variable cannot describe with a single origin, and the one variable this course cannot populate at all.
27.2 Setup
Work from the project root. You need the CDISC Define-XML v2.1 package unzipped into refs/, as the session’s opening callout describes:
Rebuild the DM document from the session’s Example 1 before you start, or keep the R session open from where the session left off.
27.3 Task
(Guided) Resolve rule 73. The session’s document declares
USUBJIDwithOrigin Type="Derived"and noMethodOID, which violates conformance rule 73.Fix it properly. That means two additions, not one: a
MethodDefelement that states howUSUBJIDis derived, and aMethodOIDattribute on theItemRefthat points at it. GLPX-1 buildsUSUBJIDby concatenating the study identifier, the site and the subject number. CheckR/build_sdtm.Rand describe what it actually does, not what you assume it does.Re-run
xml_validate()and re-run the rule 73 check from the session. Then answer: the document validatedTRUEbefore this fix and validatesTRUEafter. What changed, and who benefits?(The trap) Value-level metadata for LB. Add an
ItemGroupDeffor LB, and defineLBSTRESN.You will find you cannot. Not because anything is missing from your toolkit, but because a single
ItemDefforLBSTRESNcannot say what the variable means: in GLPX-1’s LB,LBSTRESNholds HbA1c in percent on some rows and fasting plasma glucose in mmol/L on others. One variable, oneItemDef, two meanings, two units, two reference ranges.Find out how Define-XML resolves this. Read §4.5 of the specification, and look at how
IT.LB.LBORRESis defined in the package’s own example atrefs/DefineV2111_0/examples/DefineXML-2-1-SDTM/defineV21-SDTM.xml.Build it: a
def:ValueListRefon theItemDef, adef:ValueListDefcontaining oneItemRefper parameter, and adef:WhereClauseDeffor each that says which rows it applies to. Use theLBTESTCDvalues GLPX-1 actually contains. Read them fromdata/sdtm/lb.csvrather than assuming; there are more of them than you might guess.Then answer, in one sentence each:
- What does a
def:WhereClauseDefactually express, in plain English? - Value-level metadata adds rows to the metadata document rather than columns to the dataset. Where have you seen that same move before in this course?
- What does a
(Semi-guided) The variable with no values. Add an
ItemGroupDeffor ADAE’s source AE domain, and defineAEDECOD.AEDECODis null on all 389 rows, for the reason ADAE established: this study’s adverse events were never coded, because MedDRA is a licensed dictionary.Define-XML v2.1 has a specific mechanism for this, and using it triggers a second requirement. Find both. Search the conformance rules workbook for
HasNoData, rules 76 and 242 are the two you need, and note that both have Source TypeSpecification.Implement both, then answer:
- Why is declaring “this variable has no data” better than simply omitting the variable from the
ItemGroupDef? - Rule 242 requires a comment whenever
def:HasNoData="Yes". Write the comment you would actually submit forAEDECOD. It should be readable by a reviewer who has never heard of this course.
- Why is declaring “this variable has no data” better than simply omitting the variable from the
27.4 Acceptance criteria
Task 1: MethodDef goes at the MetaDataVersion level, beside ItemDef and CodeList, same Def/Ref pattern as everything else. It needs OID, Name, Type and a Description. If the schema rejects your placement, remember that element order is an absolute requirement (§3.6) and the error message names what it expected instead.
Task 2: the chain is ItemDef → def:ValueListRef → def:ValueListDef → ItemRef → def:WhereClauseRef → def:WhereClauseDef → RangeCheck. Six links, and every one is an OID pointing at something declared elsewhere. This task is the central intuition of the session made tedious on purpose. Note that the value-level ItemDefs are separate ItemDef elements with their own OIDs; the example’s naming (IT.LB.LBORRES.SET1.LBSPEC.BLOOD) shows the convention, though as the session established, the convention is not the standard.
Task 3: def:HasNoData goes on the ItemRef, not the ItemDef. Read rule 76’s XPath column carefully, because getting this backwards is the most common way to fail it. Rule 242 then tells you what else becomes required, and the def:CommentDef element is documented in §4.8.
Solutions are in the paid tier.