L’IA rédige une dérivation ADTTE admiral en R

Décrivez un critère de délai jusqu’à l’événement en une phrase, laissez un copilote IA rédiger la dérivation ADTTE admiral en quelques secondes — puis exécutez le contrôle de plausibilité d’une ligne qui distingue un résultat correct d’un résultat assuré mais faux

La démo signature de la programmation agentique. Énoncez un critère de délai jusqu’à l’événement en une phrase en langage courant et un copilote IA rédige la dérivation ADTTE admiral — event_source, censor_source, derive_param_tte — en quelques secondes. Puis le vrai travail : valider le brouillon. Un contrôle de plausibilité d’une ligne attrape une dérivation assurée et exécutable dont les temps de survie sont tous négatifs, une re-dérivation indépendante confirme le correctif avec diffdf, et la population d’analyse reste une décision humaine. L’IA rédige la structure vite ; vous êtes maître de la définition du critère et de la responsabilité.

Date de publication

2 juillet 2026

Modifié

7 juillet 2026

AstucePoints clés
  • Un copilote IA transforme un critère en langage courant en une dérivation admiral en quelques secondes. L’échafaudage — event_source(), censor_source(), derive_param_tte() — est exactement le code répétitif et bien balisé qu’un assistant rédige bien.
  • Le brouillon est non qualifié. Une soumission est un livrable GxP (les réglementations qualité « bonnes pratiques » : GCP, GMP, GLP), et « le code s’est exécuté » n’a jamais été le critère pour présenter un chiffre à un régulateur.
  • La prise signature : intervertissez deux dates et la dérivation s’exécute toujours, renvoie toujours 254 lignes nettes — et 245 d’entre elles sont des temps de survie négatifs. Un contrôle de plausibilité AVAL >= 0 d’une ligne le signale instantanément ; un coup d’œil à la sortie nette, non.
  • La population d’analyse est une décision humaine. Le chronomètre du traitement existe pour les 254 sujets traités, pas pour l’ensemble des 306 inclus — l’IA rédige le choix, mais quels sujets appartiennent au critère, c’est à vous d’en décider.
  • L’IA change la vitesse, pas la responsabilité. Le code rédigé par l’IA est non qualifié jusqu’à ce qu’il franchisse les mêmes barrières de validation que celui d’un humain — l’IA change la vitesse du premier brouillon, jamais la responsabilité.

Introduction

Un statisticien vous remet un critère de délai jusqu’à l’événement en une phrase et vous demande le jeu de données d’analyse. Un copilote IA — un assistant de codage IA tel que Claude, ChatGPT ou GitHub Copilot — rédigera la dérivation admiral plus vite que vous n’ouvrez la documentation du package. C’est vraiment utile : construire un ADTTE (le jeu de données d’analyse de délai jusqu’à l’événement, une ligne par sujet) est un travail répétitif et bien balisé, et l’assistant en a vu des milliers d’exemples.

Le piège est tout aussi réel. Un critère de délai jusqu’à l’événement (TTE) est une question clinique précise encodée sous forme de structure de données — quand le chronomètre démarre, quel événement l’arrête, qu’advient-il des sujets sans événement — et une IA qui se trompe subtilement de règle de censure vous livre un jeu de données qui s’exécute proprement et qui est silencieusement absurde. Cette leçon parcourt toute la boucle : un critère en langage courant, la dérivation admiral rédigée par l’IA qu’il produit, et — tout l’enjeu de la série — la validation qui distingue un résultat correct d’un résultat assuré mais faux. C’est le complément de la carte des capacités qui ouvre cette série et de la construction ADTTE de délai jusqu’à l’événement, le tutoriel de A à Z qu’un assistant est, de fait, en train de rédiger pour vous ici. Nous travaillons sur des données d’exemple publiques du pharmaverse, de sorte que chaque ligne de validation s’exécute telle quelle.

Le critère, en une phrase

Voici le critère qu’a écrit le statisticien, en langage courant :

