library(tidyverse)
library(survival)
library(ggsurvfit)
library(tidycmprsk)
head(trial)
%>%
trial count(death_cr)
O que são Riscos Competitivos?
Em estudos de tempo até evento, frequentemente nos deparamos com situações onde múltiplos desfechos podem ocorrer, mas apenas um será observado para cada indivíduo. Por exemplo, em um estudo sobre recaída de câncer, um paciente pode morrer por outras causas antes que a recaída seja observada, tornando impossível a ocorrência do evento de interesse. Esse cenário caracteriza os chamados riscos competitivos.
Quando múltiplos tipos de eventos são possíveis e a ocorrência de um exclui os demais, o uso de técnicas tradicionais de análise de sobrevivência pode levar a interpretações incorretas.
Por que os Modelos Tradicionais Falham?
O problema central é que eventos competitivos não são censuras verdadeiras. Quando um paciente morre por outras causas em um estudo sobre recaída, essa informação é altamente relevante: sabemos com certeza que a recaída nunca ocorrerá para esse indivíduo. Tratar isso como censura (assumindo que o evento ainda poderia ocorrer) leva à superestimação da incidência acumulada.
Tratar um evento competitivo como censura é incorreto: ele informa que o evento de interesse não poderá mais ocorrer.
Essa abordagem leva à superestimação da incidência acumulada do evento principal. Por isso, em contextos com riscos competitivos, é fundamental adotar modelos que levem esses eventos em consideração.
Função de Incidência Cumulativa
A Função de Incidência Cumulativa (em inglês, cumulative incidence function - CIF) responde à pergunta: “Qual a probabilidade de que o evento de interesse ocorra até o tempo t, considerando que outros eventos podem impedir sua ocorrência?”
A CIF, para o evento
Podemos reescrever essa expressão como
Essa integral é estimada numericamente por meio de um somatório sobre os tempos de falha:
é a função de sobrevivência estimada “imediatamente” antes do tempo , neste caso, é a estimativa do risco específico da causa no tempo , com eventos da causa e indivíduos em risco nesse tempo.
Exemplo
Vamos ilustrar essa técnica com os dados trial
, em que vamos considerar death from cancer como o desfecho de interesse e death other causes como o risco competitivo.
trt | age | marker | stage | grade | response | death | death_cr | ttdeath |
---|---|---|---|---|---|---|---|---|
Drug A | 23 | 0.160 | T1 | II | 0 | 0 | censor | 24.00 |
Drug B | 9 | 1.107 | T2 | I | 1 | 0 | censor | 24.00 |
Drug A | 31 | 0.277 | T1 | II | 0 | 0 | censor | 24.00 |
Drug A | NA | 2.067 | T3 | III | 1 | 1 | death other causes | 17.64 |
Drug A | 51 | 2.767 | T4 | III | 1 | 1 | death other causes | 16.43 |
Drug B | 39 | 0.613 | T4 | I | 0 | 1 | death from cancer | 15.64 |
Veja que são três desfechos possíveis:
%>%
trial count(death_cr)
death_cr | n |
---|---|
censor | 88 |
death from cancer | 57 |
death other causes | 55 |
A função cuminc()
do pacote tidycmprsk
calcula diretamente a CIF para os dois desfechos (death from cancer e death other causes):
<- cuminc(Surv(ttdeath, death_cr) ~ 1, data = trial)
fit
fit
time n.risk estimate std.error 95% CI
5.00 199 0.000 0.000 NA, NA
10.0 189 0.030 0.012 0.012, 0.061
15.0 158 0.120 0.023 0.079, 0.169
20.0 116 0.215 0.029 0.161, 0.274
time n.risk estimate std.error 95% CI
5.00 199 0.005 0.005 0.000, 0.026
10.0 189 0.025 0.011 0.009, 0.054
15.0 158 0.090 0.020 0.055, 0.135
20.0 116 0.205 0.029 0.152, 0.264
Note que, com essa função, já obtemos a curva de incidência para os dois desfechos.
Visualização da CIF
Podemos utilizar ggcuminc()
para gerar as curvas para os dois desfechos:
%>%
fit ggcuminc(outcome = c("death from cancer", "death other causes")) +
labs(y = "Cumulative Incidence Function", x = "Tempo", color = "Causa") +
theme_bw()
Como a CIF é Calculada “Na Mão”
Vamos reproduzir o cálculo passo a passo. Para isso, vamos estimar a sobrevivência km_total
. Note que a variável death
indica “death from cancer” ou “death other causes”. Para estimar km_cancer
e km_other
.
Vamos agora reproduzir a estimativa da CIF com base na seguinte fórmula discreta:
# death: indicador de óbito (qualquer causa)
# death_cr: fator com níveis: "censor", "death from cancer", "death other causes"
<- survfit2(Surv(ttdeath, death) ~ 1, data = trial) %>%
km_total tidy_survfit()
<- survfit2(Surv(ttdeath, death) ~ 1,
km_cancer data = filter(trial, death_cr != "death other causes")) %>%
tidy_survfit()
<- survfit2(Surv(ttdeath, death) ~ 1,
km_other data = filter(trial, death_cr != "death from cancer")) %>%
tidy_survfit()
Agora vamos calcular a incidência para cada instante de falha.
<- km_total %>%
km_grouped left_join(km_cancer %>%
select(time, n.event_cancer = n.event), by = "time") %>%
left_join(km_other %>%
select(time, n.event_other = n.event), by = "time") %>%
mutate_at(vars(n.event_cancer, n.event_other),
~ case_when(is.na(.x) ~ 0, TRUE ~ .x)) %>%
mutate(i_cancer = 0, i_other = 0)
for (i in 2:nrow(km_total)) {
$i_cancer[i] <- (km_grouped$n.event_cancer[i] / km_grouped$n.risk[i]) *
km_grouped$estimate[i - 1]
km_grouped
$i_other[i] <- (km_grouped$n.event_other[i] / km_grouped$n.risk[i]) *
km_grouped$estimate[i - 1]
km_grouped
}
Agora podemos calcular a curva de incidência cumulativa fazendo a soma acumulada da incidência de cada desfecho.
<- km_grouped %>%
cum_inc select(time, i_cancer, i_other) %>%
mutate(cif_cancer = cumsum(replace_na(i_cancer, 0)),
cif_other = cumsum(replace_na(i_other, 0)))
O vetor cif_cancer
obtido pela fórmula discreta é numericamente equivalente à curva estimada automaticamente por cuminc()
— veja abaixo:
$cif_cancer
cum_inc$tidy$estimate[fit$tidy$outcome == "death from cancer"] fit
Agora vamos utilizar um gráfico do tipo escada para plotar a curva de incidiência acumulada de câncer e outras causas. Compare o gráfico abaixo, obtido manualmente, com o gráfico da Figura Figure 1 gerado automaticamente. Eles coincidem, o que valida a implementação da fórmula discreta da CIF
%>%
cum_inc select(time, cif_cancer, cif_other) %>%
pivot_longer(
cols = c(cif_cancer, cif_other),
names_to = "cause",
values_to = "cif"
%>%
) arrange(cause, time) %>%
ggplot(aes(x = time, y = cif, color = cause)) +
geom_step() +
labs(y = "Cumulative Incidence Function", x = "Tempo", color = "Causa") +
theme_bw()
Caso queira apresentar a CIF de acordo com grupo de tratamento, considere o seguinte comando:
cuminc(Surv(ttdeath, death_cr) ~ trt, data = trial) %>%
ggcuminc(outcome = c("death from cancer", "death other causes")) +
labs(y = "Cumulative Incidence Function", x = "Tempo") +
add_risktable() +
scale_ggsurvfit()
Teste de Gray
Se o objetivo for comparar as curvas CIF entre os grupos, é possível utilizar diretamente o teste de Gray (Gray, 1988).
cuminc(Surv(ttdeath, death_cr) ~ trt, trial)
strata time n.risk estimate std.error 95% CI
Drug A 5.00 97 0.000 0.000 NA, NA
Drug A 10.0 94 0.020 0.014 0.004, 0.065
Drug A 15.0 83 0.071 0.026 0.031, 0.134
Drug A 20.0 61 0.173 0.039 0.106, 0.255
Drug B 5.00 102 0.000 0.000 NA, NA
Drug B 10.0 95 0.039 0.019 0.013, 0.090
Drug B 15.0 75 0.167 0.037 0.102, 0.246
Drug B 20.0 55 0.255 0.043 0.175, 0.343
strata time n.risk estimate std.error 95% CI
Drug A 5.00 97 0.010 0.010 0.001, 0.050
Drug A 10.0 94 0.020 0.014 0.004, 0.065
Drug A 15.0 83 0.082 0.028 0.038, 0.147
Drug A 20.0 61 0.204 0.041 0.131, 0.289
Drug B 5.00 102 0.000 0.000 NA, NA
Drug B 10.0 95 0.029 0.017 0.008, 0.077
Drug B 15.0 75 0.098 0.030 0.050, 0.165
Drug B 20.0 55 0.206 0.040 0.133, 0.289
outcome statistic df p.value
death from cancer 1.99 1.00 0.16
death other causes 0.089 1.00 0.77
Modelo de Fine & Gray
O modelo de Fine & Gray (Fine e Grey, 1999) é uma extensão dos modelos de risco proporcional (como o de Cox), mas voltado para modelar diretamente a função de incidência cumulativa (CIF), levando em conta os riscos competitivos. Nesse modelo, as curvas CIF são chamadas de funções de subdistribuição.
O modelo de Fine & Gray atua sobre o risco/hazard da subdistribuição denotado por
é a função de risco de base da subdistribuição, é o vetor de covariáveis são os coeficientes a serem estimados.
Como o modelo de Fine & Gray estima o efeito das covariáveis (
- Máxima verossimilhança parcial
A estimativa de
se o evento de interesse ocorreu para o indivíduo no tempo e 0 caso contrário. são as covariáveis do indivíduo .
- Conjunto de risco estendido
- Inclui dois grupos:
- Indivíduos ainda em risco (não sofreram nenhum evento até
) - Indivíduos que sofreram um evento competitivo antes de
- Indivíduos ainda em risco (não sofreram nenhum evento até
Isso é diferente do modelo de Cox tradicional, que exclui os que tiveram eventos competitivos.
- Pesos
- Indivíduos sem eventos prévios (em risco convencional) têm peso
. - Indivíduos com eventos competitivos antes de
recebem peso , onde é a função de sobrevivência para a censura (não para os eventos).- O peso
para indivíduos com eventos competitivos é menor que 1 e diminui com o tempo, reduzindo sua influência na verossimilhança.
- Interpretação do “risco”:
Manter indivíduos com eventos competitivos no conjunto em risco é “não natural”, pois eles já não podem sofrer o evento de interesse.
Por isso, o hazard da subdistribuição (SHR) não deve ser interpretado como um risco instantâneo tradicional (HR do Cox).
- SHR > 1: A probabilidade acumulada do evento de interesse cresce mais rápido no grupo exposto.
- SHR < 1: A probabilidade acumulada cresce mais devagar.
Por que essa abordagem?
O modelo “empresta” informação de indivíduos com eventos competitivos, mas atribui a eles pesos decrescentes (pois sua influência diminui com o tempo).
Isso permite estimar diretamente o efeito sobre a incidência acumulada (CIF), que é clinicamente mais relevante em cenários com riscos competitivos.
No R, podemos utilizar o modelo de Fine & Gray com a função crr
:
<- crr(
(crr_mod Surv(ttdeath, death_cr) ~ trt,
failcode = "death from cancer",
data = trial
))
Variable Coef SE HR 95% CI p-value
trtDrug B 0.377 0.265 1.46 0.87, 2.45 0.16
O SHR estimado para o tratamento ‘Drug B’ é de 1.46. Isso significa que a incidência cumulativa de morte por câncer cresce 46% mais rapidamente no grupo Drug B comparado ao Drug A.
::tidy(crr_mod, exponentiate = TRUE, conf.int = TRUE) broom
# A tibble: 1 × 7
term estimate std.error statistic conf.low conf.high p.value
<chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 trtDrug B 1.46 0.265 1.42 0.867 2.45 0.16
Quando usar esse modelo?
O modelo de Fine & Gray é indicado quando:
- Existe mais de um tipo de evento possível;
- Um evento impede a ocorrência do outro;
- O foco está em probabilidades absolutas (e não apenas razões instantâneas de risco).
Exemplos práticos:
- Tempo até alta hospitalar com óbito como risco competitivo;
- Tempo até falência de órgão com transplante como risco competitivo;
- Tempo até internação por COVID com morte por outras causas como risco competitivo.
Conclusão
A presença de riscos competitivos muda completamente a forma como devemos analisar dados de tempo até evento. O modelo de Fine & Gray — facilmente acessado via tidycmprsk::crr()
— oferece uma alternativa estatisticamente consistente para estimar e interpretar efeitos marginais na probabilidade acumulada do evento de interesse.
Ao usar esse modelo, estamos respeitando a estrutura real dos dados e evitando vieses que podem comprometer interpretações clínicas, econômicas ou políticas.
Resumo Prático
- Problema: Eventos competitivos não são censuras - eles impedem definitivamente o evento de interesse
- Solução: Use CIF em vez de Kaplan-Meier para estimar probabilidades corretas
- Modelagem: Modelo de Fine & Gray para analisar efeitos de covariáveis
- Interpretação: SHR ≠ HR tradicional - foca na velocidade de acúmulo da probabilidade
- R: Pacote
tidycmprsk
eggsurvfit
facilitam toda a implementação
Relações
Algumas identidades utilizadas ao longo do texto.
Referências
Fine, Jason P., and Robert J. Gray. (1999). “A Proportional Hazards Model for the Subdistribution of a Competing Risk.” Journal of the American Statistical Association 94 (446): 496–509. doi:10.1080/01621459.1999.10474144
Kleinbaum, David G., and Mitchel Klein. (2012) Survival Analysis: A Self-Learning Text. 3rd ed. New York: Springer.
Robert J. Gray. (1988). “A Class of K-Sample Tests for Comparing the Cumulative Incidence of a Competing Risk.” Ann. Statist. 16 (3) 1141 - 1154. https://doi.org/10.1214/aos/1176350951
Sjoberg DD, Fei T (2024). tidycmprsk: Competing Risks Estimation. R package version 1.1.0, https://github.com/MSKCC-Epi-Bio/tidycmprsk, https://mskcc-epi-bio.github.io/tidycmprsk/.
Sjoberg D, Baillie M, Fruechtenicht C, Haesendonckx S, Treis T (2025). ggsurvfit: Flexible Time-to-Event Figures. R package version 1.1.0, https://github.com/pharmaverse/ggsurvfit.