Objectif — Question 2

Les Parties 1 et 2 ont estimé l’effet de l’initiation de l’exposition \(A_0\), sans se préoccuper de ce qui se passe ensuite (les patients peuvent arrêter ou débuter le traitement par la suite). C’est l’analogue-ITT.

Cette partie répond à une nouvelle question : quel serait l’effet si les patients avaient maintenu leur stratégie d’exposition tout au long du suivi ?

\[S^{\bar{a}=1}(t) = P(T^{\bar{a}=1} > t) \quad \text{et} \quad S^{\bar{a}=0}(t) = P(T^{\bar{a}=0} > t)\]

Stratégie : grouper les individus selon \(A_0\), puis censurer artificiellement tout individu qui dévie de sa stratégie initiale. Cette censure est très probablement informative (les patients qui changent de traitement diffèrent des autres) → on corrige par IPCW. Les poids IPTW de la Partie 2 sont conservés pour l’équilibre initial.

Note sur la session R

Les variables suivantes sont disponibles dans vos chunks interactifs (reconstruites dans le contexte de setup) :

  • df : base avec A0, L0 propagés
  • df$ps : score de propension \(P(A_0=1 \mid X, L_0)\)
  • df$iptw.s : poids IPTW stabilisés (de la Partie 2)

Étape 1 — Définir les deux groupes de stratégie

Créez df.1 (individus avec A0 == 1) et df.0 (individus avec A0 == 0).

Montrez moi comment faire !
df.1 <- df[df$A0 == 1, ]
df.0 <- df[df$A0 == 0, ]

cat("Individus avec A0=1 :", length(unique(df.1$id)), "\n")
cat("Individus avec A0=0 :", length(unique(df.0$id)), "\n")

Étape 2 — Censure artificielle dans le groupe A0 = 1

Pour la stratégie \(\bar{a} = 1\), un individu dévie dès qu’il arrête le traitement (\(A = 0\) à une visite ultérieure).

Dans df.1, créez switchA : 0 tant que l’individu suit la stratégie, 1 à la première déviation. Conservez toutes les lignes jusqu’à switchA ≤ 1 (on garde la ligne de déviation pour estimer le modèle de poids).

Montrez moi comment faire !
df.1 <- df.1 |>
  group_by(id) |>
  mutate(
    cumsumA = cumsum(A == 1),
    ## Si A=1 à toutes les visites, cumsumA == T.start + 1
    switchA = if_else(cumsumA == T.start + 1, 0L, 1L),
    switchA = cumsum(switchA)
  ) |>
  filter(switchA <= 1) |>
  ungroup()

table(df.1$switchA)

Étape 3 — Modèle de déviation et poids IPCW (groupe A0 = 1)

On estime la probabilité de ne pas dévier à chaque visite par régression logistique poolée (pooled logistic regression), puis on calcule les poids IPCW :

\[W_i(t) = \prod_{k=0}^{t} \frac{1}{P(\text{switch}_{ik}=0 \mid X_i, L_{ik})} \qquad t = 0, 1, 2\]

Ajustez wt.mod.1 <- glm(switchA ~ as.factor(T.start) + X + L, ...) sur df.1, stockez wt.denom = \(P(\text{switch}=0)\) prédit. Supprimez les lignes switchA == 1. Calculez wt = produit cumulé de 1/wt.denom.

Montrez moi comment faire !
## Modèle poolé de déviation dans df.1
wt.mod.1 <- glm(switchA ~ as.factor(T.start) + X + L,
                family = "binomial", data = df.1)

## Probabilité de ne pas dévier
df.1$wt.denom <- 1 - predict(wt.mod.1, type = "response", newdata = df.1)

## Supprimer la ligne de déviation
df.1 <- df.1[df.1$switchA == 0, ]

## Poids IPCW : produit cumulé de 1/P(no switch)
df.1 <- df.1 |>
  group_by(id) |>
  mutate(wt = cumprod(1 / wt.denom)) |>
  ungroup()

summary(df.1$wt)

Étape 4 — Répéter pour le groupe A0 = 0

Reproduire les étapes 2 et 3 pour df.0 (déviation = passer de \(A=0\) à \(A=1\)). Empiler ensuite df.1 et df.0 dans dfpp.

