Courbe de survie de Kaplan-Meier en R : estimer et tracer
Estimez les probabilités de survie avec survfit, lisez la survie médiane et son IC à 95 %, et tracez la courbe de Kaplan-Meier signature de survminer — table des effectifs à risque, bandes de confiance et p-value du log-rank sur les données de cancer du poumon
Apprenez l’estimation de Kaplan-Meier en R avec les packages survival et survminer. Construisez l’objet Surv(time, status), estimez les courbes de survie avec survfit sur les données de cancer du poumon NCCTG, lisez la survie médiane et son intervalle de confiance à 95 %, interprétez la probabilité de survie à un instant donné, et tracez le ggsurvplot prêt à publier avec table des effectifs à risque, bandes de confiance, lignes de médiane et p-value du log-rank.
Date de publication
25 juin 2026
Modifié
11 juillet 2026
AstucePoints clés
L’estimation de Kaplan-Meier est la méthode non paramétrique de référence pour estimer et tracer une courbe de survie — la probabilité de survivre au-delà de chaque instant — à partir de données comportant de la censure (patients encore en vie, ou perdus de vue, à la fin de l’étude).
Estimez-la avec survfit(Surv(time, status) ~ group, data) ; l’affichage vous donne la survie médiane et son intervalle de confiance à 95 % par groupe.
Sur les données de cancer du poumon, la survie médiane est de 270 jours pour les hommes et de 426 jours pour les femmes — un net avantage de survie pour les femmes que le log-rank confirme (p = 0.001).
Tracez la courbe signature avec ggsurvplot() de survminer : marches de survie + table des effectifs à risque + bandes de confiance + lignes de médiane + la p-value du log-rank, le tout sur un seul panneau prêt à publier (jamais un simple plot()).
KM décrit et compare la survie entre groupes catégoriels ; pour ajuster sur des covariables ou utiliser un prédicteur continu, passez au modèle de Cox.
Introduction
Imaginez une étude sur le cancer du poumon : vous suivez des patients pendant des mois, certains décèdent durant le suivi, et d’autres sont encore en vie à la clôture de l’étude — vous n’observez jamais leur événement. Vous voulez une réponse simple et honnête à deux questions : quelle fraction de patients survit au-delà d’un instant donné, et la survie diffère-t-elle entre groupes (ici, hommes vs femmes) ?
Vous ne pouvez pas simplement faire la moyenne des durées de survie — cela jetterait chaque patient encore en vie (sa vraie durée de survie est inconnue, on sait seulement qu’elle est plus longue que ce que vous avez observé). C’est la censure, et c’est la caractéristique déterminante des données de survie. La méthode qui la gère est l’estimateur de Kaplan-Meier (KM) (Kaplan & Meier, 1958) : une estimation non paramétrique de la probabilité de survie\(S(t)\) — la probabilité de survivre au-delà de l’instant \(t\) — construite un événement à la fois.
Kaplan-Meier est le point d’entrée vers toute l’analyse de survie. Utilisez-le pour :
décrire la survie dans un seul groupe (la courbe de survie globale et la survie médiane) ;
comparer la survie entre 2 groupes catégoriels ou plus visuellement, avec le log-rank pour la p-value formelle ;
Cette leçon estime les courbes KM en R avec survival (le moteur) et survminer (graphiques de qualité publication), sur le jeu de données classique du cancer du poumon NCCTG, afin que vous puissiez reproduire exactement les chiffres et la figure.
Les données : l’étude sur le cancer du poumon NCCTG
Nous utilisons lung, le jeu de données du North Central Cancer Treatment Group fourni avec le package survival — la survie de 228 patients atteints d’un cancer du poumon avancé. Chargez le package et regardez les premières lignes (le jeu de données s’attache automatiquement avec survival, vous référencez donc lung directement — pas besoin d’appel data()) :
status — le statut de censure : 1 = censuré (en vie au dernier suivi), 2 = décédé (l’événement).
sex — 1 = homme, 2 = femme.
L’objet Surv() — la réponse
La réponse en analyse de survie n’est pas un simple nombre mais une paire durée–événement : combien de temps le patient a été observé, et si l’événement (le décès) s’est réellement produit ou si l’observation a été censurée. Vous le construisez avec Surv(time, status). R lit automatiquement status codé 1 = censuré / 2 = événement ; un + après une durée marque un patient censuré (en vie lorsqu’il a été vu pour la dernière fois) :
Lisez les premiers : 306 et 455 sont des décès ; 1010+ est censuré — ce patient était en vie à 1010 jours, on sait donc seulement que sa survie dépasse 1010 jours. Cet objet Surv() est le membre de gauche de toute formule de survie.
Estimer les courbes de survie : survfit()
Utilisez survfit() avec la réponse Surv(time, status) à gauche et la variable de groupe à droite. Ici, nous estimons la survie selon le sexe :
library(survival)fit <-survfit(Surv(time, status) ~ sex, data = lung)print(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 l’affichage, ligne par ligne :
n — les patients de chaque groupe : 138 hommes (sex=1), 90 femmes (sex=2).
events — les décès observés : 112 hommes, 53 femmes. Les autres ont été censurés.
median — le chiffre phare : la survie médiane est de 270 jours pour les hommes et de 426 jours pour les femmes. La survie médiane est l’instant où la probabilité de survie \(S(t)\) chute pour la première fois à 0.5 (la moitié du groupe est décédée) — le résumé le plus rapporté d’une courbe de survie.
0.95LCL / 0.95UCL — l’intervalle de confiance à 95 % de la médiane : 212–310 jours pour les hommes, 348–550 jours pour les femmes. Les deux intervalles se chevauchent à peine, suggérant une différence réelle — que le log-rank confirmera ci-dessous.
Les femmes survivent nettement plus longtemps que les hommes dans ces données.
Probabilité de survie à un instant donné
Une courbe de survie répond aussi à « quelle fraction est encore en vie à l’instant t ? » Passez les instants qui vous intéressent à summary() — ici, 180 et 360 jours (environ 6 et 12 mois) :
library(survival)fit <-survfit(Surv(time, status) ~ sex, data = lung)summary(fit, times =c(180, 360))
Call: survfit(formula = Surv(time, status) ~ sex, data = lung)
sex=1
time n.risk n.event survival std.err lower 95% CI upper 95% CI
180 89 49 0.644 0.0408 0.569 0.730
360 37 34 0.355 0.0437 0.279 0.452
sex=2
time n.risk n.event survival std.err lower 95% CI upper 95% CI
180 71 14 0.842 0.0387 0.770 0.922
360 33 20 0.560 0.0586 0.457 0.688
En clair : à 360 jours, la probabilité de survie estimée est de 0.36 (36 %) pour les hommes et 0.56 (56 %) pour les femmes, chacune assortie d’un intervalle de confiance à 95 % (lower 95% CI / upper 95% CI). Donc un an plus tard, environ un tiers des hommes mais plus de la moitié des femmes sont encore en vie — le même avantage de survie que les médianes montraient.
Visualiser : la courbe de Kaplan-Meier avec ggsurvplot()
Les chiffres sont précis, mais une courbe de Kaplan-Meier est la façon dont les résultats de survie se lisent. Utilisez ggsurvplot() de survminer — il trace les courbes de survie en escalier et ajoute tout ce dont un lecteur a besoin sur un seul panneau :
conf.int = TRUE — des bandes de confiance à 95 % ombrées autour de chaque courbe ;
risk.table = TRUE — le nombre de sujets à risque sous le graphique à chaque instant (pour que vous sachiez combien de données soutiennent la queue de courbe) ;
pval = TRUE — la p-value du log-rank comparant les courbes, imprimée sur le graphique ;
surv.median.line = "hv" — des repères de survie médiane en pointillés horizontaux + verticaux ;
palette = "jco" — une palette de revue adaptée au daltonisme.
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())
Comment la lire :
L’axe des y est la probabilité de survie (commence à 1.0 = tout le monde en vie) ; l’axe des x est le temps en jours. Chaque chute verticale est un décès ; chaque petite marque de tick est un patient censuré.
La courbe des femmes reste au-dessus de celle des hommes à chaque instant — une meilleure survie pour les femmes, du début à la fin.
Les lignes de médiane en pointillés rencontrent l’axe des x à 270 jours (hommes) et 426 jours (femmes) — les chiffres de survfit(), désormais sur le graphique.
La p-value du log-rank (0.0013) indique que la différence entre les courbes est statistiquement significative.
La table des effectifs à risque montre le nombre de sujets encore à risque diminuer au fil du temps — notez combien peu de patients restent dans la queue, ce qui explique pourquoi les bandes de confiance s’évasent tardivement (interprétez l’extrémité droite de toute courbe KM avec prudence).
La table de survie de Kaplan-Meier : summary(fit)
ggsurvplot() montre la courbe ; la table de survie donne l’estimation sous-jacente, étape par étape. summary(fit) renvoie, à chaque instant d’événement, le nombre de sujets à risque (n.risk), le nombre de décès (n.event), la probabilité de survie estimée (survival) et son intervalle de confiance. Elle est longue, alors regardez les premières lignes pour les hommes :
library(survival)fit <-survfit(Surv(time, status) ~ sex, data = lung)s <-summary(fit)# The first few steps of the life table (one row per event time)life_table <-data.frame(time = s$time,n.risk = s$n.risk,n.event = s$n.event,surv =round(s$surv, 3),lower =round(s$lower, 3),upper =round(s$upper, 3),group = s$strata)head(life_table, 8)
Chaque ligne est une marche de la courbe : la survie ne change qu’à un instant d’événement, chutant d’un facteur qui dépend du nombre de sujets à risque. C’est l’estimation produit-limite tracée ci-dessus — la table et la figure en sont deux vues.
Comparer les groupes formellement : le log-rank
La courbe KM suggère que les femmes survivent plus longtemps ; le log-rank décide si cet écart est réel. C’est le test non paramétrique de référence pour comparer des courbes de survie, avec H₀ = aucune différence de survie entre les groupes. Le pval = TRUE que vous avez vu sur le graphique est exactement ce test. Calculez-le directement avec survdiff() :
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
Le test donne χ² = 10.3 à 1 degré de liberté, p = 0.001 — la différence de survie entre les hommes et les femmes est statistiquement significative. Le log-rank répond à « les courbes diffèrent-elles ? » mais ne donne aucune taille d’effet et ne peut pas gérer des prédicteurs continus ni ajuster sur des facteurs de confusion — pour cela, il vous faut le modèle de Cox.
NoteDe la description à la modélisation de la survie
Décrire / comparer des groupes catégoriels → courbes de Kaplan-Meier + le log-rank (cette leçon) — une courbe de survie et une p-value.
Estimer une taille d’effet, utiliser un prédicteur continu, ou ajuster sur plusieurs covariables à la fois → le modèle de Cox à risques proportionnels — un hazard ratio par facteur.
Rapport
La survie a été estimée par la méthode de Kaplan-Meier sur les données de cancer du poumon NCCTG (n = 228, 165 décès). La survie globale médiane était de 270 jours (IC à 95 % 212–310) pour les hommes et de 426 jours (IC à 95 % 348–550) pour les femmes. La survie à un an était de 36 % (hommes) contre 56 % (femmes). La différence de survie entre les sexes était statistiquement significative (log-rank χ²(1) = 10.3, p = 0.001).
NoteLes mathématiques derrière l’estimateur de Kaplan-Meier (optionnel)
La probabilité de survie à l’instant d’événement \(t_i\) se construit récursivement à partir de la probabilité à l’instant d’événement précédent, multipliée par la probabilité conditionnelle de survivre à l’instant courant — l’estimateur produit-limite :
où \(n_i\) est le nombre de patients à risque juste avant \(t_i\), \(d_i\) est le nombre d’événements (décès) à \(t_i\), et \(S(t_0) = 1\). Comme la courbe ne change qu’à un instant d’événement, \(S(t)\) est une fonction en escalier : elle reste plate entre les événements et chute à chacun. Les patients censurés quittent l’ensemble de sujets à risque sans provoquer de chute — ils réduisent simplement \(n_i\) pour les instants ultérieurs, et c’est ainsi que Kaplan-Meier utilise l’information de chaque patient jusqu’au moment où il est perdu, au lieu de l’écarter. L’intervalle de confiance autour de \(S(t)\) provient de la formule de Greenwood pour son erreur standard.
Quelle méthode, et quand ?
AstuceChoisir votre méthode de survie
Décrire la survie dans un seul groupe (courbe, survie médiane, survie à l’instant t) → estimation de Kaplan-Meier (cette leçon).
Comparer la survie entre 2 groupes catégoriels ou plus avec une p-value → log-rank.
Modéliser l’effet d’une ou plusieurs covariables (catégorielles ou continues), ajustées les unes pour les autres, avec un hazard ratio → Cox à risques proportionnels.
Estimez les courbes vous-même — remplacez sex par une autre variable de groupe, ou changez les instants que vous résumez. Le bac à sable démarre au premier Run.
🟢 Avec un agent IA
Demandez à Prova« estime les courbes de survie de Kaplan-Meier sur mes données, donne-moi la survie médiane avec les IC à 95 %, et trace un ggsurvplot prêt à publier avec la table des effectifs à risque et la p-value du log-rank » — 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
La survie médiane vaut NA (« non atteinte »). Si moins de la moitié des patients d’un groupe subissent l’événement, la courbe de survie ne chute jamais à 0.5, donc la médiane est indéfinie — R affiche NA. C’est normal avec une censure importante ou un suivi court. Rapportez un autre quantile (p. ex. le 25e percentile via quantile(fit, probs = 0.25)) ou la probabilité de survie à un instant fixe à la place.
Vos courbes se croisent. Kaplan-Meier et le log-rank supposent que les courbes se séparent dans une direction cohérente ; des courbes qui se croisent signifient qu’un groupe fait mieux tôt et moins bien plus tard (ou l’inverse). Le log-rank perd de la puissance ici et peut manquer une différence réelle — envisagez un test pondéré (Fleming-Harrington) ou rapportez la survie à des instants précis. Des courbes qui se croisent signalent aussi que l’hypothèse des risques proportionnels d’un modèle de Cox ultérieur est probablement violée.
Vous avez oublié les ticks de censure, ou lu la queue trop littéralement. Les petites marques de tick sur la courbe sont des patients censurés, pas des événements — ne les confondez pas avec des chutes. Et comme peu de patients restent à risque tard dans le suivi (vérifiez la table des effectifs à risque), l’extrémité droite de la courbe est instable et sa bande de confiance est large ; évitez les affirmations fortes sur la survie à long terme à partir d’une queue clairsemée.
Questions fréquentes
NoteÀ quoi sert l’estimateur de Kaplan-Meier ?
Il estime la probabilité de survie au fil du temps — la probabilité de survivre au-delà de chaque instant — à partir de données comportant de la censure. Utilisez-le pour décrire la survie dans un groupe (la courbe de survie et la survie médiane), et pour comparer visuellement la survie entre groupes catégoriels, associé au log-rank pour la p-value formelle.
NoteComment lire la survie médiane sur une courbe de Kaplan-Meier ?
La survie médiane est l’instant où la probabilité de survie \(S(t)\) atteint pour la première fois 0.5 — la moitié du groupe a subi l’événement. Sur le graphique, tracez une ligne horizontale à 0.5 et lisez où elle croise chaque courbe (surv.median.line = "hv" le fait pour vous) ; en R, l’affichage de survfit() la rapporte directement avec un intervalle de confiance à 95 %.
NotePourquoi ma survie médiane vaut-elle NA ou « non atteinte » ?
Parce que moins de la moitié des patients de ce groupe ont subi l’événement, donc la courbe de survie ne chute jamais à 0.5 et la médiane est indéfinie. Cela arrive avec une censure importante ou un suivi court. Rapportez un autre quantile (p. ex. le 25e percentile) ou la probabilité de survie à un instant fixe (summary(fit, times = …)) à la place.
NoteQuelle est la différence entre la courbe de Kaplan-Meier et le log-rank ?
La courbe de Kaplan-Meierestime et affiche la survie au fil du temps pour chaque groupe ; le log-rankteste si les courbes diffèrent, renvoyant une statistique du chi-deux et une p-value. KM relève de la description ; le log-rank relève de l’inférence. Ni l’un ni l’autre ne donne de taille d’effet ni ne gère de prédicteurs continus — pour cela, utilisez le modèle de Cox.
NoteDe quels packages R ai-je besoin pour une analyse de Kaplan-Meier ?
Deux : survival pour estimer les courbes (Surv(), survfit(), survdiff()) et survminer pour tracer le graphique prêt à publier (ggsurvplot() avec la table des effectifs à risque, les bandes de confiance, les lignes de médiane et la p-value du log-rank). Tous deux fournissent le jeu de données lung utilisé ici.
Testez vos connaissances
ImportantPratique
Exécutez-le. Dans la cellule interactive ci-dessous, estimez les courbes de Kaplan-Meier pour l’échantillon global (une seule courbe, sans groupe) en remplissant le blanc par 1. Quelle est la survie médiane globale, et comment se compare-t-elle aux médianes par sexe (270 vs 426 jours) ?
Interprétez. Une analyse KM rapporte une survie médiane de NA dans le groupe traitement mais de 280 jours dans le groupe témoin. En clair, que signifie le NA, et que devriez-vous rapporter à la place ?
NoteIndice
Pour une courbe globale sans groupe, le membre de droite de la formule est 1. La colonne median de l’affichage donne la survie médiane globale ; comparez-la aux médianes par sexe.
NoteSolution
fit <-survfit(Surv(time, status) ~1, data = lung)print(fit)#> n = 228, events = 165, median = 310 (95% CI 285-363)
La survie médiane globale est de 310 jours — entre les médianes des hommes (270) et des femmes (426), comme attendu lorsqu’on regroupe les deux groupes.
Pour la question 2 : une médiane de NA (« non atteinte ») signifie que moins de la moitié des patients du groupe traitement sont décédés, donc la courbe n’a jamais chuté à 0.5 — souvent un bon signe (meilleure survie). Ne la rapportez pas comme une valeur manquante ou un zéro ; rapportez plutôt la probabilité de survie à un instant fixe, ou un quantile inférieur (p. ex. le 25e percentile), et indiquez la proportion encore sans événement à la fin du suivi.
AstuceVérification rapide
Sur une courbe de Kaplan-Meier, que représente une petite marque de tick sur une courbe de survie ?
NoteAfficher la réponse
Un patient censuré — quelqu’un qui était encore en vie (sans événement) à cet instant mais a ensuite quitté l’étude (fin de suivi ou perdu de vue). Un tick n’est pas un événement ; les événements sont les chutes verticales de la courbe. Les patients censurés réduisent le nombre de sujets à risque pour les instants ultérieurs mais ne font pas descendre la courbe d’un cran.
Conclusion
Vous savez maintenant réaliser une estimation de Kaplan-Meier en R : construire la réponse Surv(time, status), estimer les courbes de survie avec survfit(), lire la survie médiane et son IC à 95 % ainsi que la probabilité de survie à n’importe quel instant, et tracer le ggsurvplot() signature de survminer — table des effectifs à risque, bandes de confiance, lignes de médiane et p-value du log-rank sur un seul panneau prêt à publier. Sur les données de cancer du poumon, la survie médiane était de 270 jours pour les hommes contre 426 pour les femmes, une différence que le log-rank a confirmée (p = 0.001). Kaplan-Meier décrit et compare la survie entre groupes catégoriels ; lorsque vous avez besoin d’une taille d’effet, d’un prédicteur continu, ou d’un ajustement sur plusieurs facteurs à la fois, le modèle de Cox est l’étape suivante.
Leçons connexes
Log-rank — le test formel pour savoir si deux courbes KM ou plus diffèrent (la p-value sur le graphique, expliquée). · Cox à risques proportionnels — modélisez la survie sur une ou plusieurs covariables et obtenez un hazard ratio par facteur. · Qu’est-ce que l’analyse de survie ? — censure, risque et fonctions de survie expliqués depuis le début.
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 = {Courbe de survie de Kaplan-Meier en R : estimer et tracer},
date = {2026-06-25},
url = {https://www.datanovia.com/learn/biostatistics/survival-analysis/kaplan-meier-estimation},
langid = {fr}
}