CDISC ADTTE en R : analyse de survie réglementaire
Faites passer un critère d’évaluation temps-jusqu’à-événement d’un jeu de données CDISC ADaM ADTTE à travers une analyse de style soumission en R — le retournement de censure CNSR, Kaplan-Meier avec médiane + IC à 95 %, le test du log-rank stratifié, le hazard ratio de Cox primaire, et un tableau gtsummary de style CSR
Analysez en R un critère d’évaluation temps-jusqu’à-événement d’un essai clinique selon les règles réglementaires. Mappez un jeu de données CDISC ADaM ADTTE vers un objet Surv() — en gérant la convention CNSR où 1 signifie censuré (l’inverse du status de R), construisez event = 1 - CNSR, puis exécutez l’ensemble d’analyse de soumission : une courbe de Kaplan-Meier avec table de risque, la survie globale médiane avec son intervalle de confiance (IC) à 95 %, le test du log-rank stratifié, le hazard ratio de Cox primaire avec IC à 95 %, une vérification des risques proportionnels, et un tableau récapitulatif de style CSR avec gtsummary — le tout encadré par la pensée estimande d’ICH E9(R1).
Date de publication
26 juin 2026
Modifié
7 juillet 2026
AstucePoints clés
Un jeu de données CDISC ADaM ADTTE est le contrat prêt pour l’analyse d’un critère d’évaluation temps-jusqu’à-événement : un enregistrement par sujet par paramètre (PARAMCD = OS, PFS, …), avec le temps dans AVAL, les unités dans AVALU, et l’indicateur de censure dans CNSR.
L’erreur n° 1 — le retournement de censure. CDISC code CNSR = 1 comme censuré et CNSR = 0 comme l’ événement — l’inverse du Surv(time, event) de R, qui attend event = 1. Construisez toujours event = 1 - CNSR avant de modéliser. Inversez ceci et chaque résultat est silencieusement faux.
Exécutez l’ensemble d’analyse de soumission sur Surv(AVAL, 1 - CNSR) : une courbe de Kaplan-Meier (table de risque + IC + lignes médianes), la médiane d’OS avec IC à 95 % par bras, le test du log-rank stratifié, et le hazard ratio de Cox avec IC à 95 % — l’estimand primaire.
Sur un essai adjuvant dans le cancer du côlon de forme CDISC, Lev+5FU a réduit le risque de décès d’environ 30 % (HR = 0.70, IC à 95 % 0.55–0.88, p = 0.003), l’hypothèse des risques proportionnels étant vérifiée (p = 0.34).
Résumez-le comme le fait un rapport d’étude clinique — un tableau gtsummary de la médiane + des probabilités de survie et un tbl_regression du HR de Cox — et encadrez-le avec la pensée estimand d’ICH E9(R1) : critère d’évaluation pré-spécifié, règles de censure, et facteurs de stratification.
Introduction
On vous a remis un jeu de données ADTTE pour un rapport d’étude clinique. Le critère d’évaluation primaire du protocole est la survie globale ; le statisticien avant vous a mappé les données brutes aux standards CDISC ADaM, et c’est maintenant à vous de produire l’analyse temps-jusqu’à-événement dont la soumission a besoin — une courbe de Kaplan-Meier, la survie médiane avec intervalles de confiance, le test du log-rank, et le hazard ratio primaire.
Si vous avez exécuté un modèle de Cox sur les données lung, vous connaissez déjà les statistiques. Ce qui change dans un cadre réglementaire, c’est le contrat de données et la rigueur qui l’entoure. Deux choses piègent les gens en premier :
La structure ADTTE — les données de survie arrivent dans une forme fixe (une ligne par sujet par paramètre) avec des noms de variables fixes. Vous ne choisissez pas les colonnes ; vous les mappez.
La convention de censure est inversée. L’indicateur CNSR de CDISC utilise 1 = censuré, alors que le Surv(time, event) de R attend event = 1 pour l’événement. Confondez-les et votre hazard ratio pointe dans le mauvais sens — une erreur silencieuse et catastrophique qu’un évaluateur repérera.
Cette leçon fait passer un jeu de données ADTTE de forme CDISC à travers une analyse de style soumission en R avec survival (le moteur), survminer (le graphique KM prêt à publier), et gtsummary (les tableaux de style CSR). C’est le pont entre « je sais ajuster un modèle de Cox » et « je sais produire une analyse temps-jusqu’à-événement prête pour soumission ».
Ce qu’est un jeu de données ADTTE — et pourquoi la structure compte
ADTTE est le standard ADaM (Analysis Data Model) pour l’analyse temps-jusqu’à-événement. La discipline qui le rend prêt pour soumission tient en une règle : un enregistrement par sujet par paramètre d’analyse. Un sujet ayant deux critères d’évaluation — survie globale (OS) et survie sans progression (PFS) — a deux lignes ADTTE, une par PARAMCD. Vous analysez un paramètre à la fois en filtrant sur PARAMCD.
Voici les variables ADTTE qui pilotent une analyse de survie :
Variable
Signification
Exemple
STUDYID
Identifiant de l’étude
COLON-ADJ-001
USUBJID
Identifiant unique de sujet
COLON-ADJ-001-0042
PARAMCD / PARAM
Code / libellé du paramètre
OS / Overall Survival
AVAL
Valeur d’analyse = temps jusqu’à l’événement ou la censure
2083
AVALU
Unité de la valeur d’analyse
DAYS
CNSR
Indicateur de censure — 0 = événement, 1 = censuré
0
EVNTDESC
Description de l’événement
Death
CNSDTDESC
Description de la date de censure
Last known alive
TRT01P
Traitement planifié (bras)
Lev+5FU
STARTDT / ADT
Origine du temps / date d’analyse
2021-03-14
La valeur d’analyse est déjà dérivée : AVAL est le temps depuis l’origine définie par le protocole (STARTDT, p. ex. la randomisation) jusqu’à la date d’analyse (ADT, la date de l’événement ou de la censure). Votre travail n’est pas de re-dériver le temps — il est de mapper correctement AVAL, CNSR, et TRT01P dans Surv() et d’exécuter l’analyse pré-spécifiée.
Construire le jeu de données ADTTE (le mapping, rendu explicite)
Les vraies données ADTTE étant confidentielles, nous dérivons ici un jeu de données ADTTE de forme CDISC à partir du jeu de données public colon livré avec le package survival — un essai de thérapie adjuvante dans le cancer du côlon. Le construire à la main est tout l’intérêt : cela vous montre le mapping exact que vous appliquerez au cas réel.
colon a deux lignes par sujet (événements de récidive et de décès, dans etype). Nous prenons les enregistrements de décès (etype == 2) comme paramètre de survie globale, et deux bras — Observation vs Lev+5FU (le régime adjuvant actif) :
library(survival)# Overall-survival records (death endpoint), two armsos <-subset(colon, etype ==2& rx %in%c("Obs", "Lev+5FU"))os$rx <-droplevels(os$rx)# Map raw trial data to a CDISC ADaM ADTTE structureadtte <-data.frame(STUDYID ="COLON-ADJ-001",USUBJID =sprintf("COLON-ADJ-001-%04d", os$id),PARAMCD ="OS",PARAM ="Overall Survival (days)",AVAL = os$time, # time to event / censoringAVALU ="DAYS",CNSR =1- os$status, # CDISC: 1 = censored, 0 = eventEVNTDESC =ifelse(os$status ==1, "Death", "Censored: alive at last follow-up"),TRT01P =factor(os$rx, levels =c("Obs", "Lev+5FU"),labels =c("Observation", "Lev+5FU")),STRAT =factor(ifelse(os$differ ==3, "Poor", "Well/Moderate")), # stratification factorstringsAsFactors =FALSE)adtte <- adtte[!is.na(adtte$STRAT), ] # drop unknown stratumhead(adtte)
STUDYID USUBJID PARAMCD PARAM AVAL AVALU
1 COLON-ADJ-001 COLON-ADJ-001-0001 OS Overall Survival (days) 1521 DAYS
2 COLON-ADJ-001 COLON-ADJ-001-0002 OS Overall Survival (days) 3087 DAYS
3 COLON-ADJ-001 COLON-ADJ-001-0003 OS Overall Survival (days) 963 DAYS
4 COLON-ADJ-001 COLON-ADJ-001-0004 OS Overall Survival (days) 293 DAYS
5 COLON-ADJ-001 COLON-ADJ-001-0005 OS Overall Survival (days) 659 DAYS
6 COLON-ADJ-001 COLON-ADJ-001-0006 OS Overall Survival (days) 1767 DAYS
CNSR EVNTDESC TRT01P STRAT
1 0 Death Lev+5FU Well/Moderate
2 1 Censored: alive at last follow-up Lev+5FU Well/Moderate
3 0 Death Observation Well/Moderate
4 0 Death Lev+5FU Well/Moderate
5 0 Death Observation Well/Moderate
6 0 Death Lev+5FU Well/Moderate
Notez le CNSR = 1 - os$status délibéré : le colon$status brut vaut 1 pour un événement, donc l’inverser donne la convention CDISC (1 = censuré). C’est la forme dans laquelle votre vrai ADTTE arrivera — maintenant vous devez le relire correctement.
library(survival)os <-subset(colon, etype ==2& rx %in%c("Obs", "Lev+5FU"))os$rx <-droplevels(os$rx)adtte <-data.frame(AVAL = os$time, CNSR =1- os$status,TRT01P =factor(os$rx, levels =c("Obs", "Lev+5FU"),labels =c("Observation", "Lev+5FU")),STRAT =factor(ifelse(os$differ ==3, "Poor", "Well/Moderate")))adtte <- adtte[!is.na(adtte$STRAT), ]# One row per subject per parameter; the censoring flag is CDISC-codedtable(arm = adtte$TRT01P)
Il y a 606 sujets (308 Observation, 298 Lev+5FU) et 287 décès ; le reste est censuré — en vie au dernier suivi.
Le retournement de censure : event = 1 - CNSR (à lire deux fois)
C’est le piège emblématique de l’analyse de survie réglementaire. L’objet réponse de R est Surv(time, event), où event = 1 marque l’événement et 0 marque la censure. Le CNSR de CDISC est l’inverse : 1 marque le censuré et 0 marque l’événement.
Passez CNSRdirectement dansSurv() et vous dites à R que chaque sujet censuré a eu l’événement et que chaque événement a été censuré. La courbe de Kaplan-Meier et la survie médiane deviennent absurdes, et le hazard ratio est silencieusement déformé — il ne se retourne pas proprement en son inverse (les temps d’événement restent rattachés aux mauvais sujets), il dérive simplement vers une valeur fausse, généralement non significative. Pire encore, il s’exécute toujours sans erreur, donc la seule défense est de faire la conversion à chaque fois et de vérifier le nombre d’événements.
library(survival)os <-subset(colon, etype ==2& rx %in%c("Obs", "Lev+5FU"))os$rx <-droplevels(os$rx)adtte <-data.frame(AVAL = os$time, CNSR =1- os$status,TRT01P =factor(os$rx, levels =c("Obs", "Lev+5FU"),labels =c("Observation", "Lev+5FU")),STRAT =factor(ifelse(os$differ ==3, "Poor", "Well/Moderate")))adtte <- adtte[!is.na(adtte$STRAT), ]# Build the R event indicator from the CDISC censoring flagadtte$event <-1- adtte$CNSR# The Surv() response — note the '+' marks CENSORED subjects (CNSR == 1)head(Surv(adtte$AVAL, adtte$event), 10)
Le + après un temps (p. ex. 1767+) marque un sujet censuré — exactement les lignes où CNSR == 1. La vérification de cohérence est passée : l’objet Surv() traite les décès comme des événements et les sujets censurés comme censurés, comme il le devrait.
L’ensemble d’analyse de soumission
Une fois Surv(AVAL, event) construit correctement, le reste est la boîte à outils temps-jusqu’à-événement standard — mais exécutée avec les critères d’évaluation et la stratification que le protocole a pré-spécifiés, non choisis post hoc.
Estimation de Kaplan-Meier et médiane d’OS avec IC à 95 %
survfit() donne la survie globale médiane et son intervalle de confiance à 95 % par bras — deux des chiffres phares de tout CSR de survie :
Call: survfit(formula = Surv(AVAL, event) ~ TRT01P, data = adtte)
n events median 0.95LCL 0.95UCL
TRT01P=Observation 308 165 2083 1548 2789
TRT01P=Lev+5FU 298 122 NA 2725 NA
Lisez les chiffres phares :
Observation : médiane d’OS = 2083 jours (IC à 95 % 1548–2789).
Lev+5FU : médiane = NA (« non atteinte ») — moins de la moitié des sujets traités sont décédés pendant le suivi, donc la courbe de survie ne descend jamais à 0.5. La borne de confiance inférieure (2725 jours) vous dit que la médiane est au moins aussi longue. Une médiane « non atteinte » est un bon signe ici, pas une donnée manquante — rapportez la borne inférieure de l’IC et une probabilité de survie à un instant fixe à la place.
La figure réglementaire emblématique — un graphique de Kaplan-Meier
La courbe de Kaplan-Meier avec une table du nombre de sujets à risque, des bandes de confiance, des lignes médianes, et la p-value du log-rank est la figure de survie standard dans une soumission. Tracez-la avec le ggsurvplot() de survminer :
La courbe Lev+5FU se situe au-dessus de la courbe Observation à chaque instant — un avantage de survie constant pour le bras actif, les courbes étant clairement séparées et ne se croisant pas.
Le test du log-rank stratifié
Les protocoles pré-spécifient couramment des facteurs de stratification (ici, la différenciation tumorale) afin que la comparaison du traitement soit faite au sein des strates pronostiques, en supprimant leur confusion. Le test du log-rank stratifié fait exactement cela — ajoutez strata() à la formule :
Call:
survdiff(formula = Surv(AVAL, event) ~ TRT01P + strata(STRAT),
data = adtte)
N Observed Expected (O-E)^2/E (O-E)^2/V
TRT01P=Observation 308 165 140 4.65 9.07
TRT01P=Lev+5FU 298 122 147 4.40 9.07
Chisq= 9.1 on 1 degrees of freedom, p= 0.003
χ² = 9.1 sur 1 df, p = 0.003 — après stratification par différenciation tumorale, la différence de survie entre les bras est statistiquement significative. (Le test non stratifié donne ici un p = 0.002 quasi identique ; ils divergent lorsque les strates sont fortement pronostiques et inégalement réparties entre les bras — pré-spécifiez la version stratifiée quand le protocole le fait.)
L’estimation primaire — le hazard ratio de Cox
Le test du log-rank répond à « les bras diffèrent-ils ? » ; la soumission réglementaire a aussi besoin d’une taille d’effet avec un intervalle de confiance — le hazard ratio, l’estimand primaire d’un critère d’évaluation temps-jusqu’à-événement. Ajustez un modèle de Cox stratifié pour que le HR corresponde à la logique du log-rank stratifié :
Call:
coxph(formula = Surv(AVAL, event) ~ TRT01P + strata(STRAT), data = adtte)
n= 606, number of events= 287
coef exp(coef) se(coef) z Pr(>|z|)
TRT01PLev+5FU -0.3581 0.6990 0.1196 -2.995 0.00274 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
exp(coef) exp(-coef) lower .95 upper .95
TRT01PLev+5FU 0.699 1.431 0.5529 0.8836
Concordance= 0.544 (se = 0.016 )
Likelihood ratio test= 9.08 on 1 df, p=0.003
Wald test = 8.97 on 1 df, p=0.003
Score (logrank) test = 9.07 on 1 df, p=0.003
Interprétez la sortie complète en langage clair :
exp(coef) = 0.70 — le hazard ratio de Lev+5FU vs Observation. Le traitement multiplie le risque de décès par 0.70, soit un risque 30 % plus faible ((1 − 0.70) × 100). Observation est le bras de référence, donc le HR se lit « traité vs contrôle » — la direction que le protocole vise.
IC à 95 % = 0.55 à 0.88. Comme l’intervalle se situe entièrement en dessous de 1, le bénéfice est statistiquement convaincant — il n’existe aucune valeur plausible où le traitement serait nuisible ou nul.
z = −3.0, Pr(>|z|) = 0.003 — le test de Wald du coefficient contre 0 : significatif.
Les tests globaux (rapport de vraisemblance, Wald, score/log-rank) donnent tous p = 0.003 — le modèle rejette « aucun effet du traitement ». La concordance (0.54) est modeste, attendue pour un seul prédicteur binaire.
Un coef négatif (−0.36) avec un HR inférieur à 1 est la direction correcte, protectrice. Si nous avions passé CNSR directement dans Surv(), le modèle se serait quand même exécuté — mais sur les mauvais sujets : le HR dérive vers une valeur déformée, non significative (≈0.9 ici, et non le vrai 0.70) et la médiane de Kaplan-Meier est gravement fausse. Il ne s’inverse pas proprement en 1/0.70 ; le danger est précisément que rien ne se plaint.
Vérifier l’hypothèse des risques proportionnels
Un hazard ratio unique n’a de sens que si l’effet du traitement est constant dans le temps — l’hypothèse des risques proportionnels. Pré-spécifiée ou non, une soumission la vérifie avec cox.zph() (résidus de Schoenfeld) :
chisq df p
TRT01P 0.912 1 0.34
GLOBAL 0.912 1 0.34
χ² = 0.91, p = 0.34 — bien au-dessus de 0.05, donc il n’y a aucune preuve que le hazard ratio du traitement change au cours du temps. Le HR unique est un résumé valide de l’effet. (Si ce test était significatif, le HR constant induirait en erreur — voir tester l’hypothèse des risques proportionnels pour les graphiques diagnostiques et les correctifs, et RMST pour un estimand qui ne suppose pas les risques proportionnels.)
Le tableau récapitulatif de style CSR — gtsummary
Un rapport d’étude clinique n’imprime pas la sortie brute de R ; il présente des tableaux propres. gtsummary transforme les mêmes objets ajustés en tableaux de style soumission sans mise en forme manuelle. D’abord, la médiane d’OS et une probabilité de survie à un instant fixe par bras :
À 5 ans, 52 % du bras Observation contre 63 % du bras Lev+5FU sont encore en vie — l’avantage de survie, maintenant sous forme d’estimation à instant fixe (utile précisément parce que la médiane des traités était « non atteinte »).
Puis l’estimand primaire — le hazard ratio de Cox — sous forme de tbl_regression :
Abbreviations: CI = Confidence Interval, HR = Hazard Ratio
exponentiate = TRUE rapporte les hazard ratios (et non les log-risques), avec l’IC à 95 % et la p-value — la ligne exacte qui va dans le tableau d’efficacité du CSR : HR 0.70 (IC à 95 % 0.55, 0.88), p = 0.003, Observation comme référence.
Le cadrage réglementaire (ICH E9, gardé pratique)
Les statistiques ci-dessus ne sont « prêtes pour soumission » que si quelques principes ont été réglés avant l’analyse. Vous n’avez pas besoin d’un manuel de conformité — vous devez savoir ce qui a été pré-spécifié et le respecter.
NoteCe qu’une soumission réglementaire attend d’une analyse temps-jusqu’à-événement
Un estimand défini (ICH E9(R1)). Énoncez précisément ce que vous estimez : la population (le Full Analysis Set / ITT), le critère d’évaluation (PARAMCD = OS, temps de la randomisation au décès toutes causes), la condition de traitement (TRT01P), la stratégie face aux événements intercurrents, et la mesure de synthèse (ici, le hazard ratio). Le HR est rapporté pour cet estimand, et non comme une association générique.
Pré-spécification. Le critère d’évaluation, la population d’analyse, les règles de censure, le test (log-rank stratifié), le modèle (Cox stratifié), et tout facteur de stratification sont fixés dans le SAP avant le verrouillage de la base de données et la levée de l’aveugle — non choisis après avoir vu les données.
Règles de censure, documentées.CNSR, EVNTDESC, et CNSDTDESC rendent le statut de chaque sujet auditable : était-ce un événement ou une censure, à quelle date et pourquoi ? Une censure informative ou incohérente biaise l’estimation, donc les règles sont écrites et suivies.
Les facteurs de stratification nommés dans le protocole entrent dans le log-rank et le Cox stratifiés (ci-dessus), pour que l’effet du traitement soit estimé au sein des strates pronostiques.
Traçabilité. Chaque chiffre se trace depuis SDTM → ADaM (ADTTE) → la sortie d’analyse, de façon reproductible.
Tout l’intérêt d’ADTTE est que les données portent ce contrat : la structure, les noms de variables, et les indicateurs sont standardisés précisément pour qu’un évaluateur de la FDA ou de l’EMA puisse ré-exécuter votre analyse et obtenir vos chiffres.
Rapport
La survie globale a été analysée sur le Full Analysis Set à partir du jeu de données ADTTE (PARAMCD = OS ; n = 606, 287 décès), comparant Lev+5FU à l’observation. La survie globale médiane était de 2083 jours (IC à 95 % 1548–2789) dans le bras observation et n’a pas été atteinte dans le bras Lev+5FU ; la survie à 5 ans était de 52 % contre 63 %. Un modèle de Cox stratifié (stratifié par différenciation tumorale, le facteur pré-spécifié) a donné un hazard ratio de 0.70 (IC à 95 % 0.55–0.88) en faveur de Lev+5FU (log-rank stratifié p = 0.003) ; l’hypothèse des risques proportionnels était satisfaite (p = 0.34).
NoteQuand vous avez besoin de tout faire auditer et valider — Arkon
Tout sur cette page constitue les statistiques d’une analyse prête pour soumission. La transformer en un véritable livrable de soumission ajoute une couche supplémentaire : une analyse validée, doublement programmée par rapport au SAP, une traçabilité complète SDTM→ADaM→TLF, versionnée et reproductible de bout en bout, avec une piste d’audit documentée qu’un régulateur peut suivre. Cette discipline de production — des pipelines d’analyse clinique reproductibles, validés et assistés par agent — est exactement ce pour quoi Arkon est conçu. Utilisez cette leçon pour faire l’analyse ; tournez-vous vers Arkon quand elle doit être auditée et validée pour un dépôt réel.
Problèmes courants
Vous avez passé CNSR directement dans Surv(). C’est l’erreur cardinale d’ADTTE. Surv(AVAL, CNSR) dit à R que les sujets censurés ont eu l’événement et inversement — les courbes s’inversent et le hazard ratio se retourne (protecteur ↔︎ nuisible), généralement sans message d’erreur. Construisez toujours event = 1 - CNSR d’abord, et vérifiez le nombre d’événements par rapport à sum(CNSR == 0).
Vous avez analysé plus d’un paramètre à la fois. ADTTE contient une ligne par sujet par PARAMCD. Si un sujet a à la fois des enregistrements OS et PFS, un survfit() non filtré agrège silencieusement deux critères d’évaluation. Faites toujours subset(adtte, PARAMCD == "OS") (ou votre paramètre) avant de construire Surv().
Vous avez utilisé la mauvaise origine du temps.AVAL est le temps depuis l’origine définie par le protocole — généralement la randomisation, parfois la première dose ou le diagnostic. Ne le re-dérivez pas à partir de dates brutes et ne mélangez pas les origines entre les sujets ; l’origine est fixée dans le SAP et déjà intégrée dans AVAL. Re-dériver le temps est une rupture de traçabilité qu’un évaluateur signalera.
Questions fréquentes
NoteQu’est-ce qu’un jeu de données CDISC ADTTE ?
ADTTE est le standard CDISC ADaM (Analysis Data Model) pour l’analyse temps-jusqu’à-événement dans les essais cliniques. Il contient un enregistrement par sujet par paramètre d’analyse (PARAMCD tel que OS ou PFS), avec le temps d’analyse dans AVAL, les unités dans AVALU, et un indicateur de censure dans CNSR. C’est le jeu de données prêt pour l’analyse, traçable, sur lequel sont exécutées les analyses de survie pour les soumissions réglementaires.
NotePourquoi CNSR=1 est-il censuré alors que le status de R utilise 1 pour l’événement ?
Ce sont simplement des conventions opposées. Le CNSR de CDISC signale la censure : CNSR = 1 signifie censuré, CNSR = 0 signifie que l’événement s’est produit. Le Surv(time, event) de R signale l’événement : event = 1 signifie l’événement, 0 signifie censuré. Pour passer de CDISC à R, construisez event = 1 - CNSR. Passez CNSR directement dans Surv() et chaque résultat est silencieusement corrompu — une erreur grave qui ne lève aucun avertissement.
NoteComment construire un objet Surv() à partir d’un jeu de données ADTTE en R ?
Filtrez sur un paramètre, convertissez l’indicateur de censure, puis appelez Surv() : adtte_os <- subset(adtte, PARAMCD == "OS"); adtte_os$event <- 1 - adtte_os$CNSR; Surv(adtte_os$AVAL, adtte_os$event). Le + après un temps marque un sujet censuré (les lignes où CNSR == 1). Cet objet Surv() est ensuite le membre de gauche de survfit(), survdiff(), et coxph().
NoteQuel est l’estimand primaire dans une analyse temps-jusqu’à-événement ?
Sous ICH E9(R1), l’estimand spécifie ce que vous estimez : la population (typiquement le Full Analysis Set / ITT), le critère d’évaluation (p. ex. la survie globale de la randomisation au décès toutes causes), la condition de traitement, la stratégie face aux événements intercurrents, et la mesure de synthèse — pour la survie, généralement le hazard ratio d’un modèle de Cox, avec le test du log-rank (stratifié) comme test d’hypothèse correspondant. Le HR est rapporté pour cet estimand, défini avant l’analyse.
NoteQuelle est la différence entre un test du log-rank stratifié et non stratifié ?
Le log-rank non stratifié compare la survie entre les bras sur tout l’échantillon. La version stratifiée les compare au sein de strates pronostiques pré-spécifiées (p. ex. différenciation tumorale, région) et combine les comparaisons intra-strates — en supprimant la confusion de ces facteurs. Utilisez le test stratifié (et un Cox stratifié correspondant) quand le protocole pré-spécifie des facteurs de stratification. Ajoutez strata() à la formule : survdiff(Surv(AVAL, event) ~ TRT01P + strata(STRAT), data = adtte).
Testez vos connaissances
ImportantPratique
Mappez-le. On vous remet un jeu de données ADTTE avec les colonnes AVAL, CNSR, et TRT01P. Écrivez le R qui construit le bon objet Surv() et un ajustement de Kaplan-Meier par bras. Quelle est la ligne unique que vous ne devez pas rater, et pourquoi ?
Interprétez. Un modèle de Cox stratifié sur un critère d’évaluation OS d’ADTTE rapporte HR = 1.35 (IC à 95 % 1.08–1.69, p = 0.009) pour le bras expérimental contre le contrôle. En langage clair : le traitement expérimental aide-t-il ou nuit-il, et le résultat est-il convaincant ? Que vérifieriez-vous en premier sur la façon dont Surv() a été construit ?
AstuceIndice
Pour (1) : la réponse est Surv(AVAL, event) — et event n’est pasCNSR. Pour (2) : un HR supérieur à 1 signifie un risque plus élevé ; un IC entièrement au-dessus de 1 est significatif. Si la direction paraît surprenante, suspectez le retournement de CNSR.
AstuceSolution
library(survival)# 1. The correct mapping — the load-bearing line is `event = 1 - CNSR`adtte$event <-1- adtte$CNSR # CDISC CNSR -> R event indicatorfit <-survfit(Surv(AVAL, event) ~ TRT01P, data = adtte)print(fit)
La ligne que vous ne devez pas rater est event = 1 - CNSR. Comme CDISC code CNSR = 1 comme censuré (l’ inverse du event = 1 de R), passer CNSR directement dans Surv() corrompt chaque résultat — les courbes et la médiane deviennent absurdes et le hazard ratio est silencieusement faux — généralement sans erreur.
Pour la question 2 : HR = 1.35 signifie un risque 35 % plus élevé de l’événement dans le bras expérimental — le traitement paraît nuisible, et non utile. Il est statistiquement convaincant : l’IC à 95 % (1.08–1.69) se situe entièrement au-dessus de 1 et p = 0.009. Mais avant de rapporter un préjudice, vérifiez comment Surv() a été construit — une direction aussi surprenante est exactement ce que produit une erreur de CNSR-non-retourné. Confirmez event = 1 - CNSR et que le nombre d’événements correspond à sum(CNSR == 0), puis ré-ajustez — ne supposez pas que le HR corrigé est simplement 1/1.35 ; avec événement et censure intervertis, la bonne valeur n’apparaît qu’une fois Surv() reconstruit correctement.
AstuceVérification rapide
Dans un jeu de données CDISC ADTTE, un sujet a AVAL = 1767 et CNSR = 1. Ce sujet a-t-il connu l’événement ?
NoteAfficher la réponse
Non — ce sujet a été censuré. CDISC code CNSR = 1 comme censuré : le sujet était sans événement (p. ex. encore en vie) à 1767 jours puis a quitté l’observation. En R, vous poseriez event = 1 - CNSR = 0, et l’ objet Surv() imprime le temps avec un + (1767+) pour marquer la censure. Seul CNSR = 0 est un événement.
Conclusion
Vous pouvez désormais faire passer un critère d’évaluation temps-jusqu’à-événement CDISC ADTTE à travers une analyse de style soumission en R : mappez AVAL, CNSR, et TRT01P vers un objet Surv() — en construisant event = 1 - CNSR pour que la convention de censure soit correcte — puis exécutez l’ensemble d’analyse que le protocole pré-spécifie : une courbe de Kaplan-Meier avec table de risque, la médiane d’OS avec IC à 95 %, le test du log-rank stratifié, le hazard ratio de Cox primaire avec son IC, une vérification des risques proportionnels, et un tableau gtsummary de style CSR. Sur l’essai adjuvant dans le cancer du côlon de forme CDISC, Lev+5FU a réduit le risque de décès d’environ 30 % (HR = 0.70, IC à 95 % 0.55–0.88, p = 0.003), les risques proportionnels étant vérifiés. Les statistiques sont la même boîte à outils de survie que vous connaissez déjà ; ce qui les rend réglementaires, c’est le contrat de données, le retournement de censure, et la pensée estimand qui les entoure.
Prouvez que vous savez le faire. Maîtrisez toute la série Analyse de survie en R — suivez votre parcours, construisez des projets et obtenez un certificat.
Demandez à Prova« mappe mon jeu de données CDISC ADTTE vers un objet Surv() — souviens-toi que CNSR=1 est censuré — puis donne-moi la médiane de Kaplan-Meier avec IC à 95 %, le test du log-rank stratifié, et le hazard ratio de Cox sous forme de tableau gtsummary » — elle répond avec du code survival + survminer + gtsummary que vous pouvez exécuter sur vos propres données. The runtime is the judge.Demander à Prova →
Note
Chaque résultat sur cette page a été produit par le code montré, exécuté au moment du build contre un environnement R figé — copiez n’importe quel bloc et exécutez-le pour les reproduire.
@online{2026,
author = {},
title = {CDISC ADTTE en R : analyse de survie réglementaire},
date = {2026-06-26},
url = {https://www.datanovia.com/learn/biostatistics/survival-analysis/cdisc-adtte-regulatory},
langid = {fr}
}