Délai entre la première exposition au médicament à l’étude (TRTSDT, la date de début du traitement) et le premier événement indésirable dermatologique émergent sous traitement — classe de systèmes d’organes (SOC) MedDRA (le Medical Dictionary for Regulatory Activities) "SKIN AND SUBCUTANEOUS TISSUE DISORDERS". Les sujets sans un tel événement sont censurés à leur dernière date connue en vie (LSTALVDT).

Lisez-le comme un relecteur QC, car chaque proposition est une décision que la dérivation doit encoder exactement :

  • L’origine — quand le chronomètre démarre (TRTSDT, la première exposition).
  • L’événement — ce qui arrête le chronomètre (le premier événement indésirable dermatologique émergent sous traitement).
  • La règle de censure — ce qu’il advient des sujets qui n’ont jamais l’événement (censurés à LSTALVDT).
  • La population — qui est même éligible à un chronomètre ancré sur le traitement (les sujets traités).

Un copilote IA fait correspondre cette phrase à l’API déclarative d’admiral proprement. Savoir s’il fait correspondre chaque proposition correctement est la question à laquelle répond le reste de cette leçon.

La dérivation rédigée par l’IA

Sollicité avec le critère ci-dessus et invité à « rédiger la dérivation ADTTE admiral », un assistant produit le bloc ci-dessous. La forme est de l’admiral idiomatique, et elle reflète le patron BDS de délai jusqu’à l’événement canonique — la disposition BDS (Basic Data Structure, une ligne par sujet et par paramètre) que le standard CDISC ADaM (Analysis Data Model) définit pour les critères de survie.

Trois objets sources font le travail, et il vaut la peine de nommer chacun avant que le code ne s’exécute :

  • event_source() déclare ce qui compte comme un événement — ici, un événement indésirable émergent sous traitement dans la SOC dermatologique, daté par sa date de début ASTDT. Il fixe CNSR (l’indicateur de censure) à 0.
  • censor_source() déclare ce qui compte comme une censure — la dernière date connue en vie pour les sujets sans événement. Il fixe CNSR à 1.
  • derive_param_tte() prend le jeu de données au niveau sujet plus ces sources et, par sujet, sélectionne l’événement le plus précoce (ou, à défaut, la date de censure), produisant le squelette BDS — STARTDT, ADT (la date d’analyse à laquelle le chronomètre s’arrête), CNSR, PARAMCD, PARAM. Un derive_vars_duration() final calcule AVAL (la valeur d’analyse — ici le temps de survie en jours) de STARTDT à ADT.

Le critère restreint le chronomètre aux sujets traités, donc le brouillon filtre ADSL (le jeu de données d’analyse au niveau sujet) sur les lignes ayant une date de début de traitement, et tire les événements d’ADAE (le jeu de données d’analyse des événements indésirables). Les blocs qui suivent s’appuient sur les objets adsl, base et adtte que celui-ci crée.

library(admiral)
library(pharmaverseadam)
library(dplyr)
data("adsl", package = "pharmaverseadam")
data("adae", package = "pharmaverseadam")

# Analysis population = treated subjects (a treatment start date exists)
adsl <- adsl %>%
  filter(!is.na(TRTSDT)) %>%
  select(STUDYID, USUBJID, TRTSDT, LSTALVDT, TRT01A)
adae <- adae %>%
  select(STUDYID, USUBJID, ASTDT, AEBODSYS, TRTEMFL)

# What counts as an EVENT: first treatment-emergent dermatologic AE
derm_ae <- event_source(
  dataset_name  = "adae",
  filter        = AEBODSYS == "SKIN AND SUBCUTANEOUS TISSUE DISORDERS" & TRTEMFL == "Y",
  date          = ASTDT,
  set_values_to = exprs(EVNTDESC = "First dermatologic AE", SRCDOM = "ADAE", SRCVAR = "ASTDT")
)

# What counts as CENSORING: last known alive date
lstalv <- censor_source(
  dataset_name  = "adsl",
  date          = LSTALVDT,
  set_values_to = exprs(EVNTDESC = "Last known alive", SRCDOM = "ADSL", SRCVAR = "LSTALVDT")
)

