insuficiencia cardíaca
Contexto, objetivos y audiencia
Este capítulo analiza los registros clínicos de pacientes con insuficiencia cardíaca mediante herramientas de visualización y análisis de datos.
El objetivo es convertir los datos en información comprensible para apoyar la administración y gestión de recursos sanitarios. Se estudian variables como la edad, la fracción de eyección, la creatinina sérica y el evento de fallecimiento.
El análisis es descriptivo: permite identificar patrones en los registros, pero no demuestra relaciones causales ni sustituye la valoración del personal de salud.
La audiencia está conformada por directivos de instituciones sanitarias, responsables de calidad, coordinadores de servicios y profesionales de gestión clínica.
Exploracion Analitica de Datos
Consiste en analizar una base de datos de 299 pacientes con insuficiencia cardíaca para conocer sus características clínicas, antecedentes médicos y resultados de seguimiento. Mediante tablas, estadísticas descriptivas y gráficos se identifican patrones, diferencias y posibles valores atípicos. Esta información ayuda a orientar el seguimiento de los pacientes y la planificación de los recursos sanitarios, sin establecer relaciones de causalidad.
archivo <- "base insuficiencia cardiaca.xlsx"
datos <- read_excel(archivo)
columnas_requeridas <- c(
"age", "anaemia", "creatinine_phosphokinase",
"diabetes", "ejection_fraction", "high_blood_pressure",
"platelets", "serum_creatinine", "serum_sodium",
"sex", "smoking", "time", "DEATH_EVENT"
)
if (!all(columnas_requeridas %in% names(datos))) {
stop("La base no contiene todas las columnas esperadas.")
}
cat("Número de registros:", nrow(datos), "\n")## Número de registros: 299
## Número de variables: 13
Probabilidad y Estadistica Aplicada
Permite analizar los resultados clínicos mediante frecuencias, porcentajes, promedios, medianas y medidas de dispersión. También utiliza la correlación de Pearson para identificar posibles relaciones entre variables como la edad, la fracción de eyección y la creatinina sérica. Estas herramientas facilitan la interpretación de los datos y apoyan la toma de decisiones basadas en evidencia, teniendo en cuenta las limitaciones de la muestra.
datos <- datos %>%
mutate(
evento = factor(
DEATH_EVENT,
levels = c(0, 1),
labels = c("Sin fallecimiento", "Con fallecimiento")
),
grupo_edad = cut(
age,
breaks = c(-Inf, 39, 59, 79, Inf),
labels = c("Menos de 40", "40 a 59", "60 a 79", "80 o más"),
right = TRUE
)
)
# Resumen de las variables
knitr::kable(
data.frame(
Variable = names(datos),
Tipo = sapply(datos, function(x) class(x)[1]),
Valores_faltantes = sapply(datos, function(x) sum(is.na(x)))
),
caption = "Descripción y calidad de los datos"
)| Variable | Tipo | Valores_faltantes | |
|---|---|---|---|
| age | age | numeric | 0 |
| anaemia | anaemia | numeric | 0 |
| creatinine_phosphokinase | creatinine_phosphokinase | numeric | 0 |
| diabetes | diabetes | numeric | 0 |
| ejection_fraction | ejection_fraction | numeric | 0 |
| high_blood_pressure | high_blood_pressure | numeric | 0 |
| platelets | platelets | character | 0 |
| serum_creatinine | serum_creatinine | character | 0 |
| serum_sodium | serum_sodium | numeric | 0 |
| sex | sex | numeric | 0 |
| smoking | smoking | numeric | 0 |
| time | time | numeric | 0 |
| DEATH_EVENT | DEATH_EVENT | numeric | 0 |
| evento | evento | factor | 0 |
| grupo_edad | grupo_edad | factor | 0 |
Análisis exploratorio y visualización
Indicadores generales
total_registros <- nrow(datos)
edad_media <- mean(datos$age, na.rm = TRUE)
total_eventos <- sum(datos$DEATH_EVENT == 1, na.rm = TRUE)
porcentaje_eventos <- mean(datos$DEATH_EVENT == 1, na.rm = TRUE) * 100
indicadores <- data.frame(
Indicador = c(
"Total de registros",
"Edad promedio (años)",
"Registros con evento de fallecimiento (%)"
),
Resultado = c(
total_registros,
round(edad_media, 1),
round(porcentaje_eventos, 1)
)
)
knitr::kable(
indicadores,
caption = "Indicadores generales de la población estudiada"
)| Indicador | Resultado |
|---|---|
| Total de registros | 299.0 |
| Edad promedio (años) | 60.8 |
| Registros con evento de fallecimiento (%) | 32.1 |
Interpretación
- ¿Qué evidencia? muestra el tamaño de la base, la edad promedio y la proporción de registros con evento de fallecimiento.
- ¿Por qué es relevante? proporciona una visión inicial de la población estudiada.
- ¿Qué acción sugiere? utilizar estos indicadores como punto de partida para analizar las características clínicas y planificar estudios complementarios.
Grafica de Distribución de los grupos de edad
resumen_grupos <- datos %>%
filter(!is.na(grupo_edad)) %>%
count(grupo_edad, name = "pacientes")
grupo_mayor <- resumen_grupos %>%
slice_max(pacientes, n = 1, with_ties = FALSE)
posicion_mayor <- match(
as.character(grupo_mayor$grupo_edad),
as.character(resumen_grupos$grupo_edad)
)
ggplot(
resumen_grupos,
aes(x = grupo_edad, y = pacientes, fill = grupo_edad)
) +
geom_col(show.legend = FALSE) +
ggrepel::geom_text_repel(
aes(label = pacientes),
size = 4,
max.overlaps = Inf
) +
annotate(
"label",
x = posicion_mayor,
y = grupo_mayor$pacientes + 10,
label = "Grupo con más registros",
size = 3.2
) +
scale_fill_brewer(palette = "Set2") +
coord_cartesian(
ylim = c(0, max(resumen_grupos$pacientes) + 25)
) +
labs(
title = "Distribución de pacientes por edad",
x = "Grupo de edad",
y = "Número de registros",
caption = "Fuente: elaboración propia con la base de datos clínica."
) +
theme_minimal()Interpretación
- ¿Qué evidencia? presenta la cantidad de registros en cada grupo de edad.
- ¿Por qué es relevante? permite reconocer qué grupos tienen mayor representación en la base y ayuda a contextualizar las comparaciones posteriores.
- ¿Qué acción sugiere? considerar el tamaño de cada grupo antes de comparar porcentajes o interpretar diferencias.
Grafica Evento de fallecimiento por grupo de edad
resumen_eventos <- datos %>%
filter(!is.na(grupo_edad), !is.na(DEATH_EVENT)) %>%
group_by(grupo_edad) %>%
summarise(
total = n(),
fallecimientos = sum(DEATH_EVENT == 1),
porcentaje = mean(DEATH_EVENT == 1) * 100,
.groups = "drop"
)
grupo_mayor_evento <- resumen_eventos %>%
slice_max(porcentaje, n = 1, with_ties = FALSE)
posicion_evento <- match(
as.character(grupo_mayor_evento$grupo_edad),
as.character(resumen_eventos$grupo_edad)
)
ggplot(
resumen_eventos,
aes(x = grupo_edad, y = porcentaje, fill = grupo_edad)
) +
geom_col(show.legend = FALSE) +
ggrepel::geom_text_repel(
aes(label = paste0(round(porcentaje, 1), "%")),
size = 4,
max.overlaps = Inf
) +
annotate(
"label",
x = posicion_evento,
y = grupo_mayor_evento$porcentaje + 7,
label = "Mayor porcentaje observado",
size = 3
) +
scale_fill_brewer(palette = "Set2") +
scale_y_continuous(
labels = function(x) paste0(x, "%")
) +
coord_cartesian(
ylim = c(0, max(resumen_eventos$porcentaje) + 20)
) +
labs(
title = "Porcentaje con evento de fallecimiento por edad",
x = "Grupo de edad",
y = "Porcentaje de registros (%)",
caption = "Fuente: elaboración propia con la base de datos clínica."
) +
theme_minimal()Interpretación
- ¿Qué evidencia? compara la proporción de registros con evento de fallecimiento dentro de cada grupo de edad.
- ¿Por qué es relevante? permite identificar diferencias descriptivas que pueden justificar análisis adicionales.
- ¿Qué acción sugiere? examinar las variables clínicas y el número de registros de cada grupo antes de establecer prioridades de seguimiento.
Grafica Fracción de eyección según el resultado
ggplot(
datos %>%
filter(!is.na(evento), !is.na(ejection_fraction)),
aes(x = evento, y = ejection_fraction, fill = evento)
) +
geom_boxplot(alpha = 0.85, show.legend = FALSE) +
scale_fill_brewer(palette = "Set2") +
labs(
title = "Fracción de eyección según el resultado registrado",
x = "Resultado",
y = "Fracción de eyección",
caption = "Fuente: elaboración propia con la base de datos clínica."
) +
theme_minimal()Interpretación
- ¿Qué evidencia? permite comparar la mediana y la dispersión de la fracción de eyección entre los dos grupos.
- ¿Por qué es relevante? facilita explorar diferencias en una variable clínica entre los registros con y sin evento de fallecimiento.
- ¿Qué acción sugiere? complementar la comparación con otras variables y con la evaluación del equipo clínico.
Grafica Relación entre edad y creatinina sérica
grafico_edad_creatinina <- ggplot(
datos %>%
filter(
!is.na(age),
!is.na(serum_creatinine),
!is.na(evento)
),
aes(
x = age,
y = serum_creatinine,
color = evento,
text = paste0(
"Edad: ", age, " años",
"<br>Creatinina sérica: ", serum_creatinine,
"<br>Resultado: ", evento
)
)
) +
geom_point(alpha = 0.75, size = 2.5) +
scale_color_brewer(palette = "Set1") +
labs(
title = "Edad y creatinina sérica",
x = "Edad (años)",
y = "Creatinina sérica",
color = "Resultado"
) +
theme_minimal()
plotly::ggplotly(
grafico_edad_creatinina,
tooltip = "text"
)Interpretación
- ¿Qué evidencia? muestra cada registro según la edad y la creatinina sérica.
- ¿Por qué es relevante? los mensajes emergentes y las funciones de zoom facilitan la exploración individual de los datos.
- ¿Qué acción sugiere? identificar observaciones que merezcan una revisión posterior y contrastarlas con otras variables clínicas.
Grafica Visualización interactiva en tres dimensiones
datos_3d <- datos %>%
filter(
!is.na(age),
!is.na(ejection_fraction),
!is.na(serum_creatinine),
!is.na(evento)
)
plotly::plot_ly(
data = datos_3d,
x = ~age,
y = ~ejection_fraction,
z = ~serum_creatinine,
color = ~evento,
type = "scatter3d",
mode = "markers",
marker = list(size = 4),
text = ~paste0(
"Edad: ", age,
"<br>Fracción de eyección: ", ejection_fraction,
"<br>Creatinina sérica: ", serum_creatinine,
"<br>Resultado: ", evento
),
hoverinfo = "text"
) %>%
plotly::layout(
title = "Relación exploratoria entre tres variables clínicas",
scene = list(
xaxis = list(title = "Edad"),
yaxis = list(title = "Fracción de eyección"),
zaxis = list(title = "Creatinina sérica")
)
)Interpretación
- ¿Qué evidencia? representa simultáneamente tres variables clínicas de los registros.
- ¿Por qué es relevante? permite explorar los datos desde diferentes ángulos y reconocer posibles agrupaciones.
- ¿Qué acción sugiere? utilizar los patrones visuales para formular preguntas que luego se comprueben con métodos estadísticos.
Preguntas orientadoras
El análisis busca responder las siguientes preguntas:
- ¿Cómo se distribuyen los registros según la edad?
- ¿Qué diferencias se observan en el evento de fallecimiento entre los grupos de edad?
- ¿Cómo se distribuye la fracción de eyección según el resultado registrado?
- ¿Qué patrones se observan entre edad y creatinina sérica?
- ¿Qué relaciones se identifican entre las principales variables numéricas?
Modelamiento analítico
Busca estudiar la relación entre las características clínicas de los pacientes y el resultado de fallecimiento registrado durante el seguimiento. Para ello, se propone la regresión logística, que permite estimar la asociación entre diferentes variables y el desenlace. Su desempeño se evalúa mediante indicadores como exactitud, sensibilidad, especificidad y área bajo la curva ROC. El modelo puede apoyar la toma de decisiones y la planificación del seguimiento, pero requiere validación adicional y no reemplaza el criterio del personal médico.
Grafica Análisis de correlación
La correlación mide la intensidad y dirección de una relación lineal entre dos variables numéricas. No demuestra que una variable cause cambios en otra.
# Seleccionar las variables que se van a analizar
nombres_variables <- c(
"age",
"creatinine_phosphokinase",
"ejection_fraction",
"platelets",
"serum_creatinine",
"serum_sodium",
"time"
)
# Convertir las variables a formato numérico
variables_correlacion <- datos %>%
select(all_of(nombres_variables)) %>%
mutate(
across(
everything(),
~ as.numeric(as.character(.x))
)
)
# Calcular la matriz de correlación
matriz_correlacion <- cor(
variables_correlacion,
use = "pairwise.complete.obs",
method = "pearson"
)
# Preparar los datos para el gráfico
datos_correlacion <- as.data.frame(
as.table(matriz_correlacion)
)
names(datos_correlacion) <- c(
"Variable_1",
"Variable_2",
"Correlacion"
)
# Crear el gráfico
ggplot(
datos_correlacion,
aes(
x = Variable_1,
y = Variable_2,
fill = Correlacion
)
) +
geom_tile(color = "white") +
geom_text(
aes(label = round(Correlacion, 2)),
size = 3
) +
scale_fill_gradient2(
low = "#2166AC",
mid = "white",
high = "#B2182B",
midpoint = 0,
limits = c(-1, 1)
) +
labs(
title = "Matriz de correlación de variables clínicas",
subtitle = "Relaciones lineales entre las variables seleccionadas",
x = "Variable",
y = "Variable",
fill = "Correlación"
) +
theme_minimal() +
theme(
axis.text.x = element_text(
angle = 45,
hjust = 1
),
axis.text.y = element_text(size = 9)
)Interpretación
- ¿Qué evidencia? muestra la dirección y la intensidad de las relaciones lineales entre las variables seleccionadas.
- ¿Por qué es relevante? ayuda a identificar relaciones que pueden estudiarse con mayor profundidad.
- ¿Qué acción sugiere? comprobar las relaciones de interés con análisis adicionales y evitar interpretar la correlación como causalidad.
Conclusiones generales
El análisis permite describir la población registrada y comparar variables clínicas relacionadas con el evento de fallecimiento.
Los gráficos estáticos facilitan la comparación de grupos y la identificación de patrones. Las visualizaciones interactivas permiten examinar observaciones específicas, mientras que la gráfica tridimensional integra tres variables en una sola representación.
La matriz de correlación ayuda a explorar relaciones entre variables numéricas. Todos estos resultados deben interpretarse considerando la calidad de los datos, el tamaño de los grupos y las limitaciones del análisis descriptivo.
Recomendaciones ejecutivas
Recomendación 1. Fortalecer el seguimiento y la calidad de la información clínica.
Establecer revisiones periódicas de los registros y de los indicadores relevantes. Las decisiones sobre el seguimiento de pacientes deben basarse en los protocolos institucionales y en la valoración del personal de salud.
Recomendación 2. Incorporar visualizaciones en los informes de gestión sanitaria.
Utilizar gráficos e indicadores para comunicar los resultados a directivos y responsables de calidad. Complementar los hallazgos descriptivos con análisis estadísticos adicionales antes de definir cambios en los procesos institucionales.