Métadonnées Define-XML avec l’IA en R : rédiger, valider

Laissez un copilote IA rédiger en quelques secondes la spécification de métadonnées au niveau variable qui alimente un Define-XML — puis exécutez les contrôles metatools qui attrapent une valeur de terminologie contrôlée hallucinée avant qu’elle n’atteigne une soumission

Un copilote IA peut rédiger les métadonnées ADaM au niveau variable — les tables de spécification metacore à partir desquelles un Define-XML est généré — depuis une description en langage courant en quelques secondes. Cette leçon fait exactement cela, puis valide le brouillon face aux vraies données avec metatools : check_ct_data attrape une hallucination de terminologie contrôlée assurée (l’IA applique le regroupement AGEGR1 de manuel que l’étude n’a jamais utilisé), get_bad_ct nomme les valeurs fautives, et check_variables attrape une variable supprimée. Elle trace la frontière honnête — metacore et metatools lisent et vérifient les métadonnées, ils n’écrivent jamais le define.xml — et garde la responsabilité là où elle doit être : l’IA rédige la spécification vite, l’outillage plus un humain la contrôlent. Sur des données pharmaverse publiques, pour que chaque contrôle s’exécute.

Date de publication

2 juillet 2026

Modifié

7 juillet 2026

AstucePoints clés
  • Un copilote IA rédige la spécification de métadonnées vite — pas le fichier. Il transforme une description en langage courant en les tables metacore (labels, types, longueurs, listes de codes de terminologie contrôlée) à partir desquelles un Define-XML est généré, en quelques secondes. Cet échafaudage est un travail répétitif et bien balisé qu’un assistant fait bien.
  • Le brouillon est non qualifié. Un Define-XML est un livrable de soumission — un livrable GxP (les réglementations qualité de « bonnes pratiques » : GCP, GMP, GLP) — et « la spécification a l’air soignée » n’a jamais été le critère pour un contrat de métadonnées qu’un relecteur lit en premier.
  • La prise signature : l’IA applique le regroupement d’âge de manuel <65 / 65-80 / >80 à AGEGR1, alors que cette étude a dérivé 18-64 / >64. check_ct_data() le signale en une ligne ; un coup d’œil à la spécification soignée, non.
  • metacore/metatools lisent et vérifient — ils n’écrivent jamais le define.xml. La génération est un outil distinct (Pinnacle 21 ou le defineR open source). Soyez précis sur cette frontière.
  • L’IA change la vitesse, pas la responsabilité. Le programmeur est maître des métadonnées et de la validation qui le prouve ; l’outillage et un humain attrapent ce que l’IA a raté.

Introduction

Un statisticien vous remet un jeu de données ADaM (Analysis Data Model) et vous demande ses métadonnées : labels, types, longueurs, et les listes de codes de terminologie contrôlée qui décrivent chaque variable. Un copilote IA — un assistant de codage IA tel que Claude, ChatGPT ou GitHub Copilot — rédigera cette spécification plus vite que vous n’ouvrez un modèle. La sortie est l’ensemble de tables que le package metacore détient, et ces tables sont ce à partir de quoi un fichier Define-XML est généré — les métadonnées lisibles par machine (define.xml) qui décrivent chaque jeu de données, variable, liste de codes et dérivation d’une soumission réglementaire, et la première chose qu’un relecteur ouvre.

C’est vraiment utile, et tout aussi vraiment dangereux. Les métadonnées sont un contrat, et une IA qui remplit avec assurance une liste de codes d’un ensemble de valeurs plausibles mais fausses vous livre une spécification qui a l’air soignée et qui est silencieusement non conforme. Cette leçon parcourt toute la boucle sur des données publiques du pharmaverse : décrire les métadonnées, laisser le copilote rédiger les tables metacore, construire l’objet de métadonnées, puis utiliser metatools pour valider le brouillon face aux vraies données — et attraper l’erreur qu’a faite l’IA.

C’est le complément en sens direct de la leçon de lecture d’un Define-XML existant : cette leçon lit un define.xml terminé dans R avec define_to_metacore() et vérifie les données face à lui ; ici, nous rédigeons les métadonnées qui en alimentent un et validons le brouillon avant qu’il ne devienne un fichier. Elle met aussi en œuvre le principe de la carte des capacités qui ouvre cette série et de la démo ADTTE à partir d’un critère : l’IA rédige, vous validez.

