Exemple complet d’analyse de survie en R : Kaplan-Meier, log-rank, Cox — de A à Z
Un projet de bout en bout sur les données de cancer du poumon — poser la question, préparer les données, estimer les courbes de Kaplan-Meier et les médianes, exécuter le test du log-rank, ajuster et interpréter un modèle de Cox, vérifier les risques proportionnels, et rédiger le rapport prêt à publier
Une analyse de survie complète et détaillée en R de A à Z sur le jeu de données de cancer du poumon NCCTG. Posez la question et construisez la réponse Surv(), estimez les courbes de survie de Kaplan-Meier et la survie médiane selon le sexe, comparez les groupes avec le test du log-rank, ajustez des modèles de Cox univariés et multivariés à risques proportionnels et interprétez les hazard ratios, validez l’hypothèse des risques proportionnels avec cox.zph et ggcoxzph, et assemblez la figure prête à publier et le paragraphe de rapport — chaque étape reliée à la leçon qui l’enseigne.
Date de publication
26 juin 2026
Modifié
7 juillet 2026
AstucePoints clés
Ce capstone exécute une analyse de survie complète de bout en bout sur les données de cancer du poumon NCCTG — la séquence exacte que vous suivriez sur votre propre étude de temps jusqu’à l’événement, chaque étape étant reliée à la leçon qui l’enseigne en profondeur.
Le déroulé : poser la question → préparer les données (Surv) → courbes de Kaplan-Meier + survie médiane → test du log-rank → modèle de Cox (hazard ratios) → vérifier les risques proportionnels → rapporter.
Le résultat sur lung : survie médiane de 270 jours (hommes) vs 426 jours (femmes) ; le test du log-rank confirme l’écart (χ²(1) = 10.3, p = 0.001) ; un modèle de Cox multivarié donne HR ≈ 0.58 pour le sexe féminin (un risque inférieur de 42 %) et HR ≈ 1.59 pour le score ECOG (un risque supérieur de 59 % par point), l’âge disparaissant après ajustement.
L’hypothèse des risques proportionnels tient pour le modèle final (cox.zph GLOBAL p = 0.22), donc les hazard ratios sont fiables.
Deux packages font tout : survival (les modèles et les tests) et survminer (les figures prêtes à publier ggsurvplot, ggforest et ggcoxzph).
Introduction
Vous avez appris les éléments — courbes de Kaplan-Meier, le test du log-rank, le modèle de Cox, les diagnostics PH. Cette leçon est le projet qui les réunit : une analyse de survie unique et complète, des données brutes à un paragraphe que vous pourriez coller dans un article.
Nous répondrons à une question clinique sur les données de cancer du poumon NCCTG — quels facteurs liés au patient modifient le risque de décès, et de combien les femmes survivent-elles plus longtemps que les hommes ? — en parcourant le déroulé complet :
Poser la question et préparer les données — construire la réponse Surv(time, status).
Estimer la survie avec les courbes de Kaplan-Meier ; lire la survie médiane et son IC à 95 %.
Comparer les sexes avec le test du log-rank.
Modéliser l’effet de plusieurs covariables à la fois avec la régression de Cox — hazard ratios avec IC.
Valider le modèle : tester l’hypothèse des risques proportionnels.
Rapporter — la figure de publication et le paragraphe de synthèse.
Chaque étape est volontairement concise : la profondeur pédagogique vit dans les leçons reliées. Ici, vous les voyez fonctionner ensemble sur un même jeu de données jusqu’à un résultat fini. Deux packages portent toute l’analyse — survival (modèles et tests) et survminer (les figures).
Étape 1 — Poser la question et préparer les données
La question. Chez 228 patients atteints d’un cancer du poumon avancé, la survie diffère-t-elle selon le sexe, et quels facteurs cliniques (âge, statut de performance, perte de poids) augmentent ou diminuent le risque de décès ? L’issue est le temps jusqu’au décès, avec une censure pour les patients encore en vie au dernier suivi — exactement le cadre pour lequel l’analyse de survie est conçue.
Les données. Nous utilisons lung, le jeu de données fourni avec le package survival. Il s’attache automatiquement, donc vous référencez lung directement — aucun appel à data() n’est nécessaire (voir préparer les données de survie pour la liste complète de préparation des données) :
Il y a 165 décès parmi 228 patients (le reste censuré), et une poignée de valeurs de covariables manquantes — à noter dès maintenant, car un modèle de Cox utilise les cas complets et écartera discrètement ces lignes.
Construire la réponse Surv()
Tout modèle de survie prend une paire temps–événement du côté gauche, construite avec Surv(time, status). Un + après un temps marque un patient censuré (en vie lors de la dernière observation) :
306 et 455 sont des décès ; 1010+ est censuré — ce patient était en vie à 1010 jours, donc nous savons seulement que sa survie dépasse 1010 jours. Cet objet est la réponse pour tout ce qui suit.
Étape 2 — Estimer la survie : Kaplan-Meier
Estimez les courbes de survie avec survfit(), globalement et selon le sexe. La sortie imprimée donne le résumé phare — la survie médiane et son IC à 95 % par groupe (la profondeur est dans l’estimation de Kaplan-Meier et survie médiane et IC) :
library(survival)# Overall, then by sexsurvfit(Surv(time, status) ~1, data = lung)
Call: survfit(formula = Surv(time, status) ~ 1, data = lung)
n events median 0.95LCL 0.95UCL
[1,] 228 165 310 285 363
fit <-survfit(Surv(time, status) ~ sex, data = lung)fit
Call: survfit(formula = Surv(time, status) ~ sex, data = lung)
n events median 0.95LCL 0.95UCL
sex=1 138 112 270 212 310
sex=2 90 53 426 348 550
Lisez-le : la survie médiane globale est de 310 jours. Décomposée selon le sexe, la survie médiane est de 270 jours pour les hommes (sex = 1) et de 426 jours pour les femmes (sex = 2) — les femmes survivent nettement plus longtemps. Les IC à 95 % (212–310 pour les hommes, 348–550 pour les femmes) se chevauchent à peine, suggérant une vraie différence que nous testerons à l’étape 3.
La figure de publication : ggsurvplot()
Les nombres sont précis, mais la survie se lit sur la courbe. Le ggsurvplot() de survminer trace les courbes de Kaplan-Meier avec tout ce qu’un relecteur attend — les bandes de confiance, la table des sujets à risque, les lignes de médiane et la p-value du log-rank — sur un seul panneau (le guide de mise en forme complet est dans courbes de survie prêtes à publier) :
library(survival)library(survminer)fit <-survfit(Surv(time, status) ~ sex, data = lung)ggsurvplot( fit,data = lung,risk.table =TRUE, # number at risk under the plotconf.int =TRUE, # 95% confidence bandspval =TRUE, # log-rank p-value, on the plotsurv.median.line ="hv", # dashed median-survival guidespalette ="jco", # colourblind-safe journal palettelegend.labs =c("Male", "Female"),legend.title ="Sex",xlab ="Time (days)",ylab ="Survival probability",ggtheme =theme_minimal())
La courbe des femmes se situe au-dessus de celle des hommes à chaque instant ; les lignes de médiane en pointillés rencontrent l’axe des x à 270 et 426 jours ; le log-rank p = 0.0013 sur le panneau annonce déjà l’étape 3. La table des sujets à risque montre combien peu de patients restent tard dans le suivi — c’est pourquoi les bandes s’évasent à la queue.
Étape 3 — Comparer les groupes : le test du log-rank
Le graphique suggère que les femmes survivent plus longtemps ; le test du log-rank décide si l’écart est réel. Exécutez-le avec survdiff(), même formule que survfit() (leçon complète : test du log-rank) :
library(survival)survdiff(Surv(time, status) ~ sex, data = lung)
Call:
survdiff(formula = Surv(time, status) ~ sex, data = lung)
N Observed Expected (O-E)^2/E (O-E)^2/V
sex=1 138 112 91.6 4.55 10.3
sex=2 90 53 73.4 5.68 10.3
Chisq= 10.3 on 1 degrees of freedom, p= 0.001
Lisez-le : les hommes ont eu 112 décès observés vs 91.6 attendus (plus que prévu), les femmes 53 vs 73.4 (moins) — cet écart est le signal. Il s’accumule en χ² = 10.3 à 1 df, p = 0.001. Comme p < 0.05, nous rejetons l’hypothèse nulle d’égalité de survie : les femmes survivent significativement plus longtemps que les hommes. Le test du log-rank donne la p-value mais aucune taille d’effet — pour savoir de combien le risque diffère, et pour ajuster sur d’autres facteurs, nous passons au modèle de Cox.
Étape 4 — Modéliser les covariables : risques proportionnels de Cox
Le modèle de Cox gère les prédicteurs continus et catégoriels et ajuste chaque effet sur les autres, renvoyant un hazard ratio (HR) par facteur (leçon complète : risques proportionnels de Cox). Rappel : HR < 1 = risque inférieur (meilleure survie), HR > 1 = risque supérieur (pire), HR = 1 ou un IC traversant 1 = aucun effet convaincant.
Examiner les covariables une à une (univarié)
Commencez par ajuster un modèle de Cox univarié pour chaque covariable candidate et tabuler les HR — un dépistage rapide des facteurs qui comptent :
Ce que cela nous indique :sex, ph.ecog, ph.karno, et (de justesse) age portent des effets univariés significatifs ; wt.loss non (p = 0.83). ph.ecog (HR ≈ 1.6) et age (HR ≈ 1.02) augmentent le risque ; sex (HR ≈ 0.59) et ph.karno (HR ≈ 0.98) le diminuent. Mais les effets univariés peuvent être confondus — ph.ecog et ph.karno sont deux vues du même statut de performance — donc le vrai test est de les ajuster ensemble.
Les ajuster ensemble (multivarié)
Ajustez les covariables cliniquement pertinentes en une fois, de sorte que chaque effet soit ajusté sur les autres :
library(survival)res.full <-coxph(Surv(time, status) ~ age + sex + ph.ecog + ph.karno + wt.loss, data = lung)summary(res.full)
Call:
coxph(formula = Surv(time, status) ~ age + sex + ph.ecog + ph.karno +
wt.loss, data = lung)
n= 213, number of events= 151
(15 observations effacées parce que manquantes)
coef exp(coef) se(coef) z Pr(>|z|)
age 0.015157 1.015273 0.009763 1.553 0.120538
sex -0.631422 0.531835 0.177134 -3.565 0.000364 ***
ph.ecog 0.740204 2.096364 0.191332 3.869 0.000109 ***
ph.karno 0.015251 1.015368 0.009797 1.557 0.119553
wt.loss -0.009298 0.990745 0.006699 -1.388 0.165168
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
exp(coef) exp(-coef) lower .95 upper .95
age 1.0153 0.9850 0.9960 1.0349
sex 0.5318 1.8803 0.3758 0.7526
ph.ecog 2.0964 0.4770 1.4408 3.0502
ph.karno 1.0154 0.9849 0.9961 1.0351
wt.loss 0.9907 1.0093 0.9778 1.0038
Concordance= 0.64 (se = 0.026 )
Likelihood ratio test= 33.53 on 5 df, p=3e-06
Wald test = 32.27 on 5 df, p=5e-06
Score (logrank) test = 32.83 on 5 df, p=4e-06
Interprétez la sortie ajustée : seuls sex (HR = 0.53, p = 0.0004) et ph.ecog (HR = 2.10, p = 0.0001) survivent à l’ajustement. age, ph.karno et wt.loss deviennent tous non significatifs (leurs IC traversent 1) — une fois connus le sexe et le score ECOG d’un patient, ils apportent peu. Notez aussi n = 213, et non 228 : coxph() a écarté 15 patients avec une covariable manquante (analyse en cas complets). Un modèle plus léger est à la fois plus simple et évite de perdre des lignes à cause des données manquantes de wt.loss — la façon formelle de le choisir est construction et sélection d’un modèle de Cox. Ici, nous gardons les deux facteurs forts et cliniquement interprétables plus age, et nous retenons age + sex + ph.ecog comme modèle final.
library(survival)res.cox <-coxph(Surv(time, status) ~ age + sex + ph.ecog, data = lung)summary(res.cox)
Call:
coxph(formula = Surv(time, status) ~ age + sex + ph.ecog, data = lung)
n= 227, number of events= 164
(1 observation effacée parce que manquante)
coef exp(coef) se(coef) z Pr(>|z|)
age 0.011067 1.011128 0.009267 1.194 0.232416
sex -0.552612 0.575445 0.167739 -3.294 0.000986 ***
ph.ecog 0.463728 1.589991 0.113577 4.083 4.45e-05 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
exp(coef) exp(-coef) lower .95 upper .95
age 1.0111 0.9890 0.9929 1.0297
sex 0.5754 1.7378 0.4142 0.7994
ph.ecog 1.5900 0.6289 1.2727 1.9864
Concordance= 0.637 (se = 0.025 )
Likelihood ratio test= 30.5 on 3 df, p=1e-06
Wald test = 29.93 on 3 df, p=1e-06
Score (logrank) test = 30.5 on 3 df, p=1e-06
Le modèle final en langage clair :
sex : HR = 0.58, IC à 95 % 0.41–0.80, p = 0.001. À âge et score ECOG constants, être une femme réduit le risque de décès d’environ 42 % — le signal le plus fort et le plus robuste.
ph.ecog : HR = 1.59, IC à 95 % 1.27–1.99, p < 0.001. Chaque aggravation d’un point du score de performance augmente le risque d’environ 59 % — un facteur de mauvais pronostic marqué.
age : HR = 1.01, IC à 95 % 0.99–1.03, p = 0.23. Après ajustement, l’âge n’est pas significatif (l’IC inclut 1) ; son effet univarié était expliqué par les autres covariables.
Le forest plot : ggforest()
La figure de Cox emblématique montre le HR, l’IC et la p-value de chaque covariable sur un seul panneau, avec la ligne de référence à HR = 1 — à gauche c’est protecteur, à droite c’est délétère :
library(survival)library(survminer)res.cox <-coxph(Surv(time, status) ~ age + sex + ph.ecog, data = lung)ggforest(res.cox, data = lung)
En un coup d’œil : sex nettement à gauche de la ligne (protecteur), ph.ecog à droite (délétère), age à cheval dessus (aucun effet net) — exactement ce que disaient les nombres.
Étape 5 — Valider le modèle : risques proportionnels
Chaque hazard ratio ci-dessus suppose que l’effet est constant dans le temps — l’hypothèse des risques proportionnels (PH). Avant de faire confiance aux HR, testez-la avec cox.zph() (résidus de Schoenfeld mis à l’échelle), qui donne un test par covariable et un test GLOBAL (leçon complète : tester les hypothèses PH) :
library(survival)res.cox <-coxph(Surv(time, status) ~ age + sex + ph.ecog, data = lung)test.ph <-cox.zph(res.cox)test.ph
chisq df p
age 0.188 1 0.66
sex 2.305 1 0.13
ph.ecog 2.054 1 0.15
GLOBAL 4.464 3 0.22
Lisez-le : la règle de décision est p ≥ 0.05 → PH tient, p < 0.05 → PH violée. Chaque test par covariable est non significatif (age p = 0.66, sex p = 0.13, ECOG p = 0.15) et le test GLOBAL est p = 0.22 (χ² = 4.46 à 3 df). L’hypothèse est soutenue — les hazard ratios peuvent être lus comme constants dans le temps.
NotePourquoi le modèle plus léger se valide aussi plus proprement
Le modèle complet à cinq covariables de l’étape 4 était presque correct, mais cox.zph() a signalé ph.karno avec p = 0.03 — une légère violation de PH. Écarter les covariables redondantes et non significatives n’a pas seulement simplifié le modèle ; cela a supprimé la seule variable dont l’effet dérivait dans le temps. Un modèle parcimonieux est souvent un modèle mieux comporté.
Voyez-le sur le graphique ggcoxzph() — une ligne de lissage plate dans chaque panneau signifie aucune tendance temporelle :
library(survival)library(survminer)res.cox <-coxph(Surv(time, status) ~ age + sex + ph.ecog, data = lung)test.ph <-cox.zph(res.cox)ggcoxzph(test.ph)
Les trois splines sont essentiellement plats et restent à l’intérieur de la bande — aucune tendance systématique avec le temps, en accord avec les p-values non significatives de cox.zph(). Comme vérification finale, les observations influentes (ggcoxdiagnostics(), dfbeta) montrent qu’aucun patient unique ne déforme l’ajustement :
library(survival)library(survminer)res.cox <-coxph(Surv(time, status) ~ age + sex + ph.ecog, data = lung)ggcoxdiagnostics(res.cox, type ="dfbeta", linear.predictions =FALSE)
Une poignée de points pour age et ph.ecog sont plus grands que les autres, mais aucun n’est grand par rapport à son coefficient — aucun patient à retirer. Le modèle est validé.
Étape 6 — Rapporter
Toute l’analyse, rédigée comme elle apparaîtrait dans un article clinique :
La survie globale chez 228 patients atteints d’un cancer du poumon avancé (données NCCTG ; 165 décès) a été estimée par la méthode de Kaplan-Meier. La survie médiane était de 270 jours (IC à 95 % 212–310) pour les hommes et de 426 jours (IC à 95 % 348–550) pour les femmes, une différence statistiquement significative au test du log-rank (χ²(1) = 10.3, p = 0.001). Un modèle de Cox multivarié à risques proportionnels (n = 227, 164 événements) ajustant sur l’âge, le sexe et le score de performance ECOG a montré que le sexe féminin était associé à un risque de décès significativement plus faible (HR = 0.58, IC à 95 % 0.41–0.80, p = 0.001) et qu’un score ECOG plus élevé était associé à un risque plus élevé (HR = 1.59, IC à 95 % 1.27–1.99, p < 0.001) ; l’âge n’était pas significatif après ajustement (HR = 1.01, IC à 95 % 0.99–1.03, p = 0.23). L’hypothèse des risques proportionnels était satisfaite (résidus de Schoenfeld mis à l’échelle, GLOBAL χ²(3) = 4.46, p = 0.22), et les diagnostics d’influence n’ont révélé aucune observation indûment influente.
Ce paragraphe — médianes avec IC, résultat du log-rank, hazard ratios ajustés, et vérification de l’hypothèse — est une analyse de survie complète et défendable.
Ce que vous feriez ensuite
L’analyse lung est propre car le décès est le seul événement et PH tient. Les vraies études ajoutent souvent une subtilité — et chacune a une leçon dans cette série :
Les patients peuvent mourir d’autres causes, et non de l’événement d’intérêt → risques concurrents (incidence cumulée, le modèle de Fine-Gray) plutôt que le simple Kaplan-Meier.
Exécutez vous-même toute l’analyse — changez la variable de regroupement, ajoutez une covariable au modèle de Cox, ou remplacez le modèle final. Le bac à sable démarre au premier Run.
🟢 Avec un agent IA
Demandez à Prova« exécute une analyse de survie complète sur mes données — courbes de Kaplan-Meier avec survie médiane, un test du log-rank, un modèle de Cox avec hazard ratios, et une vérification des risques proportionnels — et rédige-moi le paragraphe de rapport » — elle répond avec du code survival + survminer que vous pouvez exécuter sur vos propres données. The runtime is the judge.Demander à Prova →
Problèmes courants
Votre modèle de Cox a « perdu » des patients — le n a diminué.coxph() utilise les cas complets : tout patient avec une valeur manquante dans n’importe quelle covariable est écarté. Le modèle complet à cinq covariables est tombé à n = 213 (15 écartés), surtout parce que wt.loss est manquant pour certains patients ; le modèle plus léger age + sex + ph.ecog a gardé n = 227. Vérifiez toujours model$n par rapport à nrow(lung), et préférez un modèle avec moins de covariables, plus complètes (ou une imputation) plutôt que d’analyser discrètement un échantillon différent.
Vous avez lu la direction du hazard ratio à l’envers. Dans lung, sex vaut 1 = homme, 2 = femme, donc le HR est femme vs homme. HR = 0.58 signifie que les femmes ont un risque inférieur (meilleure survie) — protecteur. Avec un factor, R utilise le premier niveau comme référence ; vérifiez le codage avant de qualifier un facteur de « délétère ».
Vous avez rapporté les hazard ratios sans vérifier les risques proportionnels. Un HR de Cox n’a de sens que si l’effet est constant dans le temps. Exécutez toujours cox.zph() (et regardez ggcoxzph()) : un test significatif ou un graphique de résidus en pente signifie que le HR unique est une moyenne temporelle trompeuse — corrigez-le par stratification ou un terme variant dans le temps (voir tester les hypothèses PH), ne publiez pas simplement le nombre.
Questions fréquentes
NoteComment réaliser une analyse de survie complète en R ?
Suivez cette séquence : (1) construisez la réponse avec Surv(time, status) ; (2) estimez les courbes de Kaplan-Meier avec survfit(Surv(time, status) ~ group, data) et lisez la survie médiane ; (3) comparez les groupes avec le test du log-rank, survdiff() ; (4) ajustez un modèle de Cox, coxph(), et interprétez les hazard ratios avec les IC à 95 % ; (5) vérifiez l’hypothèse des risques proportionnels avec cox.zph() et ggcoxzph() ; (6) rapportez les médianes, le résultat du log-rank, les hazard ratios ajustés et la vérification PH. Deux packages couvrent tout : survival et survminer.
NoteKaplan-Meier ou Cox — lequel faire en premier ?
Kaplan-Meier d’abord. Il décrit la survie dans chaque groupe (les courbes et la survie médiane) sans hypothèses, et le test du log-rank vous dit si les groupes diffèrent. Ajustez ensuite le modèle de Cox pour quantifier l’effet sous forme de hazard ratio, utiliser des prédicteurs continus et ajuster sur plusieurs covariables à la fois. Kaplan-Meier est descriptif ; Cox est l’étape de modélisation qui s’appuie dessus.
NoteQue contient le jeu de données lung pour l’analyse de survie ?
lung (dans le package survival) contient des données de survie sur 228 patients atteints d’un cancer du poumon avancé du North Central Cancer Treatment Group : time (suivi en jours), status (1 = censuré, 2 = décédé), sex (1 = homme, 2 = femme), age, et les covariables de statut de performance ph.ecog, ph.karno, pat.karno, meal.cal et wt.loss. Il s’attache automatiquement avec le package, donc vous référencez lung directement.
NoteComment interpréter les hazard ratios dans cette analyse ?
Un hazard ratio est un effet multiplicatif sur le risque de décès. HR = 0.58 pour le sexe féminin signifie que les femmes ont un risque inférieur de 42 % à celui des hommes ((1 − 0.58) × 100) — protecteur. HR = 1.59 pour le score ECOG signifie que chaque aggravation d’un point augmente le risque de 59 % — délétère. HR = 1.01 pour l’âge avec un IC qui inclut 1 signifie aucun effet convaincant. Lisez toujours un HR avec son intervalle de confiance à 95 % et sa p-value.
NoteQuels packages R me faut-il pour une analyse de survie complète ?
Deux. survival fait la modélisation et les tests : Surv(), survfit() (Kaplan-Meier), survdiff() (log-rank), coxph() (Cox), et cox.zph() (test PH). survminer fait les figures de qualité publication : ggsurvplot() (courbes KM avec table des sujets à risque, IC, lignes de médiane, p-value), ggforest() (forest plot des hazard ratios), et ggcoxzph() / ggcoxdiagnostics() (diagnostics du modèle). Les deux fournissent le jeu de données lung utilisé ici.
Testez vos connaissances
ImportantPratique
Exécutez-le. Dans la cellule interactive ci-dessous, étendez l’analyse : ajustez le modèle de Cox final en ajoutant wt.loss comme quatrième covariable, puis vérifiez les risques proportionnels. Remplissez le blanc. wt.loss est-il un prédicteur significatif après ajustement, et le test GLOBAL cox.zph() soutient-il toujours PH ?
Interprétez. Votre modèle de Cox rapporte, pour un indicateur de traitement, HR = 0.65 (IC à 95 % 0.48–0.88, p = 0.005), et cox.zph() donne un p GLOBAL = 0.40. En langage clair, quel est l’effet du traitement, est-il statistiquement convaincant, et pouvez-vous faire confiance au hazard ratio ?
NoteIndice
Remplissez le blanc avec wt.loss. Dans summary(), lisez l’exp(coef) de wt.loss (le HR) et sa p-value — un IC traversant 1 (ou p ≥ 0.05) signifie aucun effet convaincant. Dans cox.zph(), lisez la ligne GLOBAL : p ≥ 0.05 signifie que PH est soutenu.
NoteSolution
res.cox <-coxph(Surv(time, status) ~ age + sex + ph.ecog + wt.loss, data = lung)summary(res.cox)#> wt.loss HR ~ 0.99, p ~ 0.5 — NOT significant after adjustment (CI crosses 1);#> sex and ph.ecog remain the strong predictors. n drops to ~214 (wt.loss missingness).cox.zph(res.cox)#> GLOBAL p > 0.05 — the proportional-hazards assumption is still supported.
wt.loss n’apporte rien une fois le sexe et le score ECOG dans le modèle, et il vous coûte des lignes par données manquantes — une bonne raison de le laisser de côté. PH tient toujours globalement.
Pour la question 2 : HR = 0.65 signifie un risque de décès inférieur de 35 % dans le groupe traité ((1 − 0.65) × 100) — un effet de traitement protecteur. Il est statistiquement convaincant : l’IC à 95 % (0.48–0.88) se situe entièrement sous 1 et p = 0.005. Et comme cox.zph() GLOBAL p = 0.40 (≥ 0.05), les risques proportionnels tiennent, donc le hazard ratio unique est fiable — vous pouvez le rapporter comme un effet constant au cours du suivi.
AstuceVérification rapide
Vous exécutez une analyse de survie et constatez que les courbes de Kaplan-Meier se séparent nettement, mais le test du log-rank donne p = 0.18. Un relecteur demande le hazard ratio « pour être sûr ». Quelle est la bonne étape suivante ?
NoteAfficher la réponse
Ajustez un modèle de Cox pour obtenir le hazard ratio avec son IC à 95 % — le test du log-rank ne donne qu’une p-value, pas une taille d’effet. Mais interprétez-le honnêtement : un test du log-rank non significatif (p = 0.18) signifie qu’il n’y a pas de preuve forte que les courbes diffèrent, donc attendez-vous à ce que l’intervalle de confiance du HR de Cox traverse 1. Si les courbes se croisent nettement, le test du log-rank perd de la puissance et PH est probablement violée — vérifiez cox.zph(), et envisagez un test du log-rank pondéré ou le RMST plutôt que de forcer un HR unique.
Conclusion
Vous avez réalisé une analyse de survie complète en R de A à Z : posé la question, construit la réponse Surv(time, status), estimé les courbes de Kaplan-Meier et lu la survie médiane (270 vs 426 jours), confirmé la différence avec le test du log-rank (p = 0.001), ajusté et interprété un modèle de Cox multivarié (sexe féminin HR 0.58, ECOG HR 1.59), validé le tout par rapport à l’hypothèse des risques proportionnels (GLOBAL p = 0.22), et assemblé la figure prête à publier et le paragraphe de rapport. Cette séquence — décrire, comparer, modéliser, valider, rapporter — est la colonne vertébrale de toute étude de temps jusqu’à l’événement ; remplacez par vos propres données et les six mêmes étapes vous mènent à un résultat défendable. Quand vos données ajoutent une subtilité (événements concurrents, courbes qui se croisent, forme paramétrique), les leçons ce que vous feriez ensuite prennent le relais.
Leçons connexes
Estimation de Kaplan-Meier — estimez les courbes de survie et lisez la survie médiane, le cœur descriptif de l’étape 2. · Test du log-rank — la comparaison formelle de groupes à l’étape 3 (la p-value sur le graphique). · Risques proportionnels de Cox — ajustez et interprétez les hazard ratios, la modélisation à l’étape 4. · Tester les hypothèses PH — les diagnostics qui valident le modèle à l’étape 5. · Courbes de survie prêtes à publier — la boîte à outils complète de mise en forme ggsurvplot pour les figures.
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.
Chaque résultat de cette page a été produit par le code montré, exécuté au moment du build contre un environnement R figé — modifiez n’importe quel bloc et faites Run pour le reproduire vous-même.
@online{2026,
author = {},
title = {Exemple complet d’analyse de survie en R : Kaplan-Meier,
log-rank, Cox — de A à Z},
date = {2026-06-26},
url = {https://www.datanovia.com/learn/biostatistics/survival-analysis/capstone-lung-analysis},
langid = {fr}
}