Montrez moi comment faire !
## Censure artificielle dans df.0
df.0 <- df.0 |>
  group_by(id) |>
  mutate(
    cumsumA = cumsum(A == 0),
    switchA = if_else(cumsumA == T.start + 1, 0L, 1L),
    switchA = cumsum(switchA)
  ) |>
  filter(switchA <= 1) |>
  ungroup()

## Modèle poolé de déviation dans df.0
wt.mod.0      <- glm(switchA ~ as.factor(T.start) + X + L,
                     family = "binomial", data = df.0)
df.0$wt.denom <- 1 - predict(wt.mod.0, type = "response", newdata = df.0)
df.0          <- df.0[df.0$switchA == 0, ]
df.0          <- df.0 |>
  group_by(id) |>
  mutate(wt = cumprod(1 / wt.denom)) |>
  ungroup()

## Empilement
dfpp <- rbind(df.1, df.0)
cat("Lignes dans dfpp :", nrow(dfpp), "\n")

Étape 5 — Poids combinés IPTW × IPCW

Les poids IPCW (wt) corrigent la censure artificielle informative. Mais ils ne rééquilibrent pas encore les caractéristiques initiales entre \(A_0=1\) et \(A_0=0\). Il faut combiner avec les poids IPTW estimés en Partie 2.

Calculez dfpp$comb.wt = dfpp$iptw.s * dfpp$wt, puis vérifiez la distribution.

Montrez moi comment faire !
dfpp$comb.wt <- dfpp$iptw.s * dfpp$wt

cat("Poids IPCW seuls  - moy:", round(mean(dfpp$wt), 3),
    " / max:", round(max(dfpp$wt), 2), "\n")
cat("Poids combinés    - moy:", round(mean(dfpp$comb.wt), 3),
    " / max:", round(max(dfpp$comb.wt), 2), "\n")
Note

Pourquoi multiplier ? Les poids IPTW rééquilibrent les groupes sur les caractéristiques initiales (\(X\), \(L_0\)). Les poids IPCW compensent la censure artificielle informative au cours du suivi (\(L_t\), \(A_t\)). Les deux sources de biais sont indépendantes, donc leurs corrections se multiplient.

Étape 6 — Analyse de survie per-protocol

Tracez le Kaplan-Meier pondéré par comb.wt dans dfpp. Comparez avec l’analogue-ITT de la Partie 2.

Montrez moi comment faire !
km.pp <- survfit(Surv(T.start, T.stop, D) ~ A0,
                 data    = dfpp,
                 weights = comb.wt)

plot(km.pp,
     col  = c("#1D2769", "#AC182E"), lwd = 2, conf.int = FALSE,
     xlab = "Temps (années)", ylab = "Probabilité de survie",
     main = "Kaplan-Meier per-protocol (IPTW × IPCW)")
legend("bottomleft",
       legend = c("Stratégie ā=0 (jamais exposé)",
                  "Stratégie ā=1 (toujours exposé)"),
       col = c("#1D2769", "#AC182E"), lwd = 2, bty = "n")

## Différence de survie à 3 ans
s3.pp <- summary(km.pp, times = 3)$surv
cat("Survie à 3 ans - ā=0 :", round(s3.pp[1], 3), "\n")
cat("Survie à 3 ans - ā=1 :", round(s3.pp[2], 3), "\n")
cat("Différence     :", round(diff(s3.pp), 3), "\n")

La différence de survie à 3 ans (per-protocol) est 0.316.

Interprétation

Comparez l’effet per-protocol à l’effet analogue-ITT. Pourquoi peut-il différer ?

  • L’analogue-ITT estime l’effet d’initier l’exposition \(A_0\), quelle que soit la compliance ultérieure. Il dilue l’effet si certains exposés arrêtent leur traitement.
  • L’analogue per-protocol estime l’effet de maintenir l’exposition tout au long du suivi. Il peut être plus fort (si l’exposition continue est nécessaire) ou différent pour d’autres raisons.

Si les deux estimations convergent, l’arrêt du traitement n’a pas d’impact majeur sur la survie. Si elles divergent, la compliance joue un rôle.

Hypothèses supplémentaires nécessaires pour l’analogue-PP :

  • Échangeabilité conditionnelle au cours du temps : \(L_t\) capture tous les facteurs qui prédisent à la fois la déviation et le décès.
  • Positivité au cours du temps : à chaque visite, chaque individu doit avoir une probabilité positive de continuer ou d’arrêter.

Pour continuer, cliquez sur Conclusion dans le menu à gauche.