La frontière : ce que l’IA rédige, et ce qu’elle ne rédige pas

Saisissez ceci exactement, car il est facile d’en dire trop. Trois lignes tracent la frontière :

  • L’IA rédige la spécification de métadonnées — les tables metacore (labels de variables, types, longueurs, et listes de codes de terminologie contrôlée). Elle n’écrit pas le fichier define.xml.
  • metacore détient cette spécification en mémoire ; metatools vérifie les données face à elle. Ni l’un ni l’autre n’écrit de define.xml. Ce qui génère réellement le fichier, c’est un outillage distinct — le Pinnacle 21 standard de l’industrie ou le package R open source defineR, tous deux pilotés depuis une feuille de calcul de métadonnées. La spécification metacore est l’entrée de cette génération, vérifiée et traçable dans R.
  • Rédigé par l’IA n’est pas validé par l’IA. Le copilote accélère le premier brouillon ; metatools plus un programmeur qualifié attrapent ce qu’il a raté. La responsabilité des métadonnées reste humaine.

La frontière posée, construisez un brouillon et cassez-le.

Les métadonnées à encoder

Le jeu de données est ADSL (le jeu de données d’analyse au niveau sujet — une ligne par sujet). Nous prenons une petite tranche représentative de ses variables et décrivons ce que chacune devrait contenir :

Variable Label Terminologie contrôlée ?
STUDYID Study Identifier
USUBJID Unique Subject Identifier
SUBJID Subject Identifier for the Study
SITEID Study Site Identifier
AGE Age
AGEGR1 Pooled Age Group 1 oui — les tranches d’âge de l’étude
SEX Sex ouiM / F
ARM Description of Planned Arm
TRT01P Planned Treatment for Period 01

Deux variables portent une terminologie contrôlée (CT) — l’ensemble fixe de valeurs permises qu’une variable peut prendre : SEX et AGEGR1. SEX ne fait pas débat. AGEGR1 est là où un brouillon se trompe, alors fixez ce que les données contiennent réellement avant de faire confiance à la moindre spécification :

library(pharmaverseadam)

adsl <- pharmaverseadam::adsl[, c("STUDYID", "USUBJID", "SUBJID", "SITEID",
                                  "AGE", "AGEGR1", "SEX", "ARM", "TRT01P")]

# The controlled terminology this study actually used for AGEGR1
table(adsl$AGEGR1)

  >64 18-64 
  264    42 

Cette étude a réparti l’âge en 18-64 et >64 — deux catégories, pas le regroupement à trois tranches que vous pourriez attendre. Retenez ce fait ; c’est le piège.

La spécification de métadonnées rédigée par l’IA

Sollicité avec la description ci-dessus et invité à « rédiger la spécification metacore pour ADSL », un assistant produit les tables ci-dessous. metacore modélise les métadonnées d’un define sous forme de six tables, et il vaut la peine de nommer chacune avant que le code ne s’exécute :

  • ds_spec — une ligne par jeu de données (nom, structure, label).
  • ds_vars — quelles variables appartiennent au jeu de données, avec l’ordre des clés et si chacune est obligatoire.
  • var_spec — les attributs de chaque variable (type, longueur, label).
  • value_spec — les métadonnées au niveau valeur : par variable, son origine et la liste de codes à laquelle elle est reliée.
  • codelist — les listes de codes de terminologie contrôlée : les valeurs permises, contenues dans une colonne-liste.
  • derivations — la logique de dérivation en texte clair (vide ici ; ces variables sont collectées ou assignées, pas dérivées).

Lisez attentivement la table codelist — c’est là que vit l’erreur de l’IA. Sollicité à partir du concept « pooled age group », l’assistant a opté pour le regroupement CDISC de manuel <65 / 65-80 / >80 au lieu des tranches que cette étude a réellement dérivées. Le code se construit proprement et l’objet s’assemble sans se plaindre :

suppressPackageStartupMessages(library(metacore))
library(tibble)

