TP – Modèles de durée sous R

Master 2 – Économétrie appliquée

Author

Etienne Dagorn

Published

December 1, 2025

Exercice 1 – Exploration des données et construction de Surv()

Objectif : comprendre la structure des données et coder correctement la durée et la censure.

# 1. Aperçu général du data.frame
#    - Utilisez par exemple : head(df), str(df), summary(df)
#    - L'objectif est d'identifier les variables disponibles.
# (À vous de compléter ci-dessous)

# 2. Identifier la variable de durée
#    - Cherchez la variable qui mesure le temps de suivi (en jours).
#    - Notez son nom en commentaire.

# 3. Identifier la variable d'événement (décès)
#    - Regardez la variable 'status' et sa documentation (?pbc)
#    - Quels codes correspondent à : censure, greffe, décès ?
#    - Notez vos réponses en commentaire.

# 4. Calculer la proportion de censures
#    - Construisez un indicateur logique (TRUE/FALSE) pour la censure.
#    - Utilisez mean(indic_censure) pour obtenir la proportion.

# 5. Créer l'objet de survie S avec Surv()
#    - Utilisez Surv(time = ..., event = ...)
#    - Attention : pour l'événement, il faut un 0/1 ou TRUE/FALSE.
#    - Vérifiez l'affichage de S pour bien repérer les '+' (censure).

# Espace de code pour vos réponses :

Exercice 2 – Kaplan–Meier et calculs « à la main »

Objectif : construire une table (t_i, d_i, n_i), en déduire hazard et survie, et comparer à survfit().

# 1. Créer un sous-échantillon de taille 200
#    - Utilisez set.seed(123) pour la reproductibilité.
#    - Utilisez sample_n(df, 200) avec {dplyr}.
#    - Créez une nouvelle variable event = 1 si décès, 0 sinon (status == 2).

# 2. Construire la table des événements
#    - Ne garder que les lignes avec event == 1.
#    - Compter, pour chaque temps, le nombre de décès d_i (fonction count()).
#    - Stocker le résultat dans un data.frame, par ex. `events`.

# 3. Calculer n_i (nombre à risque juste avant t_i)
#    Idée :
#    - n = nombre total d'individus dans votre sous-échantillon.
#    - À chaque temps t_i, on retire les décès précédents.
#    - Utilisez cumsum(d_i) pour le cumul des décès.
#    - Construisez n_i = n - cumul_décès_précédents (en décalant avec lag()).

# 4. Calculer le hazard discret h_i et la survie S_i
#    - h_i = d_i / n_i
#    - S_i = produit cumulé de (1 - h_i) (fonction cumprod()).

# 5. Comparer à la KM de survfit()
#    - Construisez S_sub <- Surv(time, event) sur votre sous-échantillon.
#    - Utilisez survfit(S_sub ~ 1) pour obtenir la KM.
#    - Tracez vos courbes (S_i) avec ggplot2 et comparez visuellement.

# Espace de code pour vos réponses :

Exercice 3 – Hazard cumulé de Nelson–Aalen

Objectif : calculer le hazard cumulé H(t) et la survie approchée exp(–H(t)) à partir de votre table.

# À partir de la table construite à l'exercice 2 (contenant t_i, d_i, n_i) :

# 1. Calculer H_i = somme cumulée de d_i / n_i
#    - Vous pouvez utiliser cumsum(d_i / n_i).
#    - Ajoutez H_i comme nouvelle colonne.

# 2. Calculer S_na = exp(-H_i)
#    - Ajoutez S_na comme nouvelle colonne.

# 3. Tracer :
#    - H_i en fonction de t_i (geom_step()).
#    - S_i (de l'exercice 2) et S_na sur le même graphique
#      pour comparer les deux survies.

# 4. Observer :
#    - La forme (convexe/concave/linéaire) de H(t).
#    - Les écarts entre S_i et S_na en début / milieu / fin de période.

# Espace de code pour vos réponses :

Exercice 4 – Courbes KM par groupe et test du log-rank

Objectif : comparer la survie entre groupes (ici : sexe) et utiliser le test du log-rank.

# 1. Créer l'objet de survie global S si ce n'est pas déjà fait
#    - S <- Surv(time = df$time, event = df$status == 2)

# 2. Estimer les courbes KM par sexe
#    - Utilisez survfit(S ~ sex, data = df).
#    - Tracez les courbes avec ggsurvplot().
#    - Ajoutez éventuellement un tableau de risqué (risk.table = TRUE).

# 3. Test du log-rank
#    - Utilisez survdiff(S ~ sex, data = df).
#    - Récupérez la statistique de test (test$chisq).
#    - Calculez le p-value avec pchisq() (ou laissez R l'afficher si vous savez faire).

# 4. Interprétation (en commentaire)
#    - Les courbes sont-elles clairement séparées ?
#    - Le p-value est-il petit ou grand ?
#    - Que concluez-vous sur la différence de survie entre sexes ?

# Espace de code pour vos réponses :

Exercice 5 – Modèles paramétriques (exponentiel et Weibull)

Objectif : estimer des modèles exponentiel et Weibull, puis comparer leur ajustement.

# 1. Modèle exponentiel sans covariables
#    - Utilisez survreg(S ~ 1, data = df, dist = "exponential").
#    - Inspectez la sortie du modèle (summary()).

# 2. Récupérer le paramètre lambda
#    - Regardez comment survreg paramètre le modèle exponentiel.
#    - Construisez lambda_hat à partir de l'objet renvoyé.

# 3. Modèle Weibull sans covariables
#    - Utilisez survreg(S ~ 1, data = df, dist = "weibull").
#    - Récupérez les paramètres de forme et d'échelle.

# 4. Comparer exponentiel vs Weibull
#    - Comparez AIC(m_exp, m_weib) et BIC(m_exp, m_weib).
#    - Si vous voulez, superposez la survie théorique (via stat_function()) à la KM.

# 5. Médianes théoriques
#    - Pour chaque modèle, calculez la médiane théorique de la durée.
#    - Comparez-les à la médiane de la KM.

# Espace de code pour vos réponses :

Exercice 6 – Modèles de Cox (PH) et AFT (Weibull)

Objectif : introduire des covariables et comparer les approches PH et AFT.

# 1. Modèle de Cox
#    - Estimez coxph(S ~ age + sex + bili, data = df).
#    - Affichez le résumé et interprétez les signes des coefficients (en commentaire).
#    - Calculez les hazard ratios avec exp(coef()).

# 2. Vérification de l'hypothèse de risques proportionnels
#    - Utilisez cox.zph() sur votre modèle coxph.
#    - Notez les p-values et regardez si certaines covariables semblent violer PH.

# 3. Modèle AFT Weibull
#    - Estimez survreg(S ~ age + sex + bili, data = df, dist = "weibull").
#    - Calculez les time ratios avec exp(coef()).
#    - Interprétez en 1–2 phrases l'effet d'au moins une covariable (en commentaire).

# 4. Comparaison des modèles
#    - Comparez AIC(cox_model) et AIC(aft_model).
#    - Discutez (en commentaire) des avantages / limites de chaque approche
#      en termes d'interprétation (hazard vs durée).

# Espace de code pour vos réponses :