Modèle de Cox à risques proportionnels en R, pas à pas
Ajustez et interprétez une régression de Cox sur les données de cancer du poumon — hazard ratios univariés et multivariés, IC à 95 %, et un forest plot prêt à publier avec survminer
Apprenez le modèle de Cox à risques proportionnels en R avec les packages survival et survminer. Ajustez des modèles coxph univariés et multivariés sur les données de cancer du poumon NCCTG, interprétez les hazard ratios et leurs intervalles de confiance à 95 % en langage clair, lisez les tests globaux (rapport de vraisemblance, Wald, log-rank), et tracez le graphique ggforest des hazard ratios ainsi que les courbes de survie ajustées.
Date de publication
25 juin 2026
Modifié
7 juillet 2026
AstucePoints clés
Le modèle de Cox à risques proportionnels (coxph()) est la régression de référence de l’analyse de survie : il relie le temps de survie à un ou plusieurs prédicteurs et fonctionne pour des covariables à la fois catégorielles et continues — là où les courbes de Kaplan-Meier et le test log-rank ne gèrent que des groupes catégoriels.
Il rapporte un hazard ratio (HR) par covariable : HR = 1 aucun effet, HR < 1 risque plus faible (meilleure survie), HR > 1 risque plus élevé (survie moins bonne). Lisez-le toujours avec son IC à 95 %.
Sur les données de cancer du poumon, être une femme réduit le risque de décès d’environ 41 % (HR ≈ 0.59) — un solide bon facteur pronostique.
Ajustez-le avec coxph(Surv(time, status) ~ covariates, data) ; obtenez le tableau complet avec summary() ; visualisez-le avec survminer : ggforest() pour les hazard ratios et ggsurvplot() pour les courbes ajustées.
Imaginez un essai sur le cancer du poumon : les patients sont suivis pendant des mois, certains décèdent, d’autres sont toujours en vie à la fin de l’étude (leur temps de survie est censuré), et vous voulez savoir quels facteurs modifient le risque de décès d’un patient — traitement, sexe, âge, état général. Une simple comparaison de groupes ne suffit pas : si un groupe est aussi plus âgé, toute différence de survie pourrait tenir à l’âge plutôt qu’au facteur qui vous intéresse. Il vous faut un modèle qui pèse plusieurs facteurs à la fois et qui gère la censure.
Ce modèle, c’est le modèle de Cox à risques proportionnels (Cox, 1972) — la méthode la plus utilisée en analyse de survie. Contrairement aux courbes de Kaplan-Meier et au test log-rank, qui sont univariés et ne gèrent que des prédicteurs catégoriels, la régression de Cox :
fonctionne aussi pour des prédicteurs continus (âge, niveau de biomarqueur, perte de poids) ;
ajuste pour plusieurs covariables simultanément, de sorte que chaque effet est rapporté les autres étant maintenues constantes ;
fournit une taille d’effet — le hazard ratio — pour chaque facteur, avec un intervalle de confiance et une p-value.
Cette leçon ajuste le modèle de Cox en R avec survival (le moteur de modélisation) et survminer (graphiques de qualité publication), en utilisant le jeu de données classique du cancer du poumon NCCTG pour que vous puissiez reproduire à l’identique les nombres et les figures.
NoteCe que le modèle estime
Le modèle de Cox écrit le risque — le risque instantané de l’événement au temps t — comme un risque de base multiplié par l’effet des covariables :
H₀ : une covariable n’a aucun effet sur le risque (HR = 1). Hₐ : la covariable modifie le risque (HR ≠ 1).
Une covariable avec HR > 1 augmente le risque (un mauvais facteur pronostique) ; HR < 1 le diminue (un bon facteur pronostique).
Les données : l’étude sur le cancer du poumon NCCTG
Nous utilisons lung, le jeu de données sur le cancer du poumon du North Central Cancer Treatment Group fourni avec le package survival : la survie de 228 patients atteints d’un cancer du poumon avancé, avec scores de performance et covariables cliniques. Chargez-le et regardez les premières lignes :
status — statut de censure : 1 = censuré (en vie au dernier suivi), 2 = décédé (l’événement).
sex — 1 = homme, 2 = femme.
age — âge en années.
ph.ecog — score de performance ECOG (0 = pleinement actif … plus élevé = plus altéré).
L’objet Surv() — la réponse
La réponse, dans tout modèle de survie, n’est pas un nombre unique mais une paire temps–événement : combien de temps nous avons observé le patient, et si l’événement (le décès) s’est réellement produit ou si l’observation a été censurée. Vous la construisez avec Surv(time, status). R reconnaît automatiquement status codé 1 = censuré / 2 = événement ; un + après un temps marque une observation censurée :
Cet objet Surv() est le membre de gauche de toute formule coxph().
Ajuster le modèle de Cox
Nous ajusterons la régression de Cox sur quatre covariables cliniquement pertinentes — age, sex, ph.ecog, ph.karno — en commençant par des modèles univariés (un facteur à la fois), puis un modèle multivarié (plusieurs facteurs ensemble, chacun ajusté pour les autres).
Régression de Cox univariée
Commencez par une seule covariable, sex. Ajustez-la avec coxph() — la réponse Surv(time, status) à gauche, le prédicteur à droite :
library(survival)res.cox <-coxph(Surv(time, status) ~ sex, data = lung)res.cox
Call:
coxph(formula = Surv(time, status) ~ sex, data = lung)
coef exp(coef) se(coef) z p
sex -0.5310 0.5880 0.1672 -3.176 0.00149
Likelihood ratio test=10.63 on 1 df, p=0.001111
n= 228, number of events= 165
Pour le tableau complet — le hazard ratio, son intervalle de confiance et les tests globaux — appelez summary() :
library(survival)res.cox <-coxph(Surv(time, status) ~ sex, data = lung)summary(res.cox)
Call:
coxph(formula = Surv(time, status) ~ sex, data = lung)
n= 228, number of events= 165
coef exp(coef) se(coef) z Pr(>|z|)
sex -0.5310 0.5880 0.1672 -3.176 0.00149 **
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
exp(coef) exp(-coef) lower .95 upper .95
sex 0.588 1.701 0.4237 0.816
Concordance= 0.579 (se = 0.021 )
Likelihood ratio test= 10.63 on 1 df, p=0.001
Wald test = 10.09 on 1 df, p=0.001
Score (logrank) test = 10.33 on 1 df, p=0.001
Lisez la sortie, ligne par ligne :
coef = −0.531. Le signe est ce qui compte d’abord : un coefficient négatif signifie que le risque diminue quand la covariable augmente. Comme sex va de 1 = homme → 2 = femme, le signe négatif dit que les femmes ont un risque de décès plus faible que les hommes dans ces données.
exp(coef) = 0.59 — le hazard ratio. C’est la taille d’effet : être une femme (sex = 2 vs 1) multiplie le risque par 0.59, soit un risque de décès inférieur de 41 % ((1 − 0.59) × 100). Être une femme est ici un bon facteur pronostique.
IC à 95 % = 0.42 à 0.82. La fourchette plausible pour le HR. Comme il se situe entièrement en dessous de 1, l’effet protecteur est statistiquement convaincant.
z = −3.18, Pr(>|z|) = 0.0015 — le test de Wald.z = coef / se(coef) teste si le coefficient diffère de 0. Ici p = 0.0015 : le sexe est hautement significatif.
Tests globaux (en bas). Trois tests asymptotiquement équivalents du modèle entier contre l’hypothèse nulle : les tests du rapport de vraisemblance, de Wald et du score (log-rank) — tous donnent p ≈ 0.001. Le test du rapport de vraisemblance est préféré pour les petits échantillons. La concordance (0.58) est l’indice C, la probabilité que le modèle classe une paire aléatoire de patients dans le bon ordre de survie (0.5 = hasard).
Pour balayer toutes les covariables candidates rapidement, ajustez un modèle univarié pour chacune et tabulez les HR :
Ce que cela nous apprend :sex, age et ph.ecog portent des effets univariés significatifs, tandis que ph.karno n’en porte pas. age et ph.ecog ont HR > 1 (âge plus avancé et score de performance moins bon → risque plus élevé, survie moins bonne) ; sex a HR < 1 (femme → risque plus faible). Nous écartons le non significatif ph.karno et emportons les trois facteurs pertinents dans le modèle multivarié.
Régression de Cox multivariée
Ajustez maintenant age, sex et ph.ecog ensemble pour que chaque effet soit ajusté pour les deux autres — la véritable force de la régression de Cox. Ajoutez les covariables avec + :
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
Interprétez la sortie complète en langage clair :
Le modèle est significatif. Les trois tests globaux (rapport de vraisemblance, Wald, score) donnent p ≈ 1×10⁻⁶, rejetant nettement l’hypothèse nulle selon laquelle tous les coefficients valent 0.
sex : HR = 0.58, IC à 95 % 0.41–0.80, p = 0.00099. À âge et score de performance constants, être une femme réduit le risque de 42 % — l’effet protecteur résiste à l’ajustement et constitue le signal le plus fort du modèle.
ph.ecog : HR = 1.59, IC à 95 % 1.27–1.99, p = 4.5×10⁻⁵. Chaque point de dégradation du score de performance ECOG augmente le risque d’environ 59 % — un solide mauvais facteur pronostique.
age : HR = 1.01, IC à 95 % 0.99–1.03, p = 0.23. Après ajustement pour le sexe et le score de performance, l’âge n’est plus significatif : une année de plus multiplie le risque par à peine ~1.01 (une hausse de 1 %), et l’ IC inclut 1, si bien qu’on ne peut écarter « aucun effet ». L’effet univarié apparent de l’âge s’expliquait en grande partie par les autres covariables.
AstuceLire un hazard ratio d’un seul coup d’œil
HR < 1 → protecteur (risque plus faible, meilleure survie) : HR 0.59 = 41 % de risque en moins.HR > 1 → délétère (risque plus élevé, survie moins bonne) : HR 1.59 = 59 % de risque en plus.HR = 1 (ou un IC qui traverse 1) → aucun effet convaincant. Le HR est un effet multiplicatif sur le risque, supposé constant au cours du temps (l’hypothèse des risques proportionnels).
Visualiser le modèle
Le forest plot — ggforest() (la figure de Cox emblématique)
Le visuel de Cox le plus utile est le forest plot des hazard ratios issu de ggforest() de survminer — il montre pour chaque covariable son HR, son IC à 95 % et sa p-value sur un seul panneau prêt à publier, avec la ligne de référence à HR = 1. Les points à gauche de 1 sont protecteurs ; à droite, délétères :
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 se situe nettement à gauche de la ligne (protecteur), ph.ecog se situe à droite (délétère), et age est à cheval sur la ligne (aucun effet net) — exactement ce que disaient les nombres.
Courbes de survie ajustées — ggsurvplot()
Un modèle de Cox ajusté peut aussi prédire des courbes de survie. Pour montrer comment la survie dépend du sexe tout en maintenant les autres covariables fixes, construisez un petit data frame avec une ligne par sexe (âge à sa moyenne, ph.ecog fixé à 1), passez-le à survfit(), et tracez avec ggsurvplot() de survminer :
library(survival)library(survminer)res.cox <-coxph(Surv(time, status) ~ age + sex + ph.ecog, data = lung)# One row per sex; other covariates held at typical valuessex_df <-data.frame(sex =c(1, 2),age =rep(mean(lung$age, na.rm =TRUE), 2),ph.ecog =c(1, 1))fit <-survfit(res.cox, newdata = sex_df)ggsurvplot(fit, data = lung, conf.int =TRUE,legend.labs =c("Male", "Female"),palette ="jco", ggtheme =theme_minimal(),xlab ="Time (days)", ylab ="Survival probability")
La courbe féminine reste au-dessus de la courbe masculine à chaque instant — l’avantage de survie prédit par le modèle pour les femmes, la même histoire que celle racontée numériquement par le HR de 0.58.
Rapport
Un modèle de Cox à risques proportionnels multivarié sur les données de cancer du poumon NCCTG (n = 227, 164 décès) 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) après ajustement pour l’âge et le score de performance ECOG, tandis 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 (HR = 1.01, IC à 95 % 0.99–1.03, p = 0.23). Le modèle global était significatif (test du rapport de vraisemblance p < 0.001).
NoteLes mathématiques derrière le modèle de Cox (facultatif)
Le modèle de Cox écrit le risque pour un patient de covariables \(x_1, \dots, x_p\) comme le risque de base\(h_0(t)\) mis à l’échelle par une fonction exponentielle des covariables :
Le risque de base \(h_0(t)\) est laissé totalement non spécifié (c’est pourquoi Cox est dit semi-paramétrique) — le modèle n’estime que les coefficients \(b_i\) via la vraisemblance partielle, qui ne dépend que de l’ ordre dans lequel les événements surviennent, et non de la forme du risque de base.
Chaque \(\exp(b_i)\) est un hazard ratio. Pour deux patients ne différant que par la covariable \(i\), le rapport de leurs risques est constant au cours du temps :
\[
\frac{h_k(t)}{h_{k'}(t)} = \frac{h_0(t)\,e^{\sum b x}}{h_0(t)\,e^{\sum b x'}} = e^{\sum b (x - x')}
\]
Le \(h_0(t)\) s’annule, de sorte que le rapport ne dépend pas de \(t\) — c’est l’hypothèse des risques proportionnels : si le risque d’un patient est deux fois celui d’un autre au début, il reste deux fois plus élevé tout du long. Cette hypothèse doit être testée (leçon suivante).
Comparer la survie entre 2 groupes catégoriels ou plus → test 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 par facteur → risques proportionnels de Cox (cette leçon).
Ajustez vous-même le modèle de Cox — changez les covariables, ou remplacez sex par un prédicteur continu. Le bac à sable démarre au premier Run.
🟢 Avec un agent IA
Demandez à Prova« ajuste un modèle de Cox à risques proportionnels sur mes données de survie, donne-moi les hazard ratios avec leurs IC à 95 %, et dis-moi en mots simples quels facteurs augmentent ou diminuent le risque » — 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
Vos hazard ratios « semblent faux » — vérifiez le codage du facteur. Un HR de Cox est toujours relatif à un niveau de référence. Dans lung, sex est numérique (1 = homme, 2 = femme), donc le HR est femme vs homme. Si votre variable de groupe est un factor, R utilise le premier niveau comme référence — re-niveler-la (relevel(f, ref = "...")) pour que le HR compare les groupes que vous visez.
Vous avez supposé le modèle valide sans tester les risques proportionnels. Les résultats de Cox ne sont fiables que si les HR sont à peu près constants au cours du temps. Un effet qui se croise ou converge viole l’hypothèse des risques proportionnels et biaise le HR. Testez-la toujours avec cox.zph() et ggcoxzph() — voir Tester l’hypothèse des risques proportionnels.
Les valeurs manquantes de covariables suppriment silencieusement des lignes.coxph() utilise les cas complets par défaut : un seul NA dans une covariable retire ce patient (notez que le modèle multivarié a utilisé n = 227, et non 228, car un ph.ecog était manquant). Vérifiez cox.model$n par rapport à nrow(data) pour savoir combien de patients le modèle a réellement utilisés, et décidez si une imputation se justifie.
Questions fréquentes
NoteComment interpréter un hazard ratio dans un modèle de Cox ?
Le hazard ratio est un effet multiplicatif sur le risque de l’événement. HR = 1 signifie aucun effet ; HR < 1 signifie un risque plus faible (meilleure survie) — par ex. HR = 0.59 est un risque inférieur de 41 % ; HR > 1 signifie un risque plus élevé (survie moins bonne) — par ex. HR = 1.59 est un risque supérieur de 59 %. Lisez-le toujours avec son intervalle de confiance à 95 % : si l’IC traverse 1, l’effet n’est pas statistiquement convaincant.
NoteQuelle est la différence entre le modèle de Cox et le test log-rank ?
Le test log-rank compare la survie entre groupes catégoriels et ne donne qu’une p-value — aucune taille d’effet, et aucun moyen de gérer des prédicteurs continus ou d’ajuster pour des facteurs de confusion. Le modèle de Cox est une régression : il gère des prédicteurs continus et catégoriels, estime un hazard ratio pour chacun, et ajuste chaque effet pour les autres dans un modèle multivarié.
NoteQue signifie un HR inférieur à 1 en analyse de survie ?
Un HR inférieur à 1 signifie que la covariable est associée à un risque plus faible de l’événement — c’est-à-dire une meilleure survie, un bon facteur pronostique. Par exemple, HR = 0.59 pour le sexe féminin signifie que les femmes ont un risque de décès inférieur de 41 % à celui des hommes. Un HR supérieur à 1 signifie un risque plus élevé (survie moins bonne) ; HR = 1 signifie aucun effet.
NoteQu’est-ce que l’hypothèse des risques proportionnels ?
C’est l’hypothèse centrale du modèle de Cox : le hazard ratio entre deux patients quelconques est constant au cours du temps (les courbes de survie sont proportionnelles et ne se croisent pas). Si l’effet d’une covariable grandit ou diminue au fil du suivi — ou si les courbes se croisent — l’hypothèse est violée et le HR unique est trompeur. Testez-la avec cox.zph() et ggcoxzph() ; voir Tester l’hypothèse des risques proportionnels.
NoteDe quels packages R ai-je besoin pour la régression de Cox ?
Deux : survival pour ajuster le modèle (coxph(), Surv(), survfit()) et survminer pour le visualiser (ggforest() pour le forest plot des hazard ratios, ggsurvplot() pour les courbes de survie, ggcoxzph() pour le diagnostic PH). Les deux fournissent le jeu de données lung utilisé ici.
Testez vos connaissances
ImportantPratique
Exécutez-le. Dans la cellule interactive ci-dessous, ajustez un modèle de Cox de la survie sur ph.ecog seul. Remplissez le blanc. Le score de performance ECOG est-il un prédicteur significatif, et est-ce un bon ou un mauvais facteur pronostique ?
Interprétez. Une covariable a HR = 0.70 (IC à 95 % 0.55–0.89, p = 0.004). En mots simples, quel est son effet sur la survie, et est-il statistiquement convaincant ?
NoteIndice
Remplissez le blanc avec ph.ecog. La réponse est toujours Surv(time, status). Pour juger l’effet, regardez exp(coef) (le HR) et sa p-value, et rappelez-vous que HR > 1 = risque plus élevé = survie moins bonne.
NoteSolution
res.cox <-coxph(Surv(time, status) ~ ph.ecog, data = lung)summary(res.cox)#> HR (exp(coef)) ~ 1.61, p ~ 0.0001 — significant, HR > 1 = a BAD prognostic factor:#> a higher ECOG performance score is associated with a higher hazard of death (worse survival).
Pour la question 2 : HR = 0.70 signifie un risque inférieur de 30 % de l’événement ((1 − 0.70) × 100) — un facteur protecteur / bon facteur pronostique. Il est statistiquement convaincant car l’IC à 95 % (0.55–0.89) se situe entièrement en dessous de 1 et p = 0.004 < 0.05.
AstuceVérification rapide
Dans un modèle de Cox, une covariable a un hazard ratio de 1.0 avec un IC à 95 % de 0.85–1.18. Que concluez-vous ?
NoteAfficher la réponse
Aucun effet convaincant. HR = 1 signifie que la covariable ne modifie pas le risque, et l’intervalle de confiance chevauche 1 (il inclut des valeurs à la fois en dessous et au-dessus), de sorte que vous ne pouvez écarter « aucun effet ». La covariable n’est pas un prédicteur utile dans ce modèle.
Conclusion
Vous savez désormais ajuster et interpréter le modèle de Cox à risques proportionnels en R : construire la réponse Surv(time, status), ajuster coxph() pour une covariable (univarié) ou plusieurs à la fois (multivarié, chacune ajustée pour les autres), et lire la sortie complète — le hazard ratio, son IC à 95 %, la p-value de Wald et les tests globaux. Sur les données de cancer du poumon, le sexe féminin a réduit le risque de décès d’environ 42 % et une moins bonne performance ECOG l’a augmenté d’environ 59 %, tandis que l’âge a disparu après ajustement. Le forest plot ggforest() de survminer et les courbes ajustées ggsurvplot() transforment ces nombres en figures prêtes à publier. Il ne reste plus qu’à vérifier si les hazard ratios tiennent dans le temps — l’hypothèse des risques proportionnels.
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 = {Modèle de Cox à risques proportionnels en R, pas à pas},
date = {2026-06-25},
url = {https://www.datanovia.com/learn/biostatistics/survival-analysis/cox-proportional-hazards},
langid = {fr}
}