Modèles de fragilité en R : Cox à effets mixtes (coxme)

Patients au sein de centres, événements récurrents chez un même sujet, animaux appariés par portée — ajoutez un effet aléatoire (la fragilité) à un modèle de Cox avec coxme pour que vos erreurs standard cessent de supposer une indépendance qui n’existe pas

Ajustez un modèle de fragilité (Cox à effets mixtes / à effets aléatoires) en R avec le package coxme. Lorsque les temps de survie sont groupés ou corrélés — patients au sein d’hôpitaux, événements répétés chez un même patient, portées d’animaux — une fragilité partagée ajoute un effet aléatoire par groupe pour que le modèle tienne compte de la corrélation intra-groupe. Ajustez un modèle à fragilité partagée avec coxme, interprétez les hazard ratios des effets fixes et la variance de fragilité, comparez avec un coxph naïf, découvrez l’ancienne voie coxph(frailty()), testez si l’effet aléatoire compte, et tracez les effets aléatoires par groupe.

Date de publication

26 juin 2026

Modifié

7 juillet 2026

AstucePoints clés
  • Lorsque les temps de survie sont groupés, un modèle de Cox ordinaire est faux — des patients du même hôpital, des événements répétés chez un même patient, ou des animaux appariés par portée sont corrélés, et coxph() les suppose indépendants. Cette hypothèse dégonfle les erreurs standard et surestime la précision.
  • Une fragilité est un effet aléatoire partagé et non observé — un terme multiplicatif sur le risque par groupe — qui absorbe la variation inter-groupe que les covariables fixes n’expliquent pas.
  • Ajustez-la avec coxme() du package coxme : une ordonnée à l’origine aléatoire par groupe s’écrit (1 | cluster). coxme(Surv(time, status) ~ rx + (1 | litter), data) se lit exactement comme lme4.
  • Interprétez deux choses : les hazard ratios des effets fixes (exp(fixef()), ajustés pour le groupement) et la variance de fragilité (VarCorr()) — l’ampleur de la variation du risque de base entre groupes.
  • L’ancienne voie coxph(... + frailty(id, distribution = "gamma")) fonctionne toujours ; coxme est l’approche moderne par modèle mixte et celle qu’il faut privilégier aujourd’hui.
  • Testez si l’effet aléatoire compte avec un test du rapport de vraisemblance face au modèle de Cox sans fragilité, et visualisez les groupes avec un caterpillar plot des effets aléatoires par groupe (ranef()).

Introduction

Vous analysez une étude de cancérogenèse sur 100 portées de rats, ou un essai en oncologie sur 37 centres, ou un jeu de données sur les cathéters rénaux où chaque patient contribue deux temps d’infection. Dans chacun de ces cas, les temps de survie ne sont pas indépendants — des rats de la même portée partagent une génétique et une cage, des patients du même hôpital partagent un standard de soins et un case-mix, deux événements du même patient partagent ce patient. Donnez cela à un modèle de Cox ordinaire et vous obtenez un hazard ratio bien net avec une erreur standard trop petite : coxph() compte chaque observation comme une information nouvelle, donc il surestime ce que vous savez réellement.

La solution est une fragilité — un effet aléatoire ajouté au modèle de Cox, un par groupe. Chaque groupe obtient son propre multiplicateur non observé sur le risque de base : une portée « à forte fragilité » meurt plus vite sur toute la ligne, un centre « à faible fragilité » a une meilleure survie de base, pour des raisons que vos covariables n’ont jamais mesurées. Le modèle estime dans quelle mesure ce multiplicateur caché varie (la variance de fragilité) et corrige l’inférence sur les effets fixes pour la corrélation intra-groupe. C’est le jumeau, en analyse de survie, d’un modèle à effets mixtes : des effets fixes pour les covariables qui vous intéressent, une ordonnée à l’origine aléatoire pour le groupe.

Cette leçon ajuste des modèles de fragilité en R avec coxme (le package de Cox à effets mixtes de Therneau) et le package de base survival, sur des données appariées par portée et multicentriques. Vous apprendrez à :

  • reconnaître quand le groupement met en défaut un modèle de Cox ordinaire ;
  • ajuster un modèle à fragilité partagée avec coxme() et la syntaxe (1 | cluster) ;
  • interpréter les HR des effets fixes et la variance de fragilité ;
  • le comparer avec un coxph() naïf et voir les erreurs standard changer ;
  • utiliser l’ancienne voie coxph(frailty()) et savoir pourquoi coxme l’a supplantée ;
  • tester si l’effet aléatoire compte et tracer les effets par groupe.