vars <- c("STUDYID", "USUBJID", "SUBJID", "SITEID",
          "AGE", "AGEGR1", "SEX", "ARM", "TRT01P")
required <- c("STUDYID", "USUBJID", "SUBJID", "AGE", "SEX", "ARM")

# One row per dataset
ds_spec <- tibble(
  dataset   = "ADSL",
  structure = "one record per subject",
  label     = "Subject-Level Analysis Dataset"
)

# Which variables belong to ADSL (mandatory + core, not the deprecated `keep`)
ds_vars <- tibble(
  dataset   = "ADSL",
  variable  = vars,
  key_seq   = ifelse(vars %in% c("STUDYID", "USUBJID"),
                     match(vars, c("STUDYID", "USUBJID")), NA_integer_),
  order     = seq_along(vars),
  mandatory = vars %in% required,
  core      = ifelse(vars %in% required, "Required", "Permissible"),
  supp_flag = FALSE
)

# Each variable's attributes
labels <- c(STUDYID = "Study Identifier", USUBJID = "Unique Subject Identifier",
            SUBJID = "Subject Identifier for the Study", SITEID = "Study Site Identifier",
            AGE = "Age", AGEGR1 = "Pooled Age Group 1", SEX = "Sex",
            ARM = "Description of Planned Arm", TRT01P = "Planned Treatment for Period 01")
types <- c(STUDYID = "text", USUBJID = "text", SUBJID = "text", SITEID = "text",
           AGE = "integer", AGEGR1 = "text", SEX = "text", ARM = "text", TRT01P = "text")
var_spec <- tibble(
  variable = vars,
  type     = unname(types[vars]),
  length   = NA_integer_,
  label    = unname(labels[vars]),
  format   = NA_character_,
  common   = NA
)

# Value-level metadata: link AGEGR1 and SEX to their codelists
value_spec <- tibble(
  dataset       = "ADSL",
  variable      = vars,
  code_id       = ifelse(vars == "AGEGR1", "CL.AGEGR1",
                  ifelse(vars == "SEX", "CL.SEX", NA_character_)),
  type          = unname(types[vars]),
  origin        = "Assigned",
  derivation_id = NA_character_,
  where         = NA_character_,
  sig_dig       = NA_integer_
)

# The controlled terminology -- AGEGR1 is the AI's HALLUCINATION (textbook, not this study)
codelist <- tibble(
  code_id = c("CL.AGEGR1", "CL.SEX"),
  name    = c("Pooled Age Group 1", "Sex"),
  type    = "permitted_val",
  codes   = list(c("<65", "65-80", ">80"),   # textbook grouping -- WRONG for this study
                 c("M", "F"))
)

# Required even when empty
derivations <- tibble(derivation_id = character(), derivation = character())

# Assemble the immutable metadata object and scope it to ADSL
mc_draft   <- metacore(ds_spec, ds_vars, var_spec, value_spec,
                       derivations = derivations, codelist = codelist,
                       verbose = "silent")
adsl_draft <- select_dataset(mc_draft, "ADSL", verbose = "silent")
mc_draft
── Metacore object contains metadata for 1 datasets ────────────────────────────
→ ADSL (Subject-Level Analysis Dataset)
To use the Metacore object with metatools package, first subset a dataset using
`metacore::select_dataset()`

L’objet s’assemble : metacore() renvoie un modèle de métadonnées valide en mémoire pour un jeu de données, et select_dataset() le restreint à ADSL pour que metatools puisse y lire. Rien ici n’a produit d’erreur — ce qui est justement le problème. La spécification est structurellement correcte et sémantiquement fausse, et seule une vérification face aux vraies données peut faire la différence.

Valider : attraper la terminologie contrôlée hallucinée

check_ct_data() balaie chaque colonne de terminologie contrôlée du jeu de données et compare ses valeurs à la liste de codes que la spécification déclare. Exécutez-le face au brouillon de l’IA :

library(metatools)

invisible(check_ct_data(adsl, adsl_draft))
Warning: ✖ Invalid controlled terminology detected
ℹ Variable: AGEGR1 | Codelist: CL.AGEGR1
ℹ Values not permitted '18-64' and '>64'