# The BDS skeleton: one row per subject, earliest event or the censor date
base <- derive_param_tte(
  dataset_adsl      = adsl,
  source_datasets   = list(adsl = adsl, adae = adae),
  start_date        = TRTSDT,
  event_conditions  = list(derm_ae),
  censor_conditions = list(lstalv),
  set_values_to     = exprs(PARAMCD = "TTDERMAE", PARAM = "Time to First Dermatologic AE")
)

# AVAL = duration from the start date to the analysis date, in days
adtte <- base %>%
  derive_vars_duration(new_var = AVAL, start_date = STARTDT, end_date = ADT, out_unit = "days")

head(adtte[, c("USUBJID", "STARTDT", "ADT", "CNSR", "AVAL")])
# A tibble: 6 × 5
  USUBJID     STARTDT    ADT         CNSR  AVAL
  <chr>       <date>     <date>     <int> <dbl>
1 01-701-1015 2014-01-02 2014-07-02     1   182
2 01-701-1023 2012-08-05 2012-08-07     0     3
3 01-701-1028 2013-07-19 2014-01-14     1   180
4 01-701-1033 2014-03-18 2014-04-14     1    28
5 01-701-1034 2014-07-01 2014-12-30     1   183
6 01-701-1047 2013-02-12 2013-04-07     1    55

La structure est correcte : une ligne par sujet, CNSR suivant la convention CDISC (0 = l’événement s’est produit, 1 = censuré), AVAL portant le temps en jours. Résumez ce qui est ressorti :

cat("Rows (one per subject):    ", nrow(adtte), "\n")
Rows (one per subject):     254 
cat("Events   (CNSR == 0):      ", sum(adtte$CNSR == 0), "\n")
Events   (CNSR == 0):       98 
cat("Censored (CNSR == 1):      ", sum(adtte$CNSR == 1), "\n")
Censored (CNSR == 1):       156 
cat("Median time to event (d):  ", median(adtte$AVAL[adtte$CNSR == 0]), "\n")
Median time to event (d):   29.5 

98 événements, 156 censurés, une médiane du temps jusqu’au premier événement dermatologique de 29.5 jours. Net, plausible, en forme de soumission. Maintenant, ne faites confiance à aucune ligne tant qu’elle n’a pas franchi la barrière.

Valider : la population est-elle cohérente ?

La validation la moins coûteuse est un contrôle de plausibilité, et le premier est arithmétique : dans un jeu de données TTE à une ligne par sujet, chaque sujet est soit un événement, soit une censure, donc les événements plus les censurés doivent égaler la population d’analyse.

N     <- nrow(adsl)
n_evt <- sum(adtte$CNSR == 0)
n_cns <- sum(adtte$CNSR == 1)

cat("Treated subjects (N):    ", N, "\n")
Treated subjects (N):     254 
cat("Events + censored:       ", n_evt + n_cns, "\n")
Events + censored:        254 
cat("Reconciles:              ", n_evt + n_cns == N, "\n")
Reconciles:               TRUE 

Cela se réconcilie — face à 254. Mais l’étude en a inclus davantage, et l’écart n’est pas un bug ; c’est une décision que l’IA a prise discrètement en votre nom. Regardez l’ensemble complet des inclus :

adsl_enrolled <- pharmaverseadam::adsl   # the full enrolled set, untouched

c(enrolled    = nrow(adsl_enrolled),
  never_dosed = sum(is.na(adsl_enrolled$TRTSDT)),
  treated     = sum(!is.na(adsl_enrolled$TRTSDT)))
   enrolled never_dosed     treated 
        306          52         254 

306 inclus, dont 52 n’ont aucune date de début de traitement — des échecs de sélection qui n’ont jamais été dosés. Un chronomètre ancré à la première exposition au médicament à l’étude n’a légitimement pas de départ pour eux, donc un critère émergent sous traitement n’a rien à mesurer. Le filter(!is.na(TRTSDT)) du brouillon a géré cela correctement, mais c’est justement le point à souligner : la population d’analyse est une décision scientifique dont le programmeur est maître, non une ligne que l’IA a le droit de trancher silencieusement. Retirez le filtre et le même code dériverait sur 306 sujets et échouerait discrètement à cette réconciliation — une dérivation « qui tourne bien » avec le mauvais dénominateur derrière chaque estimation de survie en aval. L’IA peut rédiger le choix dans un sens comme dans l’autre ; décider quels sujets appartiennent au critère, c’est à vous.