NoteCe qu’une fragilité ajoute au modèle de Cox

Un modèle de Cox standard donne à chaque sujet le même risque de base \(h_0(t)\). Un modèle à fragilité partagée le multiplie par un terme aléatoire propre au groupe \(u_i\) (la fragilité), partagé par tous les membres du groupe \(i\) :

\[ h_{ij}(t) = h_0(t)\, u_i \,\exp(b_1 x_{1ij} + \dots + b_p x_{pij}) \]

De manière équivalente, sur l’échelle logarithmique, chaque groupe possède une ordonnée à l’origine aléatoire \(w_i = \log u_i \sim N(0, \sigma^2)\). Le modèle estime les coefficients fixes \(b\) et la variance de fragilité \(\sigma^2\). Un \(\sigma^2\) plus grand signifie que les groupes diffèrent davantage en risque de base ; \(\sigma^2 = 0\) ramène à un modèle de Cox ordinaire.

Les données : une étude sur des rats appariés par portée

Nous utilisons rats, l’expérience classique de tumorigenèse appariée par portée fournie avec le package survival. Chacune des 100 portées comporte trois rats — un recevant un médicament (rx = 1) et deux témoins (rx = 0) — et l’on enregistre le temps jusqu’à la tumeur. La portée est le groupe : des rats de la même portée partagent une génétique, donc leurs temps jusqu’à la tumeur sont corrélés. rats fait partie des données chargées paresseusement par le package survival, il suffit donc de le référencer après library(survival) :

library(survival)

head(rats)
  litter rx time status sex
1      1  1  101      0   f
2      1  0   49      1   f
3      1  0  104      0   f
4      2  1   91      0   m
5      2  0  104      0   m
6      2  0  102      0   m
c(rats = nrow(rats), litters = length(unique(rats$litter)), tumors = sum(rats$status))
   rats litters  tumors 
    300     100      42 

Les colonnes que nous modélisons :

  • time / status — temps jusqu’à la tumeur et indicateur d’événement (1 = tumeur, 0 = censuré).
  • rx — le traitement : 1 = médicament, 0 = témoin. C’est l’effet fixe pour lequel nous voulons un hazard ratio.
  • litter — le groupe (1–100), trois rats chacun. C’est ce qui devient l’effet aléatoire.

Seuls 42 des 300 rats ont développé une tumeur — un jeu de données fortement censuré, typique des données de survie.

Pourquoi le groupement compte : d’abord le modèle de Cox naïf

Commencez par le modèle qui ignore les portées, afin d’avoir une référence à laquelle comparer. Ajustez un modèle de Cox ordinaire du temps jusqu’à la tumeur en fonction du traitement :

library(survival)

naive <- coxph(Surv(time, status) ~ rx, data = rats)
summary(naive)$coefficients
        coef exp(coef)  se(coef)       z   Pr(>|z|)
rx 0.7137368  2.041606 0.3087778 2.31149 0.02080582

Lecture : le médicament augmente le risque de tumeur — exp(coef)2.04, donc les rats traités développent des tumeurs à un rythme environ deux fois supérieur à celui des témoins (HR = 2.04, p = 0.021). L’erreur standard du log-HR vaut 0.309. C’est ce chiffre qui pose problème : il traite les 300 rats comme indépendants, alors qu’il n’y a en réalité que 100 portées indépendantes. Ignorer la corrélation entre portées rend l’erreur standard trop petite et fait paraître le résultat plus certain qu’il ne l’est. Il nous faut un modèle qui sache que trois rats partagent une portée.

Ajuster le modèle à fragilité partagée avec coxme()

L’outil moderne est coxme() du package coxme. Sa formule se lit exactement comme lme4 : les effets fixes à gauche, une ordonnée à l’origine aléatoire pour le groupe sous la forme (1 | litter). Ce (1 | litter) est la fragilité partagée — un multiplicateur aléatoire sur le risque par portée :

library(survival)
library(coxme)

fit <- coxme(Surv(time, status) ~ rx + (1 | litter), data = rats)
fit
Cox mixed-effects model fit by maximum likelihood
  Data: rats
  events, n = 42, 300
  Iterations= 19 81 
                    NULL Integrated    Fitted
Log-likelihood -225.2822  -218.4886 -183.0781

                  Chisq   df          p   AIC    BIC