Le contrôle échoue bruyamment : AGEGR1 porte les valeurs 18-64 et >64, et la liste de codes CL.AGEGR1 de l’IA (<65 / 65-80 / >80) n’en permet aucune. SEX passe en silence — l’IA a eu raison sur celle-là. Pour récupérer les valeurs fautives sous forme de données — les journaliser, les compter, ou piloter un correctif — utilisez get_bad_ct() :

library(metatools)

get_bad_ct(adsl, adsl_draft, "AGEGR1")
[1] "18-64" ">64"  

"18-64" ">64" — les deux catégories réelles que la liste de codes du brouillon n’autorise pas. C’est toute la leçon en une ligne : l’IA a produit une liste de codes assurée, soignée, plausible comme dans un manuel, et elle ne correspond pas à l’étude. Un coup d’œil à la spécification ne l’attraperait pas ; un contrôle d’une ligne, oui.

Corriger la liste de codes et re-vérifier

Le correctif consiste à aligner la liste de codes sur la dérivation réelle de l’étude. Corrigez l’unique entrée fautive, reconstruisez l’objet de métadonnées et ré-exécutez le contrôle (cela réutilise les tables de spécification construites ci-dessus) :

library(metacore)
library(metatools)

# Align AGEGR1 to the study's real age bands
codelist$codes[codelist$code_id == "CL.AGEGR1"] <- list(c("18-64", ">64"))

mc_fixed   <- metacore(ds_spec, ds_vars, var_spec, value_spec,
                       derivations = derivations, codelist = codelist,
                       verbose = "silent")
adsl_fixed <- select_dataset(mc_fixed, "ADSL", verbose = "silent")

invisible(check_ct_data(adsl, adsl_fixed))
✔ All controlled terminology checks passed
library(metatools)
get_bad_ct(adsl, adsl_fixed, "AGEGR1")
character(0)

✔ All controlled terminology checks passed, et get_bad_ct() renvoie désormais character(0) — aucune valeur fautive. La terminologie contrôlée des métadonnées est conforme aux données qu’elle décrit.

L’autre axe : chaque variable a-t-elle sa place ?

La terminologie contrôlée est une moitié de la conformité ; l’autre est structurelle — la spécification liste-t-elle les bonnes variables ? check_variables() compare les colonnes du jeu de données à la spécification et signale tout ce qui manque ou est en trop. Un deuxième dérapage courant de l’IA est de supprimer silencieusement une variable de la spécification. Reconstruisez les métadonnées sans TRT01P pour voir le contrôle structurel se déclencher :

library(metacore)
library(metatools)

# A spec that dropped TRT01P (the AI omitted it)
mc_missing <- metacore(
  ds_spec,
  ds_vars[ds_vars$variable != "TRT01P", ],
  var_spec[var_spec$variable != "TRT01P", ],
  value_spec[value_spec$variable != "TRT01P", ],
  derivations = derivations, codelist = codelist, verbose = "silent"
)
adsl_missing <- select_dataset(mc_missing, "ADSL", verbose = "silent")

invisible(check_variables(adsl, adsl_missing, strict = FALSE))
Warning: In: [check_variables(adsl, adsl_missing, strict = FALSE)]

The following variables do not belong: TRT01P
# The complete, corrected spec has every ADSL variable
invisible(check_variables(adsl, adsl_fixed, strict = TRUE))
No missing or extra variables

Le premier contrôle avertit — The following variables do not belong: TRT01P — parce que les données ont une colonne que la spécification n’a jamais déclarée. La spécification complète rapporte No missing or extra variables. La même discipline s’étend à tout jeu de données : pointez les contrôles vers ADAE (le jeu de données d’analyse des événements indésirables) ou tout autre, et ils font ressortir exactement là où les métadonnées et les données divergent. (Passer strict = TRUE transforme l’avertissement en erreur bloquante — utile quand vous voulez qu’un pipeline s’arrête sur une discordance.)

La barrière honnête

Remarquez ce que les contrôles font et ne font pas. Par défaut, ils avertissent — ils font ressortir un problème et laissent l’exécution se poursuivre ; ils n’empêchent pas silencieusement une mauvaise spécification d’avancer en aval. La vraie barrière est donc une ligne que vous écrivez et un jugement que vous portez :