Valider : le contrôle de plausibilité qui attrape un bug assuré

Maintenant la dérivation elle-même. derive_vars_duration() prend une start_date et une end_date, et un copilote IA — comme un humain fatigué — les intervertit parfois. Voici un brouillon qui l’a fait, et c’est toute la leçon en une seule sortie : il s’exécute sans la moindre erreur ni le moindre avertissement.

# The AI-drafted duration line, with start and end dates SWAPPED
adtte_bug <- base %>%
  derive_vars_duration(new_var = AVAL, start_date = ADT, end_date = STARTDT, out_unit = "days")

# One-line plausibility gate: a survival time can never be negative
all(adtte_bug$AVAL >= 0)   # the QC red flag
[1] FALSE
sum(adtte_bug$AVAL < 0)    # how many rows are impossible
[1] 245
min(adtte_bug$AVAL)        # the worst offender, in days
[1] -197

all(adtte_bug$AVAL >= 0) renvoie FALSE. 245 des 254 lignes sont négatives, la pire un temps de survie de −197 jours — un sujet qui a eu son événement près de sept mois avant de commencer le traitement. C’est physiquement impossible, et pourtant le code l’a produit avec assurance, dans la bonne forme, sans se plaindre. Un coup d’œil à un tableau net de 254 lignes ne l’attraperait pas ; une assertion d’une ligne — le contrôle qualité (QC) réduit à son essence — l’attrape en un seul FALSE.

Corrigez l’ordre des arguments et re-dérivez :

# The corrected duration line: the clock runs from the start date to the analysis date
adtte_fix <- base %>%
  derive_vars_duration(new_var = AVAL, start_date = STARTDT, end_date = ADT, out_unit = "days")

all(adtte_fix$AVAL >= 0)                        # now TRUE
[1] TRUE
median(adtte_fix$AVAL[adtte_fix$CNSR == 0])     # median time to event, in days
[1] 29.5

TRUE, avec une médiane du temps d’événement revenue à une valeur sensée de 29.5 jours. Le bug ne s’est jamais annoncé ; la barrière de plausibilité, si. C’est tout l’argument de la série en un avant/après : s’exécuter n’est pas la même chose qu’être correct, et un contrôle peu coûteux et explicite est ce qui les distingue.

Valider : une re-dérivation indépendante avec diffdf

Un contrôle de plausibilité attrape l’impossible. Il ne confirme pas que la dérivation est juste — pour cela, la même discipline que vous appliqueriez à tout jeu de données clinique s’applique ici : la double programmation indépendante. Un second programmeur re-dérive l’ADTTE à partir de la même intention, et les deux sont comparés clé par clé avec diffdf(), le moteur de double programmation vu plus tôt dans cette série.

library(diffdf)

# An independent re-derivation from the raw pharmaverse data (using :: to avoid clobbering)
adsl2 <- pharmaverseadam::adsl %>%
  filter(!is.na(TRTSDT)) %>%
  select(STUDYID, USUBJID, TRTSDT, LSTALVDT, TRT01A)
adae2 <- pharmaverseadam::adae %>%
  select(STUDYID, USUBJID, ASTDT, AEBODSYS, TRTEMFL)

evt2 <- event_source(
  dataset_name  = "adae",
  filter        = AEBODSYS == "SKIN AND SUBCUTANEOUS TISSUE DISORDERS" & TRTEMFL == "Y",
  date          = ASTDT,
  set_values_to = exprs(EVNTDESC = "First dermatologic AE", SRCDOM = "ADAE", SRCVAR = "ASTDT")
)
cns2 <- censor_source(
  dataset_name  = "adsl",
  date          = LSTALVDT,
  set_values_to = exprs(EVNTDESC = "Last known alive", SRCDOM = "ADSL", SRCVAR = "LSTALVDT")
)
adtte2 <- derive_param_tte(
  dataset_adsl      = adsl2,
  source_datasets   = list(adsl = adsl2, adae = adae2),
  start_date        = TRTSDT,
  event_conditions  = list(evt2),
  censor_conditions = list(cns2),
  set_values_to     = exprs(PARAMCD = "TTDERMAE", PARAM = "Time to First Dermatologic AE")
) %>%
  derive_vars_duration(new_var = AVAL, start_date = STARTDT, end_date = ADT, out_unit = "days")

