La insuficiencia cardíaca es una condición clínica compleja y progresiva que afecta a millones de personas en todo el mundo. Comprender los factores que influyen en la supervivencia de los pacientes con insuficiencia cardíaca es crucial para mejorar los resultados clínicos y desarrollar estrategias de intervención más efectivas.
El presente estudio se centra en el análisis del conjunto de datos “heart_failure_clinical_records_dataset”, que contiene información detallada sobre pacientes diagnosticados con insuficiencia cardíaca. Este conjunto de datos incluye una variedad de variables clínicas, tales como la edad, la presencia de anemia, los niveles de creatina fosfoquinasa, diabetes, fracción de eyección, hipertensión arterial, recuento de plaquetas, niveles de creatinina sérica y sodio sérico, sexo, tabaquismo, tiempo de seguimiento y el evento de muerte.
El objetivo principal de este análisis es explorar la relación entre estas variables y el tiempo de supervivencia de los pacientes con insuficiencia cardíaca. Específicamente, buscamos identificar los factores que están asociados con un mayor riesgo de mortalidad y determinar si existen diferencias significativas en la supervivencia entre subgrupos de pacientes, como aquellos definidos por el sexo.
Descripción de las variables
heart_failure_clinical_records_dataset <- read_csv("heart_failure_clinical_records_dataset.csv")
## Rows: 299 Columns: 13
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (13): age, anaemia, creatinine_phosphokinase, diabetes, ejection_fractio...
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
df=heart_failure_clinical_records_dataset
head(df)
## # A tibble: 6 × 13
## age anaemia creatinine_phosphokinase diabetes ejection_fraction
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 75 0 582 0 20
## 2 55 0 7861 0 38
## 3 65 0 146 0 20
## 4 50 1 111 0 20
## 5 65 1 160 1 20
## 6 90 1 47 0 40
## # ℹ 8 more variables: high_blood_pressure <dbl>, platelets <dbl>,
## # serum_creatinine <dbl>, serum_sodium <dbl>, sex <dbl>, smoking <dbl>,
## # time <dbl>, DEATH_EVENT <dbl>
tail(df)
## # A tibble: 6 × 13
## age anaemia creatinine_phosphokinase diabetes ejection_fraction
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 63 1 103 1 35
## 2 62 0 61 1 38
## 3 55 0 1820 0 38
## 4 45 0 2060 1 60
## 5 45 0 2413 0 38
## 6 50 0 196 0 45
## # ℹ 8 more variables: high_blood_pressure <dbl>, platelets <dbl>,
## # serum_creatinine <dbl>, serum_sodium <dbl>, sex <dbl>, smoking <dbl>,
## # time <dbl>, DEATH_EVENT <dbl>
dim(df)
## [1] 299 13
colSums(is.na(df))
## age anaemia creatinine_phosphokinase
## 0 0 0
## diabetes ejection_fraction high_blood_pressure
## 0 0 0
## platelets serum_creatinine serum_sodium
## 0 0 0
## sex smoking time
## 0 0 0
## DEATH_EVENT
## 0
attach(df)
df$DEATH_EVENT[df$DEATH_EVENT == 0]<- 2
df$DEATH_EVENT[df$DEATH_EVENT == 1]<- 1
datos <- df %>%
mutate(rango_edad = cut(age,
breaks = c(0, 18, 30, 45, 60, 100),
labels = c("0-18", "19-30", "31-45", "46-59", "60-95"),
right = FALSE))
ggplot(datos, aes(x = rango_edad)) +
geom_bar(fill = "skyblue", color = "black", alpha = 0.7) +
labs(title = "Distribución de Edades en Rangos", x = "Rango de Edad", y = "Frecuencia") +
theme_minimal()
En la gráfica anterior podemos visualizar el rango de edades de las personas que estamos estudiando.
diabetes_1 <- table(df$sex, df$diabetes)
barplot(diabetes_1,
main="Sexo vs diabetes",
xlab="Presenta diabetes",
ylab="Frecuencias",
legend = rownames(diabetes_1),
ylim = c(0, 180),
col=c("#FFB90F","#1C86EE"),
beside=TRUE
)
Comparamos el tipo de variable sexo 0 con sexo 1 respecto a la variable diabetes en el caso de que no haya presentado diabetes se representa con el número 0 y en caso de que si con el número 1.
Surv(df$time,df$DEATH_EVENT)
## [1] 4+ 6+ 7+ 7+ 8+ 8+ 10+ 10+ 10+ 10+ 10+ 10+ 11+ 11+ 12
## [16] 13+ 14+ 14+ 15+ 15+ 16 20+ 20+ 22 23+ 23+ 24+ 26+ 26+ 26+
## [31] 27+ 28+ 28+ 29 29+ 30+ 30+ 30+ 30 30+ 31+ 32+ 33+ 33 33+
## [46] 35+ 38+ 40+ 41+ 42+ 43+ 43+ 43+ 44+ 45+ 50+ 54 54 55+ 59+
## [61] 60+ 60+ 60 61+ 63 64+ 65+ 65+ 66+ 67+ 68 71 72+ 72 73+
## [76] 73+ 74 74 74 74 75 76 77+ 78 78+ 79 79 79 79 79
## [91] 80 80 82 82+ 83 83 83 85 85 86 87 87 87 87 87
## [106] 88+ 88 88 88 88 90+ 90 90 90+ 91 91 94 94 94 95+
## [121] 95 95 95 95 96+ 97 100+ 104 104 105 106 107 107 107 107
## [136] 107 107 108 108 108 109+ 109 109 110 111+ 112 112 113 113+ 115
## [151] 115+ 117 118 119 120 120 120 120 121 121 121 121 123 126+ 129+
## [166] 130+ 134 135+ 140 145 145 146 146 146 146 146 147 147 147 147
## [181] 148 150+ 154+ 162+ 170+ 171+ 172+ 172+ 172 174 174 174 175 180 180+
## [196] 180+ 185 186 186 186 186 186 186 187 187 187 187 187 187 187
## [211] 188 192 192 193+ 194 195 196 196+ 197 197 198+ 200 201 201 205
## [226] 205 205 206 207 207 207+ 208 209 209 209 209 209 210 210 211
## [241] 212 212 212 213 213 213 214+ 214 214 214 214 215 215 215 215
## [256] 216 220 230 230 231 233 233 235+ 237 237 240 241+ 244 244 244
## [271] 244 244 245 245 245 245 245 246 246 246 247 250 250 250 250
## [286] 250 250 250 256 256 257 258 258 270 270 271 278 280 285
km = Surv(df$time,df$DEATH_EVENT)
km1 = survfit(km~1,data=df,type = "kaplan-meier")
km1
## Call: survfit(formula = km ~ 1, data = df, type = "kaplan-meier")
##
## n events median 0.95LCL 0.95UCL
## [1,] 299 203 186 148 196
El estimador de Kaplan - Meier, es un estimador no paramétrico de la función de supervivencia, con el cual podemos observar el total de individuos en el estudio, el evento, la media y los intervalos de confianza.
ggsurvplot(km1)
Como se observa en la gráfica a medida que aumenta el tiempo, la probabilidad de supervivencia disminuye, la cual esta desde 0 hasta 1 y el tiempo inicia en 0 hasta 300. Se observa que en el tiempo 0, la probabilidad de supervivencia es 1 y a medida que el tiempo aumenta, empieza a disminuir la probabilidad de supervivencia.
Utilizando la función survfit se va a estimar el comportamiento del tiempo de supervivencia dependiendo del sexo del paciente.
km2=surv_fit(Surv(df$time,df$DEATH_EVENT) ~ sex,data = df)
| n | events | median | 0.95LCL | 0.95UCL | |
|---|---|---|---|---|---|
| sex0 | 105 | 71 | 187 | 147 | 210 |
| sex1 | 194 | 132 | 186 | 186 | 200 |
Al utilizar la función surv_fit encontramos los siguientes casos, para el primer caso el sexo 0 se tienen 105 individuos, de los cuales 71 presentaron el evento y una mediana de supervivencia de 187, con un límite de confianza inferior de 147 y el límite de confianza superior de 210. El segundo caso es el sexo 1, en el cual se observa que hay 194 individuos en el estudio, 132 presentaron el evento, con una mediana de 186 y el límite de confianza inferior de 186 y el superior de 200.
A = surv_summary(km2)
## Warning in .get_data(x, data = data): The `data` argument is not provided. Data
## will be extracted from model fit.
head(A)
## time n.risk n.event n.censor surv std.err upper lower strata sex
## 1 8 105 0 1 1.0000000 0.000000000 1 1.0000000 sex=0 0
## 2 10 104 0 1 1.0000000 0.000000000 1 1.0000000 sex=0 0
## 3 12 103 1 0 0.9902913 0.009756214 1 0.9715350 sex=0 0
## 4 15 102 0 2 0.9902913 0.009756214 1 0.9715350 sex=0 0
## 5 16 100 1 0 0.9803883 0.014006920 1 0.9538398 sex=0 0
## 6 20 99 0 1 0.9803883 0.014006920 1 0.9538398 sex=0 0
La función surv_summary nos crea un marco de datos, en el que nos permite visualizar los tiempos en que se estiman las probabilidades de supervivencia, los números de individuos que están en riesgo, los eventos que se han presentado, los números de observaciones censuradas, la estimación de la probabilidad de supervivencia, el error estandar de la probabilidad de supervivencia, los límites de intervalo de confianza y el sexo
Resumen de la información del tiempo de supervivencia
summary(km2)$table
## records n.max n.start events rmean se(rmean) median 0.95LCL 0.95UCL
## sex=0 105 105 105 71 168.4327 7.595082 187 147 210
## sex=1 194 194 194 132 165.6090 5.481873 186 146 200
Con la función summary(km2)$table observamos el número total de observaciones para el análisis, los individuos en riesgo al inicio del estudio, el tiempo de supervivencia promedio hasta un tiempo específico, el error estándar del tiempo de supervivencia medio restringido, el cual mide la variabilidad o incertidumbre en el tiempo medio restringido estimado, también tenemos el tiempo de supervivencia mediano, en el que se espera que el 50% de los individuos hayan experimentado el evento, finalmente tenemos los límites de confianza. La tabla que obtuvimos es complementaria a la que creamos en km2, en esta taba se adiciona el número total de las observaciones el cual corresponde a 105 para el sexo 0 y 194 para sexo 1. Se tiene que el tiempo de supervivencia promedio para el sexo 0 es 168.4327 y sexo 1 de 165.6090, con un error estándar medio de 7.595082 para sexo 0 y para sexo 1 de 5.481873.
ggsurvplot(
km2, # ajuste hecho anteriormente
pval = TRUE, # p-value de la prueba log-rank
conf.int = TRUE, # intervalos de confianza puntuales
conf.int.style = "step", # cambia el estilo de las bandas de confianza
xlab = "Tiempo en días", # título del eje X
break.time.by = 50, # separación de los intervalos en el eje X
ggtheme = theme_light(), # personaliza la gráfica y tabla con un tema
risk.table = "abs_pct", # número absoluto y porcentaje en riesgo
risk.table.y.text.col = T, # color del texto en la tabla de riesgo
risk.table.y.text = FALSE, # muestra barras en lugar de nombres
ncensor.plot = TRUE, # grafica el número de censuras al tiempo t
surv.median.line = "hv", # agrega líneas de la mediana
legend.labs =
c("sex0", "sex1"), # cambia nombres de las categorías
palette =
c("pink", "purple"), # elige los colores
xlim = c(0, 290) # corta el eje X
)
## Warning in geom_segment(aes(x = 0, y = max(y2), xend = max(x1), yend = max(y2)), : All aesthetics have length 1, but the data has 2 rows.
## ℹ Please consider using `annotate()` or provide this layer with data containing
## a single row.
## All aesthetics have length 1, but the data has 2 rows.
## ℹ Please consider using `annotate()` or provide this layer with data containing
## a single row.
## All aesthetics have length 1, but the data has 2 rows.
## ℹ Please consider using `annotate()` or provide this layer with data containing
## a single row.
## All aesthetics have length 1, but the data has 2 rows.
## ℹ Please consider using `annotate()` or provide this layer with data containing
## a single row.
Se utiliza la función survdiff para revisar el número de observaciones, lo observado, lo esperado, Chi-cuadrado por esperado, Chi-cuadrado por varianza, el Chi-cuadrado, los grados de libertad,
lr=survdiff(Surv(df$time,df$DEATH_EVENT)~sex,data=df)
lr
## Call:
## survdiff(formula = Surv(df$time, df$DEATH_EVENT) ~ sex, data = df)
##
## N Observed Expected (O-E)^2/E (O-E)^2/V
## sex=0 105 71 72.1 0.01593 0.026
## sex=1 194 132 130.9 0.00877 0.026
##
## Chisq= 0 on 1 degrees of freedom, p= 0.9
alpha=0.05
qchisq(p=1-alpha,df=1)
## [1] 3.841459
Se evidencia que el resultado del p=0.9, un valor considerado muy alto, lo cual nos indica que no hay evidencia estadística suficiente para rechazar la hipótesis nula
Eventos acumulados
ggsurvplot(km2,
risk.table.col = "strata",
palette = c("pink","purple"),
fun = "event")
En la gráfica anterior se presenta la probabilidad acumuda del evento, respecto al sexo 0 y sexo 1. A medida que avanza el tiempo se evidencia que la supervivencia de los grupos en el tiempo 0 a 100 ha tenido un aumento no tan significativo como el que tuvo posteriormente.
ggsurvplot(km2,
risk.table.col = "strata",
palette = c("pink","purple"),
fun = "cumhaz")
Podemos observar el aumento del riesgo total acumulado para un grupo de
pacientes.