library(metatools)

# The programmatic gate: zero off-codelist values before the metadata advances
length(get_bad_ct(adsl, adsl_fixed, "AGEGR1")) == 0
[1] TRUE

TRUE. Le contrôle a fait ressortir l’erreur de l’IA ; un humain l’a lue, a corrigé la liste de codes et a confirmé que la barrière est au vert avant que les métadonnées n’alimentent quoi que ce soit. Cette division est tout l’enjeu de la série. L’IA a rédigé la spécification vite — du temps réellement gagné sur des tables répétitives et bien balisées. Mais elle a produit une liste de codes plausible-et-fausse et une spécification qui a supprimé une variable, et metatools plus une personne ont attrapé les deux. Le programmeur est maître des métadonnées et de la validation qui le prouve ; l’IA change la vitesse du premier brouillon, jamais la responsabilité — et, pour être exact sur la frontière une dernière fois, la spécification metacore est vérifiée et traçable dans R, mais le define.xml lui-même est généré par Pinnacle 21 ou defineR, pas par ce code.

🟢 Avec un agent IA

Demandez à Prova « Un copilote IA a rédigé mes métadonnées ADaM sous forme de tables metacore — comment valider le brouillon avec metatools pour qu’une liste de codes hallucinée ou une variable supprimée ne puisse pas atteindre un Define-XML ? » — elle répond en s’appuyant sur les leçons de ce pilier, avec du code pharmaverse exécutable (check_ct_data(), get_bad_ct(), check_variables()) que vous pouvez essayer sur des données d’exemple. The runtime is the judge. Demandez à Prova →

Problèmes fréquents

select_dataset() échoue avec `derivation_id` not found (ou une erreur de colonne « core »). Chaque table metacore doit porter son ensemble complet de colonnes attendues, même quand certaines colonnes sont entièrement NA. Si value_spec omet derivation_id, ou ds_vars omet core, metacore() affiche un avertissement « incorrect column names » et l’appel select_dataset()/metatools ultérieur échoue. Construisez chaque table avec son ensemble complet de colonnes (ds_vars : dataset, variable, key_seq, order, mandatory, core, supp_flag ; value_spec : dataset, variable, code_id, type, origin, derivation_id, where, sig_dig) et remplissez de NA ce que vous n’avez pas.

Utiliser keep au lieu de mandatory dans ds_vars. keep est le nom déprécié ; le metacore actuel attend mandatory (un logique). Utilisez mandatory, et donnez à core l’un des mots acceptés — Required, Expected ou Permissible — sinon la construction avertit.

Assigner des codes à codelist$codes avec la mauvaise forme. codes est une colonne-liste. Pour une liste de codes type = "permitted_val", chaque élément est un simple vecteur de caractères (c("18-64", ">64")) ; pour une liste de codes type = "code_decode", chaque élément est un tibble à deux colonnes de paires code/decode. Assignez avec codelist$codes[i] <- list(...), pas codelist$codes[i] <- c(...).

Traiter un contrôle réussi comme la barrière. check_ct_data() et check_variables() avertissent par défaut — ils n’empêchent pas une mauvaise spécification d’avancer. La vraie barrière est une assertion explicite dont vous êtes maître, p. ex. length(get_bad_ct(data, mc, "AGEGR1")) == 0, ou check_variables(..., strict = TRUE) pour transformer une discordance en erreur bloquante. Le contrôle fait ressortir le problème ; c’est vous qui décidez si les métadonnées passent.

Questions fréquentes

Non — elle rédige les métadonnées, pas le fichier. Un copilote IA peut rédiger les tables de spécification metacore (labels, types, listes de codes) à partir desquelles un Define-XML est généré, bien plus vite que vous ne les tapez. Mais générer le fichier define.xml est une étape distincte réalisée par Pinnacle 21 ou le package open source defineR, piloté depuis une feuille de calcul de métadonnées. metacore et metatools lisent et vérifient les métadonnées ; ils n’écrivent jamais le define.xml.

