library(survival)
head(lung[, c("time", "status", "sex")]) time status sex
1 306 2 1
2 455 2 1
3 1010 1 1
4 210 2 1
5 883 2 1
6 1022 1 1
survfit()
surv_median()ggsurvplot()Lisez la survie médiane et son IC à 95 % depuis un survfit, gérez le cas « non atteinte », et placez les médianes sur la courbe avec ggsurvplot
Calculez le temps de survie médian et son intervalle de confiance à 95 % en R à partir d’un ajustement Kaplan-Meier avec survfit(), lisez-les en langage clair, gérez le cas où la médiane est « non atteinte » (NA), obtenez un tableau soigné avec surv_median(), et tracez les médianes sur la courbe de survie avec ggsurvplot(surv.median.line = “hv”) sur les données du cancer du poumon NCCTG.
25 juin 2026
7 juillet 2026
print(survfit(...)) donne la médiane et son intervalle de confiance à 95 % par groupe.surv_median() (survminer) renvoie les mêmes chiffres sous forme de data frame soigné, prêt à insérer dans un tableau ou un rapport.NA (« non atteinte ») — rapportez un quantile inférieur, la probabilité de survie à un instant fixe, ou le temps de survie moyen restreint (RMST) à la place.ggsurvplot(fit, surv.median.line = "hv").« Quel est le temps de survie typique ? » est la première question qu’un clinicien, un patient ou un régulateur pose à propos d’une étude de survie — et la réponse est le temps de survie médian : le point où la moitié du groupe a connu l’événement. C’est le chiffre phare des essais en oncologie, la valeur qui sous-tend les mentions d’étiquetage, et le résumé qui tient en une seule phrase.
Vous ne pouvez pas la calculer en prenant la médiane des temps observés — les patients censurés (toujours vivants au dernier suivi) la tireraient vers le bas, car leur vrai temps de survie est plus long que ce que vous avez observé. La survie médiane se lit plutôt sur la courbe de Kaplan-Meier : le moment où la probabilité de survie estimée \(S(t)\) atteint pour la première fois 0.5.
Cette leçon calcule la survie médiane et son intervalle de confiance à 95 % en R — depuis un ajustement survfit(), avec surv_median(), et sur le graphique — en utilisant les données classiques du cancer du poumon NCCTG. Vous gérerez aussi le cas que tout analyste finit par rencontrer : la médiane qui est « non atteinte ». Si vous débutez avec l’estimation de la courbe elle-même, commencez par l’estimation Kaplan-Meier.
Nous utilisons lung, le jeu de données fourni avec le package survival — la survie de 228 patients atteints d’un cancer du poumon avancé. Chargez le package et référencez lung directement (il s’attache automatiquement avec survival, donc aucun appel à data() n’est nécessaire) :
time status sex
1 306 2 1
2 455 2 1
3 1010 1 1
4 210 2 1
5 883 2 1
6 1022 1 1
Les trois colonnes dont nous avons besoin :
time — le temps de survie (suivi) en jours.status — 1 = censuré (vivant au dernier suivi), 2 = décédé (l’événement).sex — 1 = homme, 2 = femme.survfit()Ajustez les courbes de Kaplan-Meier avec survfit(Surv(time, status) ~ group), puis print(). La sortie rapporte la survie médiane et son intervalle de confiance à 95 % pour chaque groupe :
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 les colonnes de médiane :
median — 270 jours pour les hommes, 426 jours pour les femmes. La moitié des hommes sont décédés au jour 270 ; la moitié des femmes, au jour 426.0.95LCL / 0.95UCL — l’intervalle de confiance à 95 % pour cette médiane : 212–310 jours pour les hommes, 348–550 jours pour les femmes.Pour la médiane globale (une seule courbe, sans regroupement), placez 1 du côté droit de la formule :
Call: survfit(formula = Surv(time, status) ~ 1, data = lung)
n events median 0.95LCL 0.95UCL
[1,] 228 165 310 285 363
Regroupée sur les deux sexes, la survie médiane est de 310 jours (IC à 95 % 285–363) — entre la médiane masculine (270) et la médiane féminine (426), comme attendu.
Deux formulations à bien distinguer :
Si moins de la moitié des patients d’un groupe ont connu l’événement, la courbe de survie n’atteint jamais 0.5, donc la médiane est indéfinie. R l’affiche sous la forme NA — souvent rapportée comme « non atteinte » (NR). C’est fréquent avec des traitements efficaces, un suivi court ou une censure importante.
Vous pouvez le reproduire avec un suivi court : prenez le groupe des femmes, mais arrêtez de suivre tout le monde au jour 300 (censure administrative — toute personne encore vivante alors est marquée comme censurée). Seules 27 femmes sur 90 sont décédées au jour 300, donc la courbe n’atteint jamais 0.5 :
library(survival)
# Female group with follow-up capped at day 300 (administrative censoring)
women <- subset(lung, sex == 2)
status_300 <- ifelse(women$time > 300, 1, women$status) # censored if alive past day 300
time_300 <- pmin(women$time, 300)
fit_nr <- survfit(Surv(time_300, status_300) ~ 1)
print(fit_nr)Call: survfit(formula = Surv(time_300, status_300) ~ 1)
n events median 0.95LCL 0.95UCL
[1,] 90 27 NA NA NA
La colonne median est NA : la courbe n’atteignant jamais 0.5, il n’y a aucun temps à rapporter. NA n’est ni zéro ni une donnée manquante — cela signifie généralement une bonne survie (la plupart des patients sont toujours sans événement). Que rapporter à la place :
quantile(fit, probs = 0.25)), que la courbe atteint souvent bel et bien.summary(fit, times = 365).surv_median()print(fit) convient pour la lecture, mais pour un rapport ou un tableau vous voulez les médianes sous forme de data frame. Le surv_median() de survminer renvoie exactement cela — strates, médiane, borne inférieure, borne supérieure :
strata median lower upper
1 sex=1 270 212 310
2 sex=2 426 348 550
Les mêmes chiffres que la sortie — 270 (212–310) pour les hommes, 426 (348–550) pour les femmes — désormais dans des colonnes que vous pouvez formater ou assembler dans un tableau de résultats.
ggsurvplot()La médiane se montre mieux qu’elle ne s’énonce. Le ggsurvplot() de survminer avec surv.median.line = "hv" trace des repères pointillés horizontaux et verticaux depuis \(S(t) = 0.5\) jusqu’à chaque temps médian — ainsi le lecteur voit où chaque courbe croise 50 % :
library(survival)
library(survminer)
fit <- survfit(Surv(time, status) ~ sex, data = lung)
ggsurvplot(
fit,
data = lung,
surv.median.line = "hv", # dashed horizontal + vertical median guides
conf.int = TRUE, # 95% confidence bands
palette = "jco", # colourblind-safe journal palette
legend.labs = c("Male", "Female"),
legend.title = "Sex",
xlab = "Time (days)",
ylab = "Survival probability",
ggtheme = theme_minimal()
)
Comment le lire : la ligne horizontale en pointillés se situe à 0.5 ; à partir du point où elle rencontre chaque courbe, une ligne verticale en pointillés descend vers l’axe des x — à 270 jours (hommes) et 426 jours (femmes). Ce sont les médianes de survfit(), désormais visibles sur le graphique. La courbe féminine croise 0.5 bien plus tard, l’avantage de survie que les chiffres rapportaient. (Pour le panneau complet prêt à publier — table des effectifs à risque et p-value du log-rank — voir l’estimation Kaplan-Meier.)
La survie a été estimée par la méthode de Kaplan-Meier sur les données du cancer du poumon NCCTG (n = 228, 165 décès). La survie globale médiane était de 310 jours (IC à 95 % 285–363). Par sexe, 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.
Quand la médiane d’un groupe n’est pas atteinte, rapportez-le explicitement et ajoutez un résumé de repli :
La survie médiane n’a pas été atteinte dans le bras de traitement (contre 280 jours, IC à 95 % 230–340, dans le bras témoin) ; la probabilité de survie à 12 mois était de 68 % (traitement) contre 41 % (témoin).
Quand les médianes ne sont pas atteintes (ou que les courbes de survie se croisent / les risques sont non proportionnels), le temps de survie moyen restreint (RMST) — le temps moyen sans événement jusqu’à un horizon choisi \(\tau\) — est l’alternative standard. Contrairement à la médiane, le RMST est toujours défini, et la différence de RMST entre les bras est un effet directement interprétable (« X mois supplémentaires sans événement sous traitement »). Voir la leçon RMST (temps de survie moyen restreint) (parcours avancé) pour le déroulé complet.
NA) → un quantile inférieur (par exemple le 25e centile), la survie à un instant fixe, ou le RMST.Lisez les médianes vous-même — remplacez sex par un autre regroupement, modifiez la troncature qui déclenche une médiane « non atteinte », ou extrayez un quantile différent. Le bac à sable démarre au premier Run.
Demandez à Prova « calcule la survie médiane avec les intervalles de confiance à 95 % depuis mon ajustement Kaplan-Meier, dis-moi ce qu’il faut rapporter quand la médiane d’un groupe n’est pas atteinte, et trace un ggsurvplot avec les lignes de médiane » — 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 →
La médiane est NA (« non atteinte »). La courbe de survie n’atteint jamais 0.5 parce que moins de la moitié du groupe a connu l’événement — il n’y a donc aucune médiane à rapporter. C’est normal avec une censure importante, un suivi court ou une survie réellement bonne. Ne lisez pas NA comme zéro ni comme une donnée manquante ; rapportez un quantile inférieur (quantile(fit, probs = 0.25)), la probabilité de survie à un instant fixe (summary(fit, times = 365)), ou le RMST à la place.
Vous avez comparé les deux médianes et déclaré la différence significative. Que deux médianes (ou leurs intervalles de confiance) se chevauchent ou non n’est pas un test statistique. Des IC qui ne se chevauchent pas suggèrent une différence mais la sous-estiment ou la surestiment ; des IC qui se chevauchent ne prouvent pas « aucune différence ». Pour tester si la survie diffère, lancez le test du log-rank ; pour quantifier l’effet, ajustez un modèle de Cox.
C’est le moment où la probabilité de survie estimée \(S(t)\) atteint pour la première fois 0.5 — le point au bout duquel la moitié du groupe a connu l’événement (par exemple un décès). C’est le résumé en un chiffre le plus rapporté d’une courbe de survie car il est interprétable (« la moitié des patients survivent au-delà de X jours ») et robuste face à la longue queue censurée qui rend une simple moyenne peu fiable.
Ajustez une courbe de Kaplan-Meier et affichez-la : fit <- survfit(Surv(time, status) ~ group, data); print(fit). La sortie rapporte la médiane et son intervalle de confiance à 95 % par groupe. Pour un data frame soigné, utilisez le surv_median(fit) de survminer. Les deux lisent la médiane directement sur la courbe — vous ne prenez pas la médiane des temps bruts (cela gérerait mal la censure).
Parce que moins de la moitié des patients de ce groupe ont connu l’événement, donc la courbe de survie n’atteint jamais 0.5 et la médiane est indéfinie. Cela se produit avec des traitements efficaces, un suivi court ou une censure importante — et c’est souvent bon signe. Rapportez un quantile inférieur (par exemple le 25e centile), la probabilité de survie à un instant fixe, ou le temps de survie moyen restreint (RMST) à la place.
C’est l’éventail des valeurs plausibles pour la vraie médiane compte tenu de votre échantillon : si vous répétiez l’étude de nombreuses fois, environ 95 % de ces intervalles contiendraient la vraie médiane. Un IC large signifie une estimation imprécise (petit groupe, peu d’événements). Comparer les IC de deux groupes n’est pas un test formel de différence — utilisez le test du log-rank pour cela.
La médiane est un point temporel unique (là où la survie atteint 0.5) et est indéfinie quand la courbe n’y arrive jamais. Le RMST est le temps moyen sans événement jusqu’à un horizon choisi \(\tau\) (l’aire sous la courbe jusqu’à \(\tau\)) et est toujours défini. Utilisez la médiane pour un simple chiffre phare ; utilisez le RMST quand la médiane n’est pas atteinte, que les courbes se croisent, ou que les risques sont non proportionnels.
1. Quelle est la médiane globale, et comment se situe-t-elle par rapport aux médianes par sexe (270 contre 426) ?NA (« non atteinte ») dans le bras de traitement et de 280 jours dans le bras témoin. En mots simples, que signifie le NA, et que devriez-vous rapporter à la place ?Pour une courbe globale sans groupes, le côté droit de la formule est 1. La colonne median de surv_median() donne la survie médiane regroupée ; comparez-la aux médianes par sexe (270 et 426).
La survie médiane globale est de 310 jours (IC à 95 % 285–363) — entre la médiane masculine (270) et la médiane féminine (426), comme attendu lorsque vous regroupez les deux groupes.
Pour la question 2 : NA (« non atteinte ») signifie que moins de la moitié des patients du bras de traitement ont connu l’événement, donc la courbe n’est jamais passée sous 0.5 — généralement un bon signe, pas une donnée manquante. Ne le rapportez pas comme zéro. Rapportez plutôt la probabilité de survie à un instant cliniquement pertinent (par exemple la survie à 12 mois), un quantile inférieur, ou le RMST, et indiquez la borne de confiance inférieure si elle existe (« médiane d’au moins X jours »).
La survie médiane d’un groupe s’affiche comme NA. Qu’est-ce que cela signifie le plus probablement ?
Que plus de la moitié des patients de ce groupe étaient toujours sans événement à la fin du suivi, donc la courbe de Kaplan-Meier n’a jamais atteint une probabilité de survie de 0.5 — la médiane est indéfinie (« non atteinte »), ni zéro ni une erreur de données. C’est souvent un résultat favorable. Rapportez un quantile inférieur, la survie à un instant fixe, ou le RMST à la place.
Vous savez désormais rapporter le temps de survie médian en R : ajustez les courbes avec survfit(), lisez la médiane et son IC à 95 % depuis print(fit) ou surv_median(), et montrez les médianes sur le graphique avec ggsurvplot(surv.median.line = "hv"). Sur les données du cancer du poumon, la survie médiane était de 270 jours pour les hommes, 426 pour les femmes, et 310 au global. Quand moins de la moitié du groupe a connu l’événement, la médiane est « non atteinte » — rapportez un quantile inférieur, la survie à un instant fixe, ou le RMST à la place, et rappelez-vous que comparer des médianes n’est pas un test : le test du log-rank et le modèle de Cox le font.
survfit + ggsurvplot en entier). · Test du log-rank — le test formel pour savoir si deux courbes de survie ou plus diffèrent (ne comparez pas les médianes à l’œil). · Modèle de Cox à risques proportionnels — modélisez la survie sur une ou plusieurs covariables et obtenez un hazard ratio par facteur.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.
Passez à Pro — Prova illimité sur vos propres données et un certificat vérifiable qui atteste la compétence.
dès 15 $/mois facturé annuellement
✓ Vous êtes Pro — continuez. The runtime is the judge.
Prêt à passer à la vitesse supérieure ?
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.
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 = {Survie médiane et intervalle de confiance à 95 \% en R},
date = {2026-06-25},
url = {https://www.datanovia.com/learn/biostatistics/survival-analysis/median-survival-and-ci},
langid = {fr}
}