# The gate: compare the fixed derivation against the independent one, subject by subject
diffdf(adtte, adtte2, keys = "USUBJID")
No issues were found!

« No issues were found! » — les deux dérivations indépendantes concordent exactement. Ce n’est qu’à présent, la population décidée, le contrôle de plausibilité au vert et une re-dérivation indépendante concordante, que l’ADTTE est qualifiée. Le patron est celui de la double programmation avec diffdf : la confiance se gagne à la barrière, de la même manière que pour tout code — quel que soit l’auteur ou l’outil de rédaction.

Qui est maître de quoi

Alignez ce que l’IA a fait et ce que vous avez fait, et la division est exacte. L’assistant a rédigé la structure vite — l’échafaudage event_source() / censor_source() / derive_param_tte(), les variables BDS, l’appel admiral idiomatique. C’est du temps réellement gagné. Mais deux choses qu’il a produites étaient plausibles-et-fausses (une dérivation aux dates interverties, et une population qu’il aurait décidée silencieusement), et un humain plus une barrière QC ont attrapé les deux.

La responsabilité n’a donc jamais bougé. Vous êtes maître de la définition du critère — la règle de censure est-elle correcte, la population est-elle correcte, le chronomètre démarre-t-il là où le protocole le dit — et vous êtes maître de la validation qui prouve que la dérivation l’implémente. L’IA rédige ; le promoteur et le programmeur qualifié restent redevables de chaque valeur dérivée. Pour le dire dans l’unique phrase à laquelle cette série ne cesse de revenir : le code rédigé par l’IA est non qualifié jusqu’à ce qu’il franchisse les mêmes barrières de validation que celui d’un humain — l’IA change la vitesse du premier brouillon, jamais la responsabilité. Une soumission est un livrable GxP, et la responsabilité ne se transfère jamais à l’outil.

🟢 Avec un agent IA

Demandez à Prova « Un copilote IA a rédigé une dérivation ADTTE admiral pour un critère de délai jusqu’à l’événement — comment la mettre en QC pour qu’une date intervertie ou la mauvaise population d’analyse ne puisse pas atteindre un tableau de survie ? » — elle répond en s’appuyant sur les leçons de validation de cette série, avec les contrôles de plausibilité exécutables et la double programmation diffdf() que vous pouvez essayer sur votre propre brouillon. The runtime is the judge. Demandez à Prova →

Problèmes fréquents

« La dérivation s’est exécutée, donc l’ADTTE est bon. » C’est l’instinct le plus dangereux avec le code clinique rédigé par l’IA. Une exécution propre signifie que la syntaxe est valide — rien de plus. La dérivation aux dates interverties ci-dessus s’est exécutée parfaitement et a renvoyé 254 lignes nettes de temps négatifs impossibles. Traitez une exécution propre comme le début de la validation (contrôles de plausibilité, une re-dérivation indépendante, revue), jamais sa fin.

Dériver sur la population incluse au lieu de la population traitée. Un critère TTE ancré sur le traitement n’a aucun chronomètre pour les échecs de sélection jamais dosés. Si vous omettez filter(!is.na(TRTSDT)), le code s’exécute toujours mais events + censored n’égale plus votre population d’analyse, et chaque estimation de survie en aval porte le mauvais dénominateur. Décidez la population délibérément — c’est un choix scientifique, non un défaut que l’outil devrait faire à votre place — et réconciliez le décompte.

derive_param_tte() avertit à propos d’« enregistrements en double ». Cet avertissement est bénin : quand un sujet a plusieurs événements indésirables qualifiants, admiral garde le plus précoce (le premier événement) comme date TTE, ce qui est exactement ce que veut un critère « délai jusqu’au premier événement ». Le check_type = "warning" par défaut est correct ; ne le faites pas taire avec check_type = "none" — lisez-le, confirmez que le comportement du premier événement est celui que vous vouliez, et poursuivez.