Integrated loglik 13.59  2.0 1.1210e-03  9.59   6.11
 Penalized loglik 84.41 33.4 2.6679e-06 17.61 -40.43

Model:  Surv(time, status) ~ rx + (1 | litter) 
Fixed coefficients
        coef exp(coef)  se(coef)   z     p
rx 0.7301151  2.075319 0.3177679 2.3 0.022

Random effects
 Group  Variable  Std Dev  Variance
 litter Intercept 1.147775 1.317388

Interprétez la sortie en langage clair — il y a deux parties :

  • Effets fixes — la partie que vous rapportez comme dans un modèle de Cox ordinaire. rx : coef = 0.730, HR = exp(0.730) ≈ 2.08, p = 0.022. Ajusté pour le groupement par portée, le médicament continue à peu près de doubler le risque de tumeur. Notez l’erreur standard : 0.318, légèrement plus grande que les 0.309 du modèle naïf — la fragilité l’a élargie pour refléter honnêtement les 100 (et non 300) unités indépendantes. (La correction est modeste ici parce que le plan est équilibré et que la plupart des portées sont censurées ; avec plus d’événements par groupe, elle s’accentue.)
  • Effets aléatoires — la nouveauté. La variance de fragilité pour litter est Variance = 1.32 (Std Dev = 1.15 sur l’échelle du log-risque). C’est grand : les portées diffèrent beaucoup en risque de tumeur de base pour des raisons que rx ne capte pas. Un écart-type de fragilité de 1.15 signifie qu’une portée à un écart-type au-dessus de la moyenne a un risque de base exp(1.15)3.2× celui d’une portée moyenne. Le groupement est réel et mérite d’être modélisé.
  • Le test du rapport de vraisemblance en haut (Integrated loglik χ² = 13.6 sur 2 df, p = 0.001) confirme le modèle dans son ensemble — effet fixe plus fragilité — face au modèle nul.

Extrayez les éléments directement quand vous en avez besoin :

library(survival)
library(coxme)

fit <- coxme(Surv(time, status) ~ rx + (1 | litter), data = rats)

# Fixed-effect hazard ratio
exp(fixef(fit))
      rx 
2.075319 
# The frailty variance (between-litter variance on the log-hazard scale)
VarCorr(fit)
$litter
Intercept 
 1.317388 

L’effet aléatoire compte-t-il ? Un test du rapport de vraisemblance

Une variance de fragilité de 1.32 semble grande, mais testez-la : comparez le modèle de fragilité au modèle de Cox ordinaire sans fragilité avec un test du rapport de vraisemblance. Deux fois l’écart de log-vraisemblance est une statistique χ² ; parce que vous testez une variance sur la frontière (σ² = 0), utilisez une référence ½ χ²₁ (une correction standard des modèles mixtes) :

library(survival)
library(coxme)

no.frailty <- coxph(Surv(time, status) ~ rx, data = rats)               # σ² = 0
with.frailty <- coxme(Surv(time, status) ~ rx + (1 | litter), data = rats)

lrt <- 2 * (with.frailty$loglik["Integrated"] - as.numeric(logLik(no.frailty)))
p.value <- 0.5 * pchisq(lrt, df = 1, lower.tail = FALSE)                 # boundary correction
c(chisq = round(lrt, 2), p = signif(p.value, 3))
chisq.Integrated     p.Integrated 
         8.35000          0.00192 

Lecture : χ² ≈ 8.35, p0.002. L’effet aléatoire est hautement significatif — ajouter la fragilité par portée améliore le modèle de façon substantielle, donc les portées diffèrent réellement en risque de base et vous devriez conserver la fragilité. Si ce test était non significatif, un coxph() ordinaire suffirait et vous pourriez abandonner l’effet aléatoire.

L’ancienne voie : coxph(... + frailty())

Avant coxme, le package survival ajustait les modèles de fragilité au moyen d’un terme frailty() à l’intérieur de coxph(). Cela fonctionne toujours et vous le rencontrerez dans du code plus ancien, alors sachez le reconnaître :

library(survival)

fit.old <- coxph(Surv(time, status) ~ rx + frailty(litter, distribution = "gamma"), data = rats)
fit.old
Call:
coxph(formula = Surv(time, status) ~ rx + frailty(litter, distribution = "gamma"), 
    data = rats)

                            coef se(coef)    se2  Chisq   DF     p
