
Define-XML en R avec metacore et metatools : lire et vérifier les métadonnées de soumission
Lisez un fichier de métadonnées de soumission Define-XML dans un objet metacore, extrayez ses listes de codes et ses spécifications au niveau valeur, et vérifiez vos jeux de données ADaM par rapport à cette spécification avec metatools — plus la frontière honnête de ce qui génère réellement un define.xml et comment il retrace chaque valeur d’analyse jusqu’au SDTM
Define-XML, ce sont les métadonnées lisibles par machine qui décrivent chaque jeu de données, variable, liste de codes et dérivation d’une soumission réglementaire — la table des matières de l’évaluateur. Ce tutoriel pratique lit un vrai define.xml du pilote CDISC dans un objet de métadonnées metacore, en extrait les listes de codes de terminologie contrôlée et les spécifications au niveau valeur, et vérifie les jeux de données ADaM réels par rapport à cette spécification avec metatools (un PASS de terminologie contrôlée et un vrai FAIL). Il trace la frontière honnête — metacore lit un define.xml, il n’en écrit pas ; la génération revient à Pinnacle 21 ou au package defineR open source — et montre le bénéfice de la traçabilité : comment les métadonnées au niveau valeur relient chaque valeur d’analyse à sa source SDTM. Sur les métadonnées publiques du pilote CDISC et des données pharmaverse, de sorte que chaque ligne s’exécute.
- Define-XML, ce sont les métadonnées lisibles par machine qui décrivent vos jeux de données de soumission — jeux de données, variables, métadonnées au niveau valeur, listes de codes de terminologie contrôlée, et dérivations. C’est la table des matières de l’évaluateur, et v2.1 est la version courante.
metacoreLIT un define.xml dans un objet structuré ; il n’en écrit pas.define_to_metacore()transforme undefine.xmlen sept tables bien rangées que vous pouvez interroger en R (ds_spec,var_spec,value_spec,codelist,derivations, …).metatoolsVÉRIFIE vos données par rapport à cette spécification.check_ct_col()etcheck_ct_data()vérifient les valeurs d’une variable par rapport à sa liste de codes ;check_variables()vérifie que le jeu de données a les bonnes colonnes — la boucle de conformité où le define.xml est le contrat et les données sont vérifiées par rapport à lui.- Ce qui génère réellement un define.xml, c’est un autre outillage — le standard de l’industrie Pinnacle 21 (spécification Excel → define.xml, prend en charge v2.1) ou le package R open source defineR (piloté par feuille de calcul, actuellement orienté v2.0).
metacore/xportrne l’écrivent jamais — soyez précis sur la frontière. - Define-XML est là où vit la traçabilité. Le
value_specenregistre l’originet lederivation_idde chaque variable, etderivationsdétient la logique en texte clair qui nomme la source SDTM — de sorte qu’un évaluateur peut retracer une valeur d’analyse ADaM jusqu’aux données collectées sans ouvrir le moindre code.
Introduction
Vous disposez d’un dossier de jeux de données XPT (SAS Transport version 5) prêts à être livrés. Un évaluateur qui les ouvre voit des colonnes nommées USUBJID, TRT01P, AVAL — laconiques, standardisées et, à elles seules, presque dénuées de sens. Ce qui transforme ce dossier en une soumission évaluable, c’est le fichier qui le décrit : Define-XML (abréviation de Case Report Tabulation Data Definition, define.xml), les métadonnées lisibles par machine qui listent chaque jeu de données, chaque variable, son type et sa liste de codes, et comment chaque valeur d’analyse a été dérivée. Un évaluateur ouvre le Define-XML en premier — c’est la feuille de route de tout le reste.
Cette leçon porte sur le travail avec ces métadonnées en R. Vous allez lire un vrai define.xml dans un objet structuré avec le package metacore, en extraire les listes de codes et les spécifications, puis vérifier vos jeux de données réels par rapport à lui avec metatools. Au passage, un point compte plus que n’importe quel appel de fonction : metacore lit un define.xml — il n’en écrit pas. Nous serons précis sur ce qui génère le fichier, et terminerons sur la raison d’être de tout le format : la traçabilité d’une valeur d’analyse jusqu’à sa source SDTM (Study Data Tabulation Model).
La leçon compagnon a exporté les jeux de données .xpt ; celle-ci est constituée des métadonnées qui voyagent à leurs côtés.
Ce qu’est le Define-XML : le dictionnaire de données de l’évaluateur
Define-XML est un standard CDISC (Clinical Data Interchange Standards Consortium) pour décrire les jeux de données de tabulation et d’analyse sous forme de métadonnées lisibles par machine. Un fichier define.xml par standard (un pour le SDTM, un pour l’ADaM — le Analysis Data Model) enregistre, pour chaque jeu de données qu’il couvre :
- les jeux de données et leur structure (un enregistrement par sujet, par paramètre, …) ;
- chaque variable, avec son type, sa longueur, son libellé et son format d’affichage ;
- des métadonnées au niveau valeur — des métadonnées qui varient par ligne, pas seulement par colonne (un
AVALADaM signifie une chose quandPARAMCD = "ACTOT"et une autre quand il s’agit du score d’un item unique) ; - des listes de codes — la terminologie contrôlée (CT) dont les valeurs d’une variable doivent provenir (l’ensemble des bras de traitement, groupes d’âge et sexes autorisés) ;
- des dérivations et une origine — d’où vient chaque valeur et la règle qui l’a produite.
Il est livré avec une feuille de style XSL qui l’affiche sous forme de define.html lisible, de sorte qu’un humain peut parcourir les mêmes métadonnées que consomme un outil de validation. Il est exigé par la FDA et la PMDA (l’Agence japonaise des produits pharmaceutiques et des dispositifs médicaux) pour une soumission — un package ADaM doit inclure un define.xml aux côtés de ses jeux de données, nommé dans les Study Data Standards Resources de la FDA. La version courante est Define-XML v2.1 (CDISC Define-XML v2.1 ; v2.0 est la version antérieure encore présente dans les soumissions plus anciennes).
Le reste de cette leçon travaille avec un define.xml réel. CDISC livre un define.xml d’exemple issu de son pilote public à l’intérieur du package metacore, de sorte que chaque bloc ci-dessous s’exécute sur de véritables métadonnées de soumission.
Lire un define.xml en R avec metacore
metacore transforme un define.xml en un objet bien rangé et interrogeable. define_to_metacore() analyse le fichier ; afficher le résultat résume les jeux de données qu’il couvre.
Passez verbose = "silent" pour garder l’analyse silencieuse — pas quiet = TRUE, qui est déprécié et émettra un avertissement.
library(metacore)
# CDISC's public pilot ADaM define.xml, bundled with metacore
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
mcL’objet détient les métadonnées des cinq jeux de données ADaM du pilote. Sous le capot, c’est un ensemble de sept tables bien rangées que vous pouvez extraire par nom — l’ensemble du define.xml, décompacté en data frames :
| Table | Ce qu’elle contient |
|---|---|
ds_spec |
une ligne par jeu de données — nom, structure, libellé |
ds_vars |
appartenance jeu de données ↔︎ variable, avec l’ordre de clé, le statut obligatoire et le statut core |
var_spec |
une ligne par variable — type, longueur, libellé, format |
value_spec |
métadonnées au niveau valeur — par variable : origin, derivation_id, code_id, where |
codelist |
les listes de codes de terminologie contrôlée — valeurs autorisées par code_id |
derivations |
derivation_id → la logique de dérivation en texte clair |
supp |
qualificateurs supplémentaires (vide pour ce define) |
Regardez la table au niveau jeu de données pour voir les déclarations de structure qu’enregistre le define :
library(metacore)
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
mc$ds_spec# A tibble: 5 × 3
dataset structure label
<chr> <chr> <chr>
1 ADSL one record per subject. Screen Failures are excluded. Subj…
2 ADADAS one record per subject per parameter per analysis visit per ana… ADAS…
3 ADLBC one record per subject per parameter per analysis visit Anal…
4 ADTTE one record per subject per parameter AE T…
5 ADAE one record per subject per adverse event Adve…
ADSL (le Subject-Level Analysis Dataset — une ligne par sujet) est déclaré comme « one record per subject. Screen Failures are excluded » — un énoncé de structure qui fait lui-même partie du contrat.
Pour travailler avec metatools, vous devez d’abord restreindre à un seul jeu de données avec select_dataset(). Cela vous donne un objet de métadonnées limité à un jeu de données, celui que lisent les contrôles :
library(metacore)
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
adsl_mc <- select_dataset(mc, "ADSL", verbose = "silent")
class(adsl_mc)[1] "DatasetMeta" "Metacore" "R6"
Extraire une liste de codes
Une liste de codes est la terminologie contrôlée à laquelle les valeurs d’une variable doivent appartenir. Accédez-y avec get_control_term() — passez la variable sans guillemets et elle renvoie les paires code/decode autorisées (la table codelist stocke les codes dans une colonne-liste, ce qui fait de cet accesseur la voie d’accès propre) :
library(metacore)
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
get_control_term(mc, TRT01P) # planned treatment arm — the permitted values# A tibble: 3 × 2
code decode
<chr> <chr>
1 Placebo Placebo
2 Xanomeline Low Dose Xanomeline Low Dose
3 Xanomeline High Dose Xanomeline High Dose
get_control_term(mc, AGEGR1) # pooled age group# A tibble: 3 × 2
code decode
<chr> <chr>
1 <65 <65
2 65-80 65-80
3 >80 >80
TRT01P (Planned Treatment for Period 01) n’autorise exactement que trois valeurs — Placebo, Xanomeline Low Dose, Xanomeline High Dose. Tout le reste dans vos données est, par définition, une violation de terminologie contrôlée. C’est le contrat que l’étape suivante fait respecter.
Vérifier vos données par rapport à la spécification avec metatools
Voici maintenant la boucle de conformité : le define.xml est le contrat, et metatools vérifie si votre jeu de données réel le respecte. Nous utilisons un vrai jeu de données ADaM au niveau sujet issu de pharmaverseadam.
Une divergence délibérée et honnête. L’ADSL de pharmaverseadam est une construction admiral plus récente que le define.xml du pilote 3, et il porte donc légitimement des valeurs et des colonnes que le define du pilote n’a jamais déclarées. Ce n’est pas un bug de metacore — c’est exactement l’écart qu’un contrôle de conformité existe pour révéler. Nous l’utilisons pour montrer le chemin FAIL avec une vraie sortie, non une erreur artificielle.
Commencez par une variable qui se conforme. check_ct_col() vérifie les valeurs d’une colonne par rapport à sa liste de codes ; lorsque tout se conforme, elle renvoie les données de façon invisible sans aucun avertissement :
library(metacore)
library(metatools)
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
adsl_mc <- select_dataset(mc, "ADSL", verbose = "silent")
data("adsl", package = "pharmaverseadam")
# SEX conforms to its codelist -> returns the data, no warning
checked <- check_ct_col(adsl, adsl_mc, SEX)
nrow(checked)[1] 306
Aucun avertissement : chaque valeur de SEX figure dans la liste de codes autorisée (M/F). Vérifiez maintenant TRT01P. La construction pharmaverseadam inclut des sujets en échec de sélection que le define du pilote exclut, si bien qu’une valeur apparaît que la liste de codes CL.ARM n’autorise pas — et le contrôle la signale :
library(metacore)
library(metatools)
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
adsl_mc <- select_dataset(mc, "ADSL", verbose = "silent")
data("adsl", package = "pharmaverseadam")
# TRT01P carries a value not in the define's codelist -> a warning
invisible(check_ct_col(adsl, adsl_mc, TRT01P))Warning: ✖ Invalid controlled terminology detected
ℹ Variable: TRT01P | Codelist: CL.ARM
ℹ Values not permitted 'Screen Failure'
L’avertissement nomme la variable, la liste de codes (CL.ARM) et la valeur fautive. Pour récupérer les valeurs incorrectes sous forme de données — pour les journaliser, les compter ou piloter une correction — utilisez get_bad_ct() :
library(metacore)
library(metatools)
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
adsl_mc <- select_dataset(mc, "ADSL", verbose = "silent")
data("adsl", package = "pharmaverseadam")
get_bad_ct(adsl, adsl_mc, TRT01P) # the values not permitted by the codelist[1] "Screen Failure"
get_bad_ct(adsl, adsl_mc, SEX) # character(0) -> SEX is cleancharacter(0)
"Screen Failure" est la valeur que porte la construction plus récente et que le define du pilote n’autorise pas ; SEX renvoie character(0) — rien d’anormal. Dans une vraie étude, vous résoudriez cela en alignant les données sur le define (ou en mettant à jour le define pour correspondre à la population d’analyse). Pour balayer toutes les colonnes de terminologie contrôlée d’un coup plutôt qu’une à une, check_ct_data(adsl, adsl_mc) exécute le même contrôle sur l’ensemble du jeu de données et avertit par colonne fautive.
La terminologie contrôlée est une moitié de la conformité ; l’autre est structurelle — le jeu de données a-t-il les colonnes qu’attend la spécification ? check_variables() compare les colonnes du jeu de données à la spécification et rapporte ce qui manque ou ce qui est en trop :
library(metacore)
library(metatools)
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
adsl_mc <- select_dataset(mc, "ADSL", verbose = "silent")
data("adsl", package = "pharmaverseadam")
invisible(check_variables(adsl, adsl_mc))Warning: In: [check_variables(adsl, adsl_mc)]
The following variables are missing: SITEGR1, TRT01PN, TRT01AN, AVGDD, CUMDOSE,
AGEGR1N, AGEGR2, AGEGR2N, RACEN, ITTFL, EFFFL, COMP8FL, COMP16FL, COMP24FL,
DISCONFL, DSRAEFL, BMIBL, BMIBLGR1, HEIGHTBL, WEIGHTBL, EDUCLVL, DISONSDT,
DURDIS, DURDSGR1, VISIT1DT, VISNUMEN, RFENDT, DCDECOD, DCSREAS, MMSETOT
The following variables do not belong: COUNTRY, RFXSTDTC, RFXENDTC, RFPENDTC,
SCRFDT, FRVDT, DTHDTC, DTHADY, LDDTHELD, LDDTHGR1, DTH30FL, DTHA30FL, DTHDOM,
DTHB30FL, REGION1, DMDTC, DMDY, RACEGR1, ARMCD, ACTARM, ACTARMCD, TRTSDTM,
TRTSTMF, TRTEDTM, TRTETMF, EOSDT, RFICDTC, RANDDT, LSTALVDT, DTHDT, DTHDTF,
DTHCAUS, DTHCGR1, BRTHDTC
Le rapport liste les variables ADSL que déclare le define du pilote mais que cette construction plus récente ne porte pas (SITEGR1, TRT01PN, BMIBL, …). Là encore, c’est la valeur voulue du contrôle, non une défaillance de l’outil : il nomme exactement quelles variables de la spécification sont absentes, de sorte que vous pouvez réconcilier le jeu de données et ses métadonnées déclarées avant même que le fichier n’atteigne un évaluateur. Ensemble, check_ct_*() et check_variables() forment la boucle de conformité — la spécification est le contrat, les données sont la preuve, et le contrôle vous dit où ils divergent.
Ce qui écrit réellement un define.xml (et ce qui ne l’écrit pas)
Voici le point à saisir avec exactitude, car il est facile d’en dire trop. metacore lit un define.xml ; il n’en écrit pas. metatools non plus, et xportr (qui exporte les jeux de données .xpt) non plus. Ils consomment les métadonnées ; ils ne génèrent pas le fichier define.xml. Si un workflow prétend « R écrit le define.xml avec metacore », c’est faux.
Générer un define.xml est un travail distinct, et en pratique il est piloté depuis une feuille de calcul de métadonnées, non depuis votre code d’analyse :
| Outil | Ce que c’est | Version Define-XML | Comment il fonctionne |
|---|---|---|---|
| Pinnacle 21 (Community / Enterprise) | Le validateur et générateur standard de l’industrie | Prend en charge v2.1 | Lit une spécification de métadonnées Excel, génère et valide le define.xml. Les propres fichiers define du pilote de CDISC proviennent de cette lignée pilotée par feuille de calcul. |
| defineR | Package R open source (sur CRAN) | Actuellement orienté v2.0 | write_metadata() crée un modèle de feuille de calcul → vous le remplissez → write_define() produit le define.xml (plus HTML/PDF). Piloté par feuille de calcul, non relié à metacore. |
metacore / metatools / xportr |
Les outils pharmaverse de lecture/vérification/export | — (lecture seule) | Ne génèrent pas de define.xml. metacore le lit ; metatools vérifie les données par rapport à lui ; xportr écrit le .xpt. |
Voici donc le tableau honnête : le define.xml est rédigé à partir d’une spécification de métadonnées — généralement en Define-XML v2.1 via Pinnacle 21, ou avec le defineR open source (actuellement orienté v2.0) — et ensuite metacore le relit pour la vérification et la traçabilité, ce que fait cette leçon. La soumission du pilote 3 publique du R Consortium a construit ses jeux de données ADaM en R avec admiral, metacore/metatools et xportr, mais son define.xml a été produit à partir d’une spécification de métadonnées par cette voie pilotée par feuille de calcul, non écrit par le code d’analyse R.
Retracer une valeur d’analyse jusqu’au SDTM
La raison la plus profonde de l’existence de Define-XML est la traçabilité : un évaluateur devrait pouvoir prendre n’importe quelle valeur d’analyse et la retracer jusqu’aux données source collectées et à la règle qui l’a produite — sans ouvrir une ligne de code. Cette information vit dans les métadonnées au niveau valeur, et metacore la fait apparaître par programme.
Deux tables la portent. value_spec enregistre, par variable, son origin (derived, assigned, collected, …) et un derivation_id ; derivations fait correspondre cet id à la règle en texte clair. Joignez-les et vous pouvez lire la lignée d’une valeur d’analyse directement depuis les métadonnées :
library(metacore)
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
# The value-level metadata for a few ADADAS analysis variables: origin + which rule made them
vs <- mc$value_spec
trace <- unique(vs[vs$dataset == "ADADAS" & vs$variable %in% c("AVAL", "ADY", "ADT"),
c("variable", "origin", "derivation_id")])
trace# A tibble: 4 × 3
variable origin derivation_id
<chr> <chr> <chr>
1 ADY derived MT.ADADAS.ADY
2 ADT derived MT.ADADAS.ADT
3 AVAL derived MT.ADADAS.AVAL
4 AVAL derived MT.ADADAS.AVAL.ACTOT
# The plain-text derivation logic those ids point to
mc$derivations[mc$derivations$derivation_id %in% trace$derivation_id, ]# A tibble: 4 × 2
derivation_id derivation
<chr> <chr>
1 MT.ADADAS.ADT "SAS date from QS.QSDTC"
2 MT.ADADAS.ADY "ADY = ADT - TRTSDT + 1, if ADT>=TRTSDT. ADY =\nADT - TR…
3 MT.ADADAS.AVAL "QS.QSSTRESN where QSTESTCD=PARAMCD"
4 MT.ADADAS.AVAL.ACTOT "Sum of ADAS scores for items 1, 2, 4, 5, 6, 7, 8, 11, 1…
Lisez les deux tables ensemble. ADADAS.AVAL a origin = "derived" et une règle qui dit QS.QSSTRESN where QSTESTCD=PARAMCD — la valeur d’analyse provient directement du résultat standardisé du domaine SDTM QS (Questionnaires). ADT est une « SAS date from QS.QSDTC », et ADY vaut ADT - TRTSDT + 1 — chaque dérivation nomme la variable source SDTM qu’elle lit. C’est le lien ADaM→SDTM, sous forme de métadonnées : le define.xml relie chaque valeur d’analyse aux données collectées et à la transformation entre elles. La reproductibilité et la traçabilité ne sont pas une promesse dans un document — ce sont des métadonnées structurées qu’un outil peut parcourir, ce qui est exactement ce que fait un évaluateur (ou votre propre QC).
Demandez à Prova « j’ai un define.xml et un ensemble de jeux de données ADaM — lis le define en R avec metacore et vérifie mes valeurs TRT01P et SEX par rapport à ses listes de codes avec metatools. » — elle répond en s’appuyant sur les leçons de ce pilier, avec du code pharmaverse exécutable que vous pouvez essayer sur des données d’exemple. The runtime is the judge. Demandez à Prova →
Problèmes fréquents
define_to_metacore() ou select_dataset() avertit au sujet d’un argument quiet déprécié. Ces fonctions prenaient un argument quiet = dans les versions plus anciennes ; il est déprécié. Utilisez verbose = "silent" pour supprimer les messages de progression (les autres niveaux sont "message" — la valeur par défaut bruyante — "warn" et "collapse"). Passer quiet = TRUE fonctionne encore mais affiche un avertissement de dépréciation.
Un exemple metacore .rda ne se charge pas avec load_metacore(). metacore livre deux sortes d’exemples : un define XML (ADaM_define_CDISC_pilot3.xml, lu avec define_to_metacore()) et un objet metacore sauvegardé (pilot_ADaM.rda). Le .rda est une sauvegarde base R — restaurez-le avec le load() de base R (il recrée un objet nommé metacore), et non load_metacore(), qui est destiné aux fichiers .rds écrits par save_metacore() et échoue avec « unknown input format » sur un .rda. Adaptez le chargeur au fichier.
Attendre de metacore (ou xportr) qu’il écrive le define.xml. Ce n’est pas le cas. metacore lit un define.xml et metatools vérifie les données par rapport à lui ; générer le fichier revient à Pinnacle 21 ou au package defineR open source, piloté depuis une feuille de calcul de métadonnées. Si votre pipeline doit produire un define.xml, tournez-vous vers l’un d’eux — pas vers metacore.
Questions fréquentes
Define-XML est un standard CDISC pour décrire les jeux de données de soumission sous forme de métadonnées lisibles par machine. Un fichier define.xml par standard (SDTM, ADaM) liste chaque jeu de données et chaque variable, son type et sa longueur, les listes de codes de terminologie contrôlée dont ses valeurs doivent provenir, les métadonnées au niveau valeur, et les dérivations et origines qui ont produit chaque valeur. Il est livré avec une feuille de style qui l’affiche sous forme de page lisible, et il est exigé par la FDA et la PMDA pour une soumission — le dictionnaire de données et la feuille de route de l’évaluateur. La version courante est Define-XML v2.1.
Utilisez le package metacore : mc <- define_to_metacore("define.xml", verbose = "silent"). Cela analyse le fichier en un objet structuré détenant sept tables bien rangées (ds_spec, ds_vars, var_spec, value_spec, codelist, derivations, supp). Restreignez à un seul jeu de données avec select_dataset(mc, "ADSL", verbose = "silent") avant de vérifier les données, et extrayez une liste de codes avec get_control_term(mc, TRT01P). Utilisez verbose = "silent", non l’argument déprécié quiet =.
Ni metacore ni xportr — ils ne font que lire des métadonnées et exporter des jeux de données. Un define.xml est généré à partir d’une métadonnée feuille de calcul, généralement par Pinnacle 21 (l’outil standard de l’industrie, prend en charge Define-XML v2.1) ou par le package R open source defineR (write_metadata() → remplissez le modèle → write_define() ; actuellement orienté v2.0). Les fichiers define du pilote CDISC proviennent de cette lignée pilotée par feuille de calcul. metacore relit ensuite le define.xml terminé pour la vérification et la traçabilité.
metacore lit et détient les métadonnées — il analyse un define.xml (ou une feuille de calcul de spécification) en un objet structuré que vous pouvez interroger pour les jeux de données, les variables, les listes de codes, et les dérivations. metatools agit sur les données en utilisant ces métadonnées — il vérifie vos jeux de données par rapport à la spécification (check_ct_col(), check_ct_data(), check_variables(), get_bad_ct()) et aide à en construire les variables. En bref : metacore, ce sont les métadonnées ; metatools, c’est la boîte à outils qui les applique à vos données.
Les métadonnées au niveau valeur sont des métadonnées qui varient par ligne, pas seulement par colonne. En ADaM, une seule variable comme AVAL (valeur d’analyse) signifie des choses différentes selon les paramètres — un PARAMCD est un score total, un autre est un item individuel — de sorte que le define.xml enregistre le type, l’origine, la dérivation et la liste de codes par valeur, indexés par une condition where (p. ex. where PARAMCD = "ACTOT"). Dans metacore, elles vivent dans la table value_spec (origin, derivation_id, code_id, where), et c’est ce qui permet à un évaluateur de retracer chaque valeur d’analyse jusqu’à sa source et sa règle spécifiques.
Testez vos connaissances
À l’aide du define du pilote fourni, (1) lisez ADaM_define_CDISC_pilot3.xml dans un objet metacore, (2) extrayez la liste de codes de AGEGR1 et notez ses valeurs autorisées, (3) restreignez à ADSL et utilisez metatools pour vérifier la colonne AGEGR1 du jeu de données adsl de pharmaverseadam par rapport à cette liste de codes, et (4) récupérez les valeurs fautives s’il y en a. Quel accesseur vous donne la liste de codes, et quelle fonction renvoie les valeurs incorrectes ?
Lisez avec define_to_metacore(path, verbose = "silent") ; extrayez une liste de codes avec get_control_term(mc, AGEGR1) (variable sans guillemets). Avant tout contrôle metatools, restreignez avec select_dataset(mc, "ADSL", verbose = "silent"). Les deux fonctions d’aide au contrôle sont check_ct_col(data, metacore, AGEGR1) (avertit si une valeur est hors liste de codes) et get_bad_ct(data, metacore, AGEGR1) (renvoie les valeurs fautives sous forme de vecteur caractère).
library(metacore)
library(metatools)
path <- metacore_example("ADaM_define_CDISC_pilot3.xml")
mc <- define_to_metacore(path, verbose = "silent")
# (2) the permitted AGEGR1 values
get_control_term(mc, AGEGR1) # <65, 65-80, >80
# (3)-(4) check the data against the spec
adsl_mc <- select_dataset(mc, "ADSL", verbose = "silent")
data("adsl", package = "pharmaverseadam")
check_ct_col(adsl, adsl_mc, AGEGR1) # warns if any value is off-codelist
get_bad_ct(adsl, adsl_mc, AGEGR1) # the offending values (character(0) if clean)get_control_term() renvoie les paires code/decode de la liste de codes ; get_bad_ct() renvoie les valeurs présentes dans les données mais absentes de la liste de codes. C’est la même boucle lire-puis-vérifier que la leçon exécute sur TRT01P et SEX — le define est le contrat, les données sont vérifiées par rapport à lui.
A. metacore::define_to_metacore() génère un nouveau define.xml à partir de vos jeux de données. B. metacore lit un define.xml dans un objet structuré ; générer le fichier est un outil distinct (Pinnacle 21 ou defineR). C. xportr_write() produit à la fois le .xpt et son define.xml en une seule étape.
B. metacore lit un define.xml (define_to_metacore()) en tables de métadonnées bien rangées et metatools vérifie les données par rapport à lui ; ni l’un ni l’autre n’écrit un define.xml. A est l’exagération fréquente — define_to_metacore() analyse un fichier existant, il n’en crée pas. C est faux aussi : xportr_write() n’écrit que le fichier de transport XPT. Un define.xml est généré à partir d’une feuille de calcul de métadonnées par Pinnacle 21 (v2.1) ou le package defineR open source (orienté v2.0).
Conclusion
Define-XML, ce sont les métadonnées qui font d’un dossier de jeux de données une soumission évaluable — les jeux de données, les variables, les listes de codes, les métadonnées au niveau valeur et les dérivations, en un seul contrat lisible par machine. En R, metacore lit ce contrat en tables bien rangées (define_to_metacore(), puis select_dataset() et get_control_term()), et metatools vérifie vos données par rapport à lui (check_ct_col(), check_ct_data(), get_bad_ct(), check_variables()) — la boucle de conformité qui attrape un écart de terminologie contrôlée ou de variable avant qu’un évaluateur ne le fasse. Soyez précis sur la frontière : metacore lit un define.xml, il n’en écrit pas — la génération revient à Pinnacle 21 (v2.1) ou au defineR open source (orienté v2.0), piloté depuis une feuille de calcul de métadonnées. Et gardez à l’esprit la raison d’être du format : les métadonnées au niveau valeur et les dérivations retracent chaque valeur d’analyse jusqu’à sa source SDTM, de sorte que la traçabilité est une chose qu’un outil peut parcourir, non une affirmation dans un document.
Cette leçon est reproductible : chaque résultat de cette page a été produit par le code montré — copiez n’importe quel bloc et exécutez-le pour les reproduire. The runtime is the judge.
Références
- CDISC Define-XML et Define-XML v2.1 — le standard et sa version courante : les métadonnées de soumission lisibles par machine que lit cette leçon.
- metacore — CRAN — lit un define.xml (ou une feuille de calcul de spécification) en un objet de métadonnées structuré ; la source des sept tables bien rangées et de
get_control_term(). - metatools — CRAN — vérifie les jeux de données par rapport à une spécification
metacore:check_ct_col(),check_ct_data(),get_bad_ct(),check_variables(). - defineR — CRAN — le package R open source qui génère un define.xml à partir d’une feuille de calcul de métadonnées (actuellement orienté Define-XML v2.0).
- Pinnacle 21 Define-XML 2.1 support — l’ outil standard de l’industrie qui génère et valide un define.xml (v2.1) à partir d’une spécification de métadonnées Excel.
- FDA Study Data Standards Resources — le hub de la FDA nommant les standards CDISC et les métadonnées Define-XML qu’une soumission doit inclure.
- R Consortium Submissions Pilot 3 — la soumission ADaM + TLF publique fondée sur R construite avec
admiral,metacore/metatoolsetxportr.
Leçons connexes
- Exporter un fichier XPT en R avec xportr — écrire les jeux de données
.xptque décrit ce Define-XML, piloté depuis la même spécificationmetacore. · Anatomie de la soumission eCTD — où se situe le define.xml dans le dossier de données du Module 5. · Contrôles de conformité SDTM en R — valider les données de tabulation jusqu’auxquelles remonte le define ADaM. · Créer l’ADSL en R avec admiral — dériver le jeu de données ADaM dont le define.xml documente les valeurs. · Qualification de package R avec riskmetric — qualifiermetacore/metatoolspour un environnement validé. - Où cela s’inscrit : valider les données ADaM → les exporter en XPT v5 → lire et vérifier les métadonnées Define-XML (vous êtes ici) → rédiger les guides de l’évaluateur → empaqueter les programmes R pour l’eCTD. · Assemblage du dossier de soumission — la série complète. · Pharma & Clinique — le pilier.
Réutilisation
Citation
@online{2026,
author = {},
title = {Define-XML en R avec metacore et metatools : lire et vérifier
les métadonnées de soumission},
date = {2026-07-01},
url = {https://www.datanovia.com/learn/pharma-clinical/07-submission-packaging/define-xml-metacore},
langid = {fr}
}