Essayer d’appeler tte_source(). Il n’existe aucune fonction tte_source() à appeler. tte_source est la classe que event_source() et censor_source() construisent — recourez à ces deux constructeurs, pas à un tte_source() qui n’existe pas. (Fabriquer une fonction plausible mais inexistante est un dérapage classique de l’IA ; vérifiez chaque fonction au regard de la documentation du package avant de l’exécuter.)

Questions fréquentes

Comme outil de rédaction, oui — comme source de code validé, non. Un copilote IA peut rédiger une dérivation ADTTE admiral (l’échafaudage event_source() / censor_source() / derive_param_tte()) bien plus vite que vous ne la tapez, mais ce brouillon est non qualifié : un programmeur qualifié doit relire chaque ligne, et le code doit franchir les mêmes barrières que tout code franchit — contrôles de plausibilité, double programmation indépendante avec diffdf(), et revue. Utilisé ainsi, il accélère la rédaction sans affaiblir la validation.

Presque toujours une inversion de start_date / end_date dans derive_vars_duration(). Si la date d’analyse est passée comme départ et le début du traitement comme fin, AVAL est l’opposé de la vraie durée, donc un temps de survie ressort négatif — une valeur impossible que le code calcule sans se plaindre. Un contrôle de plausibilité all(AVAL >= 0) d’une ligne l’attrape immédiatement ; le correctif consiste à mettre la date de départ en premier et la date d’analyse en second.

Elle ne le devrait pas, et vous ne devriez pas le lui laisser. La population d’analyse — ici, les sujets traités avec une date de début de traitement, versus l’ensemble des sujets inclus — est une décision scientifique dont le programmeur et le statisticien sont maîtres. Un copilote IA appliquera un filtre (ou aucun) et produira un jeu de données exécutable dans un sens comme dans l’autre ; décider quels sujets appartiennent à un critère ancré sur le traitement, et réconcilier events + censored == N, est votre responsabilité, pas celle de l’outil.

CNSR est l’indicateur de censure, et la convention ADaM de CDISC est l’inverse de ce à quoi beaucoup s’attendent : CNSR = 0 signifie que l’événement s’est produit, et un entier positif (généralement 1) signifie que le sujet a été censuré (aucun événement ; suivi seulement jusqu’à une date connue). Dans admiral, event_source() fixe CNSR = 0 et censor_source() fixe CNSR = 1. Quand vous analysez les données, pensez à convertir — par exemple survival::Surv(AVAL, 1 - CNSR) — car la plupart des fonctions de survie attendent 1 = event.

Exactement comme vous validez tout code clinique — la source du brouillon est sans importance pour la barrière. Un programmeur qualifié relit et justifie chaque ligne au regard de la définition du critère, puis le code franchit les contrôles de plausibilité (AVAL >= 0, events + censored == N, CNSR dans {0, 1}, STARTDT <= ADT), une double programmation indépendante comparée avec diffdf(), et une revue. Les contrôles de plausibilité attrapent l’impossible ; la re-dérivation indépendante confirme que le résultat est juste, pas seulement exécutable.

Testez vos connaissances

Un copilote IA rédige une dérivation ADTTE et termine l’étape de durée avec derive_vars_duration(new_var = AVAL, start_date = ADT, end_date = STARTDT, out_unit = "days"). Le code s’exécute sans erreur et renvoie un tableau net à une ligne par sujet.

  1. En prose : nommez le contrôle de plausibilité d’une ligne qui attrape cela avant que cela n’atteigne une analyse de survie, et expliquez pourquoi « le code s’est exécuté » et « le tableau a l’air net » ne prouvent pas que la dérivation est correcte.
  2. En R : écrivez un minuscule exemple à deux sujets avec un STARTDT et un ADT plus tardif, calculez AVAL à la fois de la manière intervertie et de la manière correcte, et utilisez une assertion all(AVAL >= 0) pour signaler la version intervertie.