rx                         0.727    0.318  0.313  5.219  1.0 0.022
frailty(litter, distribut                        63.046 47.7 0.067

Iterations: 6 outer, 23 Newton-Raphson
     Variance of random effect= 2.02   I-likelihood = -217.5 
Degrees of freedom for terms=  1.0 47.7 
Likelihood ratio test=88.5  on 48.6 df, p=4e-04
n= 300, number of events= 42 

Lecture : le coefficient de rx (0.727, HR ≈ 2.07, p = 0.022) correspond étroitement à l’ajustement coxme, et la variance de l’effet aléatoire vaut 2.02 — un nombre différent parce que cela utilise une fragilité gamma (multiplicative sur le risque) plutôt que l’effet aléatoire log-normal de coxme (une ordonnée à l’origine aléatoire normale). Les deux décrivent la même variation inter-portées sur des échelles différentes ; la conclusion — un groupement substantiel, un HR du médicament proche de 2 — est la même.

NotePourquoi préférer coxme aujourd’hui ?

coxph(frailty()) est une approximation par vraisemblance pénalisée que Therneau lui-même considère comme supplantée. coxme ajuste l’effet aléatoire par une véritable vraisemblance de modèle mixte (intégrée), se généralise proprement à plusieurs effets aléatoires croisés et à des pentes aléatoires ((rx | center)), et se lit comme le reste du monde des modèles mixtes lme4. Utilisez coxme pour vos nouveaux travaux ; reconnaissez coxph(frailty()) dans le code hérité.

La figure emblématique : les effets aléatoires par groupe (un caterpillar plot)

Un modèle de fragilité vous fournit un effet aléatoire prédit — un BLUP (best linear unbiased predictor) — pour chaque groupe : de combien le risque de base de cette portée se situe au-dessus ou au-dessous de la moyenne. Extrayez-les avec ranef() et tracez un caterpillar plot (l’équivalent en effets aléatoires d’un forest plot), ordonné de la plus faible à la plus forte fragilité. ggforest() ne prend pas en charge coxme, donc construisez-le directement dans ggplot2 :

library(survival)
library(coxme)
library(ggplot2)

fit <- coxme(Surv(time, status) ~ rx + (1 | litter), data = rats)

# Extract the per-litter random effects (BLUPs) and order them
re <- ranef(fit)$litter
df <- data.frame(litter = names(re), frailty = as.numeric(re))
df <- df[order(df$frailty), ]
df$rank <- seq_len(nrow(df))

ggplot(df, aes(x = rank, y = frailty)) +
  geom_hline(yintercept = 0, linetype = "dashed", colour = "grey50") +
  geom_point(colour = "#3a86d4", size = 1.6) +
  labs(x = "Litter (ordered by frailty)", y = "Random effect (log-hazard)",
       title = "Per-litter frailty from the coxme model") +
  theme_minimal()

A caterpillar plot of the estimated per-litter random effects from a coxme shared-frailty model on the rats data. Each of the 100 litters is a point at its predicted log-hazard random effect, sorted from the lowest (most protective) frailty on the left to the highest (most at-risk) on the right, with a horizontal dashed line at zero marking the average litter. The points fan out well above and below zero, showing that litters differ substantially in baseline tumor risk.

Lecture : chaque point est l’effet aléatoire d’une portée sur l’échelle du log-risque. Les portées à droite (positif) ont un risque de tumeur de base plus élevé que la moyenne ; les portées à gauche (négatif) sont protégées. La dispersion — la plupart des portées dans une plage d’environ ±0.5, avec quelques-unes nettement plus hautes — est la variance de fragilité rendue visible : une variation inter-portées substantielle qu’un modèle de Cox ordinaire aurait noyée dans l’erreur. C’est l’image qui montre à un relecteur pourquoi vous aviez besoin de la fragilité.

Événements récurrents : une fragilité par sujet pour les événements répétés

La fragilité ne sert pas qu’aux groupes de sujets — elle modélise aussi les événements répétés chez un même sujet. Lorsqu’un patient peut subir plus d’une fois le même événement (infections récurrentes, réadmissions à l’hôpital), les événements d’un même patient sont corrélés, et le patient est le groupe. Une fragilité par sujet s’en charge :

library(survival)
library(coxme)

# kidney: time to catheter infection, up to 2 events per patient (id = the cluster)
fit.k <- coxme(Surv(time, status) ~ age + sex + (1 | id), data = kidney)
fit.k
Cox mixed-effects model fit by maximum likelihood
  Data: kidney
  events, n = 58, 76
  Iterations= 6 34 
                    NULL Integrated    Fitted
Log-likelihood -187.9028  -181.9045 -166.1653

                  Chisq    df          p   AIC    BIC
Integrated loglik 12.00  3.00 0.00739530  6.00  -0.18
 Penalized loglik 43.48 14.75 0.00011458 13.97 -16.43

Model:  Surv(time, status) ~ age + sex + (1 | id) 
Fixed coefficients
          coef exp(coef)   se(coef)     z      p
age  0.0042892 1.0042984 0.01171041  0.37 0.7100
sex -1.3549853 0.2579511 0.41712539 -3.25 0.0012

Random effects
 Group Variable  Std Dev   Variance 
 id    Intercept 0.6754474 0.4562292

Lecture : kidney enregistre jusqu’à deux temps d’infection de cathéter par patient, donc id est le groupe. Les effets fixes (age, sex) sont ajustés pour la fragilité par patient, et la variance de fragilité mesure l’ampleur de la différence entre patients dans leur taux d’infection sous-jacent — sex montre un fort effet protecteur pour les femmes (HR bien inférieur à 1). Pour la disposition en counting-process dont les données à événements récurrents ont souvent besoin (une ligne par intervalle à risque, Surv(start, stop, status)), voir covariables variant dans le temps ; une fragilité par sujet se superpose dessus de la même façon.

AstuceGroupé vs récurrent — même outil, deux formes
  • Données groupées (patients dans des centres, rats dans des portées) : beaucoup de sujets par groupe, un événement chacun → une fragilité partagée par groupe, (1 | center).
  • Événements récurrents (infections répétées chez un patient) : un sujet, plusieurs événements → une fragilité par sujet, (1 | id), généralement sur une disposition counting-process Surv(start, stop, status).

Un cadrage clinique : un essai multicentrique

La même mécanique donne l’usage clinique canonique — un essai multicentrique où l’institution est un effet aléatoire. Le package coxme fournit le jeu de données eortc précisément pour cela : un essai simulé sur le cancer de la vessie sur 37 centres. Parce que eortc réside dans le package coxme (et non dans le package survival), il n’est pas chargé paresseusement — chargez-le explicitement avec data(eortc) :

library(survival)
library(coxme)
data(eortc)                       # lives in coxme, so data() IS needed here

fit.e <- coxme(Surv(y, uncens) ~ trt + (1 | center), data = eortc)
fit.e
Cox mixed-effects model fit by maximum likelihood
  Data: eortc
  events, n = 1463, 2323
  Iterations= 9 49 
                    NULL Integrated    Fitted
Log-likelihood -10638.71  -10520.65 -10478.84

                   Chisq    df p    AIC    BIC
Integrated loglik 236.11  2.00 0 232.11 221.53
 Penalized loglik 319.74 28.69 0 262.37 110.67

Model:  Surv(y, uncens) ~ trt + (1 | center) 
Fixed coefficients
         coef exp(coef)   se(coef)     z p
trt 0.7086127  2.031171 0.06424398 11.03 0

Random effects
 Group  Variable  Std Dev   Variance 
 center Intercept 0.3292140 0.1083818

Lecture : sur les 37 centres, le traitement porte un HR = exp(0.709) ≈ 2.03 (p < 0.001), et la variance de fragilité des centres vaut 0.108 (SD ≈ 0.33) — les centres diffèrent modestement en risque de base. Comparez l’erreur standard du traitement à un coxph(Surv(y, uncens) ~ trt) naïf (SE ≈ 0.063 dans les deux cas ici, parce qu’avec 1463 événements la variance des centres est faible) : la fragilité importe le plus quand la variance inter-groupe est grande par rapport à l’information intra-groupe. Rapporter la fragilité des centres dit aussi à vos lecteurs que l’effet du traitement est cohérent d’une institution à l’autre, et non porté par un seul site.

Rapport

Parce que les rats étaient appariés par portée, les temps jusqu’à la tumeur au sein d’une portée sont corrélés, nous avons donc ajusté un modèle de Cox à fragilité partagée (à effets mixtes) avec une ordonnée à l’origine aléatoire par portée à l’aide du package coxme. Le traitement était associé à un risque de tumeur plus élevé (HR = 2.08, IC à 95 % 1.11–3.87, p = 0.022), ajusté pour la variation inter-portées. La variance de fragilité estimée par portée valait 1.32 (SD = 1.15 sur l’échelle du log-risque), et un test du rapport de vraisemblance a confirmé que l’effet aléatoire était nécessaire (χ² = 8.35, p = 0.002), indiquant une hétérogénéité substantielle du risque de base entre portées qu’un modèle de Cox standard aurait ignorée.

Écrivez l’ordonnée à l’origine aléatoire de chaque groupe sous la forme \(w_i \sim N(0, \sigma^2)\), de sorte que le multiplicateur de fragilité soit \(u_i = \exp(w_i)\) (log-normal, le défaut de coxme). Le risque pour le sujet \(j\) du groupe \(i\) est :

\[ h_{ij}(t) = h_0(t)\,\exp\!\big(x_{ij}^\top b + w_i\big) \]

Parce que les \(w_i\) sont non observés, coxme les intègre hors de la vraisemblance partielle pour obtenir une vraisemblance marginale (intégrée) en \(b\) et \(\sigma^2\), puis la maximise — la même logique qu’un modèle linéaire généralisé à effets mixtes. Le \(\hat\sigma^2\) estimé est la variance de fragilité que vous lisez sur VarCorr() ; les \(\hat w_i\) prédits sont les BLUP issus de ranef() que vous avez tracés. L’ancien coxph(frailty(..., distribution = "gamma")) prend plutôt \(u_i \sim \text{Gamma}(1/\theta, 1/\theta)\) et ajuste \(\theta\) par vraisemblance pénalisée — une distribution et un estimateur différents pour la même idée, ce qui explique pourquoi sa variance (2.02) est sur une échelle différente du 1.32 de coxme.

Fragilité ou stratification ? Laquelle privilégier

Une fragilité et un modèle de Cox stratifié gèrent tous deux une variable de groupement catégorielle, mais ils répondent à des questions différentes :

AstuceComment gérer une variable de groupement
  • Vous voulez estimer la variation inter-groupe et traiter les groupes comme un échantillon d’une population (généraliser au-delà de ces 37 centres / 100 portées) → une fragilité ((1 | cluster)). Elle coûte un paramètre (la variance) et donne une erreur standard d’effet fixe honnête, ajustée pour la corrélation.
  • Vous avez seulement besoin de contrôler le groupe comme une nuisance, sans intérêt pour sa variation, et vous avez peu de groupes avec beaucoup d’événements chacunstratifiez-le (strata(cluster)) — chaque groupe son propre risque de base, sans hypothèse de variance. Voir Cox stratifié.
  • L’effet du groupe change au cours du temps (il viole les risques proportionnels) → stratification ou un terme variant dans le temps, pas une fragilité (la fragilité suppose un multiplicateur constant).
  • Règle empirique : beaucoup de groupes → fragilité (vous pouvez estimer la variance) ; peu de groupes → stratifiez (une variance issue de 3 groupes n’est pas fiable).

Essayez en direct

Ajustez vous-même un modèle de fragilité — changez le jeu de données, échangez le groupe, ou comparez l’erreur standard d’effet fixe à un coxph() naïf. Le bac à sable démarre au premier Run (il télécharge survival + coxme, donnez-lui donc un instant).

🟢 Avec un agent IA

Demandez à Prova « mes données de survie sont groupées — des patients au sein d’hôpitaux — ajuste un modèle de Cox à fragilité partagée à effets mixtes avec coxme, montre-moi les hazard ratios et la variance de fragilité, et dis-moi si l’effet aléatoire est nécessaire » — elle répond avec du code survival + coxme que vous pouvez exécuter sur vos propres données. The runtime is the judge. Demander à Prova →

Problèmes courants

Vous avez ignoré le groupement et fait confiance aux erreurs standard du coxph() naïf. C’est toute la raison d’être des modèles de fragilité : quand les sujets sont corrélés (même centre, même patient, même portée), coxph() compte chacun comme indépendant et rapporte une erreur standard trop petite, donc les intervalles de confiance sont trop étroits et les p-values trop optimistes. Si votre plan comporte un regroupement naturel, modélisez-le — soit une fragilité (coxme), soit, si vous avez seulement besoin d’une erreur standard robuste sans estimer la variance, coxph(..., cluster = id) pour une variance sandwich (robuste).

Vous avez confondu fragilité et stratification. Elles ne sont pas interchangeables. Une fragilité estime la variance inter-groupe et traite les groupes comme un échantillon aléatoire — utilisez-la avec beaucoup de groupes quand vous tenez à la variation et voulez généraliser. La stratification donne à chaque groupe son propre risque de base et n’estime rien à son sujet — utilisez-la avec peu de groupes qui sont des facteurs de confusion gênants. Une variance estimée à partir de 3 centres n’a aucun sens ; une fragilité issue de 100 portées est informative.

Le modèle ne converge pas, ou la variance se fixe à zéro. Trop peu de groupes, ou trop peu d’événements par groupe, ne laisse rien à estimer à l’effet aléatoire — coxme peut rapporter une variance proche de zéro ou ne pas converger. Il vous faut un nombre raisonnable de groupes (un plancher approximatif de ~5–10, confortable avec ≥ 20) et quelques événements répartis entre eux. Avec trop peu de groupes, stratifiez plutôt, ou abandonnez l’effet aléatoire si un test du rapport de vraisemblance dit qu’il n’est pas nécessaire.

Questions fréquentes

Un modèle de fragilité est un modèle de Cox avec un effet aléatoire (la fragilité) ajouté pour des temps de survie groupés ou corrélés. Chaque groupe — un hôpital, un patient avec des événements récurrents, une portée — obtient son propre multiplicateur non observé sur le risque de base, partagé par tous les membres du groupe. C’est la version, pour les données de survie, d’un modèle à effets mixtes : des effets fixes pour vos covariables, une ordonnée à l’origine aléatoire pour le groupe. Ajustez-le en R avec coxme(Surv(time, status) ~ x + (1 | cluster), data).

Utilisez le package coxme. La syntaxe reprend lme4 : coxme(Surv(time, status) ~ rx + (1 | center), data), où (1 | center) est une ordonnée à l’origine aléatoire (une fragilité partagée) par centre. Lisez les effets fixes comme dans un modèle de Cox ordinaire (exp(fixef(fit)) pour les hazard ratios) et la variance de fragilité depuis VarCorr(fit). L’ancienne voie coxph(... + frailty(center, distribution = "gamma")) fonctionne aussi, mais coxme est l’approche moderne par modèle mixte.

Une fragilité traite la variable de groupement comme un effet aléatoire — elle estime la variance du risque de base entre groupes et suppose que les groupes sont un échantillon d’une population, de sorte que vous pouvez généraliser au-delà d’eux. La stratification (strata()) donne à chaque groupe son propre risque de base mais n’estime rien à son sujet, traitant le groupe comme une nuisance fixe. Optez pour une fragilité quand vous avez beaucoup de groupes et tenez à la variation inter-groupe ; stratifiez quand vous en avez peu, qui ne sont que des facteurs de confusion.

La variance de fragilité (issue de VarCorr()) est la variance de l’ordonnée à l’origine aléatoire sur l’échelle du log-risque — l’ampleur de la variation du risque de base entre groupes après prise en compte de vos covariables. Prenez sa racine carrée pour l’écart-type : un groupe à un écart-type au-dessus de la moyenne a un risque de base exp(SD) fois la moyenne. Une grande variance signifie que les regroupements diffèrent beaucoup (la fragilité fait un vrai travail) ; une variance proche de zéro signifie que le groupement est négligeable et qu’un modèle de Cox ordinaire suffirait.

Assez pour estimer une variance de manière fiable — une variance calculée à partir de 3 ou 4 groupes n’a aucun sens. Un plancher approximatif se situe autour de 5–10 groupes, et vous êtes à l’aise avec 20 ou plus, idéalement avec plusieurs événements répartis entre eux. Avec trop peu de groupes (ou trop peu d’événements par groupe), coxme peut ne pas converger ou fixer la variance de fragilité à zéro ; dans ce cas, stratifiez plutôt sur la variable, ou abandonnez l’effet aléatoire si un test du rapport de vraisemblance montre qu’il n’est pas nécessaire.

Testez vos connaissances

  1. Exécutez-le. Dans la cellule interactive ci-dessous, ajustez un modèle à fragilité partagée sur les données rats, puis ajustez le coxph() naïf qui ignore les portées. Remplissez le blanc. Comparez l’erreur standard de rx entre les deux modèles — laquelle est la plus grande, et pourquoi ?
  2. Interprétez. Un modèle de fragilité rapporte une variance de fragilité par portée de 0.02 (SD ≈ 0.14) et un test du rapport de vraisemblance pour l’effet aléatoire avec p = 0.61. Le groupement vaut-il la peine d’être modélisé ici ? Que feriez-vous à la place ?

Remplissez le blanc avec litter — le groupe. (1 | litter) est la fragilité partagée. Comparez se(coef) pour rx dans le bloc Fixed coefficients de coxme à se(coef) dans la sortie summary() naïve ; la fragilité l’élargit pour tenir compte des 100 (et non 300) unités indépendantes.

fit  <- coxme(Surv(time, status) ~ rx + (1 | litter), data = rats)
fit
#> Fixed effect rx: coef 0.730, HR 2.08, se 0.318, p 0.022
#> Random effect: litter variance 1.32 (SD 1.15)

naive <- coxph(Surv(time, status) ~ rx, data = rats)
summary(naive)$coefficients
#> rx: coef 0.714, HR 2.04, se 0.309, p 0.021

L’erreur standard de coxme (0.318) est plus grande que celle du modèle naïf (0.309). Le modèle de fragilité sait que les 300 rats proviennent de seulement 100 portées indépendantes, donc il élargit l’erreur standard pour en tenir compte — l’erreur standard plus petite du modèle naïf surestime la précision en traitant des rats corrélés comme indépendants.

Pour la question 2 : non, une variance de fragilité de 0.02 avec un test du rapport de vraisemblance non significatif (p = 0.61) signifie que les groupes diffèrent à peine en risque de base — l’effet aléatoire n’est pas nécessaire. Abandonnez-le et ajustez un coxph() ordinaire ; le modèle plus simple suffit et les portées n’apportent rien.

AstuceVérification rapide

Vous ajustez coxme(Surv(time, status) ~ trt + (1 | hospital), data) sur un essai de 40 hôpitaux et obtenez une variance de fragilité de 0.45 (SD ≈ 0.67) avec un test du rapport de vraisemblance p = 0.003. Que vous apprend cela, et comment rapportez-vous l’effet du traitement ?

Les hôpitaux diffèrent substantiellement en risque de base (écart-type de fragilité 0.67 → un hôpital à un écart-type au-dessus de la moyenne a ~exp(0.67) ≈ 2× le risque de base), et le test du rapport de vraisemblance significatif (p = 0.003) confirme que l’effet aléatoire est nécessaire — modéliser le groupement était le bon choix. Rapportez le hazard ratio de traitement à effet fixe (exp(fixef(fit))) avec son IC à 95 % désormais correctement élargi, plus la variance de fragilité pour documenter l’hétérogénéité inter-hôpitaux, en notant que l’effet du traitement est estimé à travers les hôpitaux plutôt que porté par un seul site.

Conclusion

Vous savez désormais ajuster un modèle de fragilité (Cox à effets mixtes) en R pour des données de survie groupées ou corrélées. Lorsque des sujets partagent un groupe — des patients dans un centre, des événements récurrents chez un patient, des rats dans une portée — un coxph() ordinaire suppose une indépendance qui n’existe pas et rapporte des erreurs standard trop petites. coxme() ajoute une ordonnée à l’origine aléatoire par groupe, (1 | cluster), qui absorbe la variation inter-groupe : vous lisez les hazard ratios des effets fixes comme dans un modèle de Cox ordinaire et la variance de fragilité qui quantifie l’ampleur de la variation du risque de base entre groupes. Sur les rats appariés par portée, le médicament a à peu près doublé le risque de tumeur (HR = 2.08) tandis que les portées différaient substantiellement en risque de base (variance de fragilité 1.32, LRT p = 0.002). Vous l’avez comparé avec le modèle naïf, rencontré l’ancienne voie coxph(frailty()), testé si l’effet aléatoire comptait, et tracé les fragilités par groupe. Optez pour une fragilité quand vous avez beaucoup de groupes et voulez modéliser leur variation ; stratifiez quand vous avez peu de groupes-nuisances à la place.

Leçons connexes

Cette page vous a-t-elle été utile ?

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.

Commencer gratuitement →

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

Passer à Pro →

✓ Vous êtes Pro — continuez. The runtime is the judge.

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.

Partager cette pageXLinkedInRedditHN
Note

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.

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {Modèles de fragilité en R : Cox à effets mixtes (coxme)},
  date = {2026-06-26},
  url = {https://www.datanovia.com/learn/biostatistics/survival-analysis/frailty-models},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“Modèles de fragilité en R : Cox à effets mixtes (coxme).” 2026. June 26. https://www.datanovia.com/learn/biostatistics/survival-analysis/frailty-models.