Oui — c’est exactement à cela qu’il sert. check_ct_data() compare les valeurs de chaque colonne de terminologie contrôlée à la liste de codes que votre spécification déclare et avertit sur toute valeur non permise ; get_bad_ct(data, metacore, "AGEGR1") renvoie les valeurs fautives sous forme de vecteur de caractères (ou character(0) quand la colonne est propre). Dans cette leçon, il a attrapé une liste de codes de l’IA <65 / 65-80 / >80 face à des données qui utilisaient en fait 18-64 / >64.

Non. metacore détient les métadonnées en mémoire — il lit un define.xml (ou un tableur de spécification) en tables structurées, et vous pouvez construire ces tables directement, comme ici. Il ne génère pas de define.xml, et metatools ou xportr non plus. Générer le fichier, c’est Pinnacle 21 ou defineR. Soyez précis sur la frontière : metacore, ce sont les métadonnées ; le define.xml en est généré par un autre outillage.

Seulement après qu’elles ont été validées et prises en charge par un programmeur qualifié — le même critère que pour tout code ou spécification. Un brouillon d’IA est non qualifié : un Define-XML est un livrable de soumission, donc les métadonnées doivent franchir les mêmes contrôles de conformité qu’une spécification écrite à la main (check_ct_data(), check_variables(), revue face aux données et à l’analyse) avant d’alimenter un define.xml. L’IA change la vitesse à laquelle vous obtenez un premier brouillon, non qui en est responsable.

Rédiger les métadonnées signifie écrire la spécification — les tables metacore qui décrivent chaque jeu de données, variable, liste de codes et dérivation. Générer le define.xml signifie transformer une spécification terminée en le fichier define.xml qu’un relecteur ouvre, ce que Pinnacle 21 ou defineR fait depuis une feuille de calcul de métadonnées. Un copilote IA aide pour la première (rédiger la spécification, puis la valider) ; la seconde est une étape d’outillage déterministe. Les garder séparées, c’est ce qui garde la frontière — et les affirmations — honnêtes.

Testez vos connaissances

Un copilote IA rédige la liste de codes SEX pour ADSL comme c("Male", "Female"), mais les données codent le sexe en M et F.

  1. En prose : nommez le contrôle qui attrape cela et dites ce que get_bad_ct(adsl, adsl_mc, "SEX") renvoie avant et après que vous ayez corrigé la liste de codes.
  2. En R : en partant des objets de la leçon, réglez la liste de codes SEX sur le mauvais c("Male", "Female"), reconstruisez les métadonnées, et confirmez que check_ct_data() signale SEX et que get_bad_ct() renvoie les deux mauvaises valeurs.

Le balayage de terminologie contrôlée est check_ct_data(data, metacore) ; l’accesseur des valeurs-en-données est get_bad_ct(data, metacore, "SEX"). Une liste de codes Male/Female ne permet ni M ni F, donc chaque valeur SEX est hors liste de codes — get_bad_ct() renvoie "M" "F" jusqu’à ce que vous aligniez la liste de codes sur c("M", "F"), après quoi il renvoie character(0).

Le contrôle est check_ct_data(), et get_bad_ct(adsl, adsl_mc, "SEX") renvoie "M" "F" pour la mauvaise liste de codes (les deux valeurs réelles sont absentes de Male/Female), puis character(0) une fois que la liste de codes est c("M", "F").

library(metacore)
library(metatools)

# Break the SEX codelist the way the AI did
codelist$codes[codelist$code_id == "CL.SEX"] <- list(c("Male", "Female"))

mc_bad   <- metacore(ds_spec, ds_vars, var_spec, value_spec,
                     derivations = derivations, codelist = codelist, verbose = "silent")
adsl_bad <- select_dataset(mc_bad, "ADSL", verbose = "silent")

check_ct_data(adsl, adsl_bad)             # warns: SEX values not permitted
get_bad_ct(adsl, adsl_bad, "SEX")         # "M" "F"

# Fix it
codelist$codes[codelist$code_id == "CL.SEX"] <- list(c("M", "F"))
mc_ok   <- metacore(ds_spec, ds_vars, var_spec, value_spec,
                    derivations = derivations, codelist = codelist, verbose = "silent")