Un temps de survie est une durée d’une date antérieure vers une date postérieure, il ne peut donc jamais être négatif. La barrière la moins coûteuse est donc all(adtte$AVAL >= 0) — si elle renvoie FALSE, le chronomètre tourne à l’envers. « Le code s’est exécuté » signifie seulement que la syntaxe est valide ; la version aux dates interverties s’exécute parfaitement et est fausse pour presque chaque sujet.

Étape 1. La barrière est l’assertion de plausibilité all(adtte$AVAL >= 0). Une valeur de délai jusqu’à l’événement est une durée mesurée en avant de la date de départ vers la date d’analyse, donc un AVAL négatif est physiquement impossible — il signifie que la dérivation a soustrait dans le mauvais sens. « Le code s’est exécuté » signifie seulement que la syntaxe est valide, et « le tableau a l’air net » seulement que la forme est correcte ; ni l’un ni l’autre ne dit que les chiffres sont corrects. Le brouillon aux dates interverties produit un tableau entier de temps négatifs impossibles sans la moindre erreur.

# Two subjects, each with a start date earlier than the analysis date
df <- data.frame(
  USUBJID = c("01-001", "01-002"),
  STARTDT = as.Date(c("2014-01-02", "2014-03-10")),
  ADT     = as.Date(c("2014-07-02", "2014-04-07"))
)

# AI draft (WRONG): start and end swapped -> negative durations
df$AVAL_bug <- as.numeric(df$STARTDT - df$ADT)   # end - start, reversed
all(df$AVAL_bug >= 0)                            # FALSE -> the gate fires

# Correct: duration from the start date to the analysis date
df$AVAL_fix <- as.numeric(df$ADT - df$STARTDT)
all(df$AVAL_fix >= 0)                            # TRUE
df

Le contrôle all(AVAL >= 0) renvoie FALSE pour la version intervertie et TRUE après le correctif — une barrière d’une ligne qui transforme une erreur silencieuse et assurée en un échec immédiat et bruyant.

A. Validée — elle s’est exécutée sans erreur et le tableau a l’air correct. B. Non qualifiée — tant qu’un humain ne l’a pas relue et qu’elle n’a pas franchi les barrières de QC (contrôles de plausibilité, re-dérivation indépendante, revue), elle n’a aucun statut de validation. C. Validée, à condition que l’assistant soit un modèle actuel et performant.

B. S’exécuter proprement et avoir l’air net ne prouvent pas l’exactitude — la dérivation aux dates interverties a fait les deux et a renvoyé 254 temps de survie négatifs impossibles. La sortie d’une IA est un brouillon non qualifié quel que soit le modèle qui l’a produit (ce qui écarte C) ; elle gagne sa validation seulement par une revue humaine plus les mêmes barrières de QC que tout code doit franchir (ce qui écarte A).

Conclusion

Un copilote IA est un véritable accélérateur pour le travail admiral : il transforme un critère de délai jusqu’à l’événement en langage courant en une dérivation ADTTE idiomatique en quelques secondes, et l’échafaudage qu’il produit 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 ce mot compte — une dérivation aux dates interverties qui s’est exécutée proprement et a renvoyé un tableau entier de temps de survie négatifs impossibles, attrapée non par une lecture attentive mais par un contrôle de plausibilité AVAL >= 0 d’une ligne, puis confirmée par une re-dérivation indépendante et diffdf(). L’IA rédige la structure vite ; vous êtes maître de la définition du critère, de la population d’analyse et de la validation qui prouve que la dérivation les implémente. 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 dérivation ADTTE rédigée par l’IA, le bug aux dates interverties que son contrôle de plausibilité attrape, la dérivation corrigée, et la re-dérivation diffdf() indépendante 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.

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 = {L’IA rédige une dérivation ADTTE admiral en R},
  date = {2026-07-02},
  url = {https://www.datanovia.com/learn/pharma-clinical/08-agentic-clinical-programming/ai-drafts-admiral-adtte-from-endpoint},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“L’IA rédige une dérivation ADTTE admiral en R.” 2026. July 2. https://www.datanovia.com/learn/pharma-clinical/08-agentic-clinical-programming/ai-drafts-admiral-adtte-from-endpoint.