adsl_ok <- select_dataset(mc_ok, "ADSL", verbose = "silent")
get_bad_ct(adsl, adsl_ok, "SEX")          # character(0)

Le patron est identique à la prise AGEGR1 : la liste de codes de l’IA était plausible et fausse, et un contrôle d’une ligne a fait la différence.

A. Des métadonnées valides — elles se sont construites proprement et les tables ont l’air correctes. B. Un brouillon non qualifié — tant qu’elles ne sont pas vérifiées face aux vraies données (check_ct_data(), check_variables()) et relues, une construction propre ne dit rien sur la concordance des listes de codes avec l’étude. C. Prêtes à générer un define.xml, puisque metacore détient une spécification complète.

B. Une construction metacore() propre signifie que les tables sont structurellement cohérentes — rien sur la concordance de la liste de codes AGEGR1 avec les données (le brouillon de cette leçon s’est bien construit et a utilisé les mauvaises tranches d’âge). A confond « s’assemble » et « est conforme ». C exagère la frontière : metacore détient la spécification, mais un define.xml est généré par Pinnacle 21 ou defineR, et seulement après que les métadonnées ont été validées.

Conclusion

Un copilote IA est un véritable accélérateur pour les métadonnées de soumission : il transforme une description en langage courant d’un jeu de données ADaM en les tables de spécification metacore à partir desquelles un Define-XML est généré, en quelques secondes, et cet échafaudage est la partie répétitive que vous alliez taper de toute façon. Mais le brouillon arrive non qualifié, et cette leçon a montré pourquoi le mot compte — une liste de codes AGEGR1 assurée et soignée de <65 / 65-80 / >80 qui ne correspondait pas à une étude utilisant 18-64 / >64, attrapée non par la lecture de la spécification mais par un check_ct_data() d’une ligne, plus une variable supprimée que check_variables() a fait ressortir. metacore et metatools lisent et vérifient les métadonnées ; ils n’écrivent jamais le define.xml. L’IA rédige la spécification vite ; vous êtes maître des listes de codes, de la conformité, et de la barrière qui dit que les métadonnées sont correctes. L’IA change la vitesse du premier brouillon. Elle ne change rien à qui répond du résultat. The runtime is the judge.

Note

Cette leçon est reproductible : la spécification metacore rédigée par l’IA, le contrôle de terminologie contrôlée qui attrape sa liste de codes hallucinée, la liste de codes corrigée et le contrôle de conformité des variables se reproduisent tous ici sur des données pharmaverse publiques. Copiez n’importe quel bloc et exécutez-le pour les reproduire. L’étape de rédaction par l’IA se produit dans votre propre outillage ; le R qui valide le brouillon est réel et s’exécute. The runtime is the judge.

Références

  • CDISC Define-XML — le standard : les métadonnées de soumission lisibles par machine qu’alimente la spécification metacore.
  • metacore — CRAN — modélise les métadonnées d’un define sous forme de tables soignées (ds_spec, ds_vars, var_spec, value_spec, codelist, derivations) ; le constructeur metacore() et select_dataset() utilisés ici.
  • metatools — CRAN et sa documentation — vérifie les données face à une spécification metacore : check_ct_data(), get_bad_ct(), check_variables().
  • Pinnacle 21 Define-XML 2.1 support et defineR — CRAN — les outils qui génèrent réellement un define.xml à partir d’une spécification de métadonnées ; metacore/metatools, non.

Leçons connexes

Cette page vous a-t-elle été utile ?

Recevez les nouvelles leçons R & Python par e-mail

Pratique, reproductible, sans spam. Désinscription à tout moment.

Double opt-in. Nous ne partageons jamais votre e-mail.

Partager cette pageXLinkedInRedditHN

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {Métadonnées Define-XML avec l’IA en R : rédiger, valider},
  date = {2026-07-02},
  url = {https://www.datanovia.com/learn/pharma-clinical/08-agentic-clinical-programming/ai-generates-define-xml-metadata},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“Métadonnées Define-XML avec l’IA en R : rédiger, valider.” 2026. July 2. https://www.datanovia.com/learn/pharma-clinical/08-agentic-clinical-programming/ai-generates-define-xml-metadata.