Esta base de datos contiene 8763 registros de pacientes de diversas partes del mundo y cuenta con una característica de clasificación binaria que indica si existe o no riesgo de ataque cardíaco, siendo una valiosa herramienta para análisis predictivo e investigación en salud cardiovascular.
El documento presenta el análisis y descripción de un conjunto de datos centrado específicamente en el riesgo de ataque cardíaco como variable objetivo. Cada dato recopilado está relacionado con características relevantes para la salud cardiovascular de los pacientes. El análisis abarca una variedad de factores clave, tales como la edad, el colesterol, la presión arterial, la frecuencia cardíaca, el índice de masa corporal (IMC), antecedentes familiares de problemas cardíacos, hábito de fumar, diabetes, nivel de estrés, problemas cardíacos previos y, por supuesto, el riesgo de ataque cardíaco. Este enfoque integral permite identificar patrones significativos y correlaciones entre estas variables y el riesgo de eventos cardíacos, proporcionando una base sólida para futuras investigaciones y estrategias preventivas. Los resultados subrayan la importancia crítica de un análisis detallado y la interpretación cuidadosa de estos datos para mejorar la predicción y la gestión del riesgo cardiovascular en la población estudiada.
Target: Riesgo de ataque cardíaco. (Sí = 1, No = 0)
library(pacman)
library(plotly())
p_load(dplyr, ggplot2, datos, kableExtra, knitr,
flextable, foreign, gganimate)
options(scipen = 999)
options(digits = 3)
datos <- read.csv("train.CSV", sep = ",")
datos <- datos %>% select(-Patient.ID)
names(datos) <- c("Edad", "Sexo", "Colesterol", "Presion_Arterial", "Frecuencia_Cardiaca",
"Diabetes", "Antecedentes_Familiares", "Fumador", "Obesidad",
"Consumo_Alcohol", "Horas_Ejercicio_Semana", "Dieta", "Problemas_Cardiacos_Anteriores",
"Uso_Medicacion", "Nivel_Estres", "Horas_Sedentarias_Dia", "Ingreso",
"IMC", "Trigliceridos", "Dias_Actividad_Fisica_Semana", "Horas_Sueño_Dia",
"Pais", "Continente", "Hemisferio", "Riesgo_Ataque_Cardiaco")
variables_importantes <- c("Edad", "Colesterol", "Presion_Arterial", "Frecuencia_Cardiaca",
"IMC", "Antecedentes_Familiares", "Fumador", "Diabetes",
"Nivel_Estres", "Problemas_Cardiacos_Anteriores", "Riesgo_Ataque_Cardiaco")
datos <- datos %>% select(all_of(variables_importantes))
str(datos)## 'data.frame': 7010 obs. of 11 variables:
## $ Edad : int 33 56 19 50 89 64 86 85 61 28 ...
## $ Colesterol : int 200 262 140 163 144 185 350 246 149 306 ...
## $ Presion_Arterial : chr "129/90" "159/105" "161/109" "120/62" ...
## $ Frecuencia_Cardiaca : int 48 46 54 53 92 45 71 81 93 56 ...
## $ IMC : num 30.4 35 30.6 35.4 39.6 ...
## $ Antecedentes_Familiares : int 1 0 1 1 0 1 0 0 1 0 ...
## $ Fumador : int 1 1 0 1 1 1 1 1 1 1 ...
## $ Diabetes : int 0 1 0 0 1 1 0 0 1 1 ...
## $ Nivel_Estres : int 2 8 3 7 1 5 10 1 6 5 ...
## $ Problemas_Cardiacos_Anteriores: int 0 1 1 0 1 0 0 0 1 1 ...
## $ Riesgo_Ataque_Cardiaco : int 1 1 0 1 1 1 0 1 1 0 ...
Los datos originales fueron transformados para mejorar la interpretación y el análisis de los factores de riesgo relacionados con enfermedades cardíacas. Variables como Colesterol, Presión Arterial y Frecuencia Cardíaca fueron categorizadas en rangos específicos (“Alto”, “Elevada”, “Normal”) para facilitar la identificación de niveles de riesgo. Además, Antecedentes Familiares, Fumador, Diabetes y Problemas Cardíacos Anteriores se convirtieron en factores con etiquetas descriptivas (“Sí” o “No”), clarificando la presencia o ausencia de cada riesgo. El Nivel de Estrés se transformó en un factor con niveles de “Alto”, “Moderado” y “Bajo”, facilitando la comprensión de su impacto en la salud cardiovascular. Estas modificaciones permiten una mejor visualización y análisis de los datos, fundamentales para identificar patrones y tomar decisiones informadas en salud cardíaca.
datos <- datos %>% select(all_of(variables_importantes))
datos <- datos %>%
mutate(
Edad = as.integer(Edad),
Colesterol = factor(case_when(
Colesterol < 200 ~ "Normal",
Colesterol < 240 ~ "Alto",
TRUE ~ "Muy Alto"
)),
Presion_Arterial = factor(case_when(
as.numeric(sub("/.*", "", Presion_Arterial)) < 120 & as.numeric(sub(".*/", "", Presion_Arterial)) < 80 ~ "Normal",
as.numeric(sub("/.*", "", Presion_Arterial)) < 140 | as.numeric(sub(".*/", "", Presion_Arterial)) < 90 ~ "Elevada",
TRUE ~ "Alta"
)),
Frecuencia_Cardiaca = factor(case_when(
Frecuencia_Cardiaca < 60 ~ "Baja",
Frecuencia_Cardiaca <= 100 ~ "Normal",
TRUE ~ "Alta"
)),
IMC = as.numeric(IMC),
Antecedentes_Familiares = factor(Antecedentes_Familiares, levels = c(0, 1), labels = c("No", "Sí")),
Fumador = factor(Fumador, levels = c(0, 1), labels = c("No", "Sí")),
Diabetes = factor(Diabetes, levels = c(0, 1), labels = c("No", "Sí")),
Nivel_Estres = factor(case_when(
Nivel_Estres <= 3 ~ "Bajo",
Nivel_Estres <= 7 ~ "Moderado",
TRUE ~ "Alto"
)),
Problemas_Cardiacos_Anteriores = factor(Problemas_Cardiacos_Anteriores, levels = c(0, 1), labels = c("No", "Sí")),
Riesgo_Ataque_Cardiaco=factor(Riesgo_Ataque_Cardiaco, levels = c(0, 1), labels =
c("No", "Sí"))
)
str(datos)## 'data.frame': 7010 obs. of 11 variables:
## $ Edad : int 33 56 19 50 89 64 86 85 61 28 ...
## $ Colesterol : Factor w/ 3 levels "Alto","Muy Alto",..: 1 2 3 3 3 3 2 2 3 2 ...
## $ Presion_Arterial : Factor w/ 3 levels "Alta","Elevada",..: 2 1 1 2 1 2 1 2 2 2 ...
## $ Frecuencia_Cardiaca : Factor w/ 3 levels "Alta","Baja",..: 2 2 2 2 3 2 3 3 3 2 ...
## $ IMC : num 30.4 35 30.6 35.4 39.6 ...
## $ Antecedentes_Familiares : Factor w/ 2 levels "No","Sí": 2 1 2 2 1 2 1 1 2 1 ...
## $ Fumador : Factor w/ 2 levels "No","Sí": 2 2 1 2 2 2 2 2 2 2 ...
## $ Diabetes : Factor w/ 2 levels "No","Sí": 1 2 1 1 2 2 1 1 2 2 ...
## $ Nivel_Estres : Factor w/ 3 levels "Alto","Bajo",..: 2 1 2 3 2 3 1 2 3 3 ...
## $ Problemas_Cardiacos_Anteriores: Factor w/ 2 levels "No","Sí": 1 2 2 1 2 1 1 1 2 2 ...
## $ Riesgo_Ataque_Cardiaco : Factor w/ 2 levels "No","Sí": 2 2 1 2 2 2 1 2 2 1 ...
library(ggplot2)
library(dplyr)
library(echarts4r)
library(magrittr)
# Definir imágenes para cada nivel de Riesgo_Ataque_Cardiaco
imagen_riesgo <- c(
"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSCZaIWwPv89J0G2IdZ_0dpBN2ylRuCCafAhqWNfRL0r6b5MTcwU2oKhbNPAEEAeYYTNEc&usqp=CAU",
"https://img.freepik.com/vector-premium/icono-medico-corazon-sano-caricatura-icono-vector-medico-corazon-sano-diseno-web-aislado-sobre-fondo-blanco_98402-57021.jpg"
)
# Crear el gráfico para Riesgo_Ataque_Cardiaco
riesgo_plot <- datos %>%
group_by(Riesgo_Ataque_Cardiaco) %>%
summarise(count = n()) %>%
mutate(
imagen = imagen_riesgo,
x = factor(Riesgo_Ataque_Cardiaco),
valor = count,
imagen = c(paste0("image://", imagen_riesgo))
)
riesgo_plot %>%
e_charts(x) %>%
e_pictorial(valor, imagen) %>%
e_theme("westeros") %>%
e_legend(FALSE) %>%
e_title("Riesgo de Ataque Cardíaco: No / Sí", left = 'center') %>%
e_labels(show = TRUE) %>%
e_x_axis(splitLine = list(show = TRUE)) %>%
e_y_axis(show = TRUE,
min = 0, max = max(riesgo_plot$valor),
interval = 700)library(dplyr)
library(echarts4r)
nivel_plot <- datos %>%
group_by(Nivel_Estres) %>%
summarise(count = n()) %>%
mutate(
x = factor(Nivel_Estres),
valor = count
)
nivel_plot %>%
e_charts(x) %>%
e_pie(valor, name = "Nivel de Estrés") %>%
e_theme("westeros") %>%
e_legend(TRUE,
bottom = 0,
title = list(
text = "Nivel de Estrés",
textStyle = list(fontSize = 16)
),
textStyle = list(fontSize = 14)
) %>%
e_title("Distribución del Nivel de Estrés", left = 'center') %>%
e_labels(show = TRUE, formatter = "{b}: {d}%")library(dplyr)
library(echarts4r)
problem_Ant_plo <- datos %>%
group_by(Problemas_Cardiacos_Anteriores) %>%
summarise(count = n()) %>%
mutate(
x = factor(Problemas_Cardiacos_Anteriores),
valor = count
)
problem_Ant_plo %>%
e_charts(x) %>%
e_bar(valor) %>%
e_theme("westeros") %>%
e_legend(FALSE) %>%
e_title("Problemas cardiacos anteriores: No / Sí", left = 'center') %>%
e_labels(show = TRUE) %>%
e_x_axis(splitLine = list(show = TRUE)) %>%
e_y_axis(show = TRUE,
min = 0, max = max(problem_Ant_plo$valor) + 50,
interval = 700)ggplot(datos, aes(x = IMC, fill = after_stat(count))) +
geom_histogram(binwidth = 1, color = "black", alpha = 0.8) +
scale_fill_gradient(low = "gold", high = "red") +
labs(title = "Distribución del Índice de Masa Corporal (IMC)",
x = "Índice de Masa Corporal (IMC)",
y = "Frecuencia") +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, size = 16),
axis.title.x = element_text(size = 14),
axis.title.y = element_text(size = 14),
legend.position = "none" # Ocultar la leyenda
) +
geom_text(stat='count', aes(label=after_stat(count)), vjust=-0.5, size=3.5, color="black")library(ggplot2)
library(dplyr)
Antece_familiares <- datos %>%
count(Antecedentes_Familiares) %>%
mutate(
etiqueta = ifelse(Antecedentes_Familiares =="sí", "Sí", "No")
)
ggplot(Antece_familiares, aes(x = "", y = n, fill = Antecedentes_Familiares)) +
geom_bar(stat = "identity", width = 1, color = "white") +
coord_polar("y", start = 0) +
labs(
title = "Distribución de Antecedentes Familiares",
fill = "Antecedentes Familiares",
y = "Frecuencia"
) +
theme_void() +
theme(
plot.title = element_text(hjust = 0.5, size = 16),
legend.position = "bottom", # Posición de la leyenda
legend.title = element_text(size = 12),
legend.text = element_text(size = 10)
) +
geom_text(aes(label = paste0(etiqueta, " (", n, ")")), position = position_stack(vjust = 0.5), size = 5)library(ggplot2)
library(dplyr)
ggplot(datos, aes(x = Fumador, fill = Fumador)) +
geom_bar() +
labs(x = "Fuma", y = "Frecuencia", title = "Gráfico de la variable Fuma") +
scale_fill_manual(values = c("darkgreen", "orange")) +
theme_minimal()library(ggplot2)
library(dplyr)
ggplot(datos, aes(x = Diabetes, fill = Diabetes)) +
geom_bar() +
labs(x = "Diabetes", y = "Frecuencia", title = "Frecuencia de Diabetes") +
scale_fill_manual(values = c("darkgreen", "orange")) +
theme_minimal()library(dplyr)
library(echarts4r)
colesterol_plot <- datos %>%
group_by(Colesterol) %>%
summarise(count = n()) %>%
mutate(
x = factor(Colesterol),
valor = count
)
colesterol_plot %>%
e_charts(x) %>%
e_pie(valor, name = "Colesterol") %>%
e_theme("westeros") %>%
e_legend(TRUE,
bottom = 0,
title = list(
text = "Colesterol",
textStyle = list(fontSize = 16)
),
textStyle = list(fontSize = 14)
) %>%
e_title("Distribución de los Niveles de Colesterol", left = 'center') %>%
e_labels(show = TRUE, formatter = "{b}: {d}%")Normal: Representa el 28.02% de los datos. Alto: Corresponde al 14.24%. Muy Alto: Es el nivel más grande, con un 57.74%.
En resumen, la mayoría de las personas se encuentran en el nivel “Muy Alto”.
# Calcular la distribución porcentual de la Frecuencia Cardíaca
resumen_frecuencia <- datos %>%
count(Frecuencia_Cardiaca) %>%
mutate(Proporcion = n / sum(n) * 100)
knitr::kable(resumen_frecuencia, col.names = c("Frecuencia Cardíaca", "Cantidad", "Proporción (%)"), align = 'c')| Frecuencia Cardíaca | Cantidad | Proporción (%) |
|---|---|---|
| Alta | 989 | 14.1 |
| Baja | 1972 | 28.1 |
| Normal | 4049 | 57.8 |
resumen_pres <- datos %>%
count(Presion_Arterial) %>%
mutate(Proporcion = n / sum(n) * 100)
knitr::kable(resumen_pres, col.names = c("Presión arterial", "Cantidad", "Proporción (%)"), align = 'c')| Presión arterial | Cantidad | Proporción (%) |
|---|---|---|
| Alta | 1329 | 19.0 |
| Elevada | 4751 | 67.8 |
| Normal | 930 | 13.3 |
library(ggplot2)
library(ggthemes)
library(gganimate)
library(dplyr)
ggplot(datos, aes(x = Nivel_Estres, y = after_stat(count), fill = Riesgo_Ataque_Cardiaco, label = after_stat(count))) +
geom_bar(stat = "count", position = "dodge") +
geom_text(stat = "count", position = position_dodge(width = 0.9), vjust = -0.5) +
scale_fill_manual(values = c("red", "blue"), labels = c("No", "Sí")) +
labs(
x = "Nivel de Estrés",
y = "Número de Personas",
title = "Distribución de frecuencias de riesgo de ataque cardíaco por nivel de estrés"
) +
theme_minimal() +
transition_states(Riesgo_Ataque_Cardiaco, transition_length = 3, state_length = 3) +
enter_fade() +
exit_fade()El gráfico muestra que el nivel de estrés parece no ser un predictor determinante del riesgo de sufrir un ataque al corazón. Observamos lo siguiente:
La proporción de personas que sufrieron un ataque al corazón es similar entre aquellos con niveles de estrés bajos y altos. La diferencia más notable en la incidencia de ataques al corazón se observa entre aquellos con estrés moderado y aquellos sin estrés. Esto sugiere que, según este análisis visual preliminar, el nivel de estrés por sí solo puede no permitir una distinción clara entre las personas con mayor y menor riesgo de sufrir un ataque al corazón. Es posible que otros factores no considerados en este gráfico también jueguen un papel importante en la predicción del riesgo de ataque cardíaco.
# Utiliza geom_bar() en lugar de geom_histogram() para variables categóricas
ggplot(datos) +
aes(x = Frecuencia_Cardiaca, fill = Riesgo_Ataque_Cardiaco) +
geom_bar(alpha = 0.5, color = "azure4", position = "dodge") +
facet_grid(Riesgo_Ataque_Cardiaco ~ .) +
theme(legend.position = "none") +
labs(title = "Gráfico de Barras de Frecuencia Cardíaca",
x = "Niveles Cardíacos",
y = "Frecuencia") +
theme_bw() +
scale_fill_manual(values = c("red", "yellow"))El gráfico muestra la distribución de la frecuencia cardíaca segmentada por el riesgo de ataque cardíaco. Los datos indican que hay menos personas con frecuencia cardíaca alta y riesgo de ataque cardíaco. En contraste, un mayor número de personas con frecuencia cardíaca baja no tienen riesgo de ataque cardíaco.
La mayoría de las personas con frecuencia cardíaca normal no tienen riesgo de ataque cardíaco, aunque una cantidad significativa sí está en riesgo. Estos hallazgos sugieren que una frecuencia cardíaca normal es común independientemente del riesgo, mientras que una frecuencia cardíaca baja se asocia más con la ausencia de riesgo de ataque cardíaco.
ggplot(datos) + aes(Fumador,fill=Riesgo_Ataque_Cardiaco,group=Riesgo_Ataque_Cardiaco) +
geom_bar(position = "fill") +
theme_light() +
labs(title = "Situación de Riesgo Cardíaco con respecto a sí Fuma",
x = "Fuma",
y = "Frecuencia") El gráfico presenta la distribución de la frecuencia cardíaca según si los individuos fuman o no. Observamos que la variable “fumador” parece no ser un predictor determinante del riesgo de sufrir un ataque al corazón. Notamos lo siguiente:
La proporción de personas que sufrieron un ataque al corazón es similar tanto entre fumadores como no fumadores, con una variación mínima que dificulta identificar con precisión si el hábito de fumar está asociado al riesgo de sufrir un ataque cardíaco.
p <- ggplot(datos) + aes((Edad), fill = Riesgo_Ataque_Cardiaco) +
geom_histogram(alpha = 0.5, color = "azure4") +
facet_grid(Riesgo_Ataque_Cardiaco ~ .) + # filas ~ columnas
theme(legend.position = "none") +
labs(title = "Histograma de la Edad",
x = "Edad",
y = "Frecuencia") +
theme_bw()
animated_plot <- p + transition_states(Riesgo_Ataque_Cardiaco, transition_length = 3, state_length = 3) +
enter_fade() + exit_fade()
# Mostrar la animación
animate(animated_plot) En
el gráfico del grupo de personas que no tienen riesgo cardíaco, se
observa una proporción más alta de personas alrededor de los 20 años,
superando las 200 personas en total.
En comparación, en el gráfico de las personas que sí tienen riesgo cardíaco, la proporción es más baja en torno a los 20 años, con menos de 110 personas en total.
En conclusión, personas de distintas edades están en riesgo de sufrir un ataque cardíaco.
ggplot(datos) + aes(x = Colesterol, fill = Riesgo_Ataque_Cardiaco) +
geom_bar(position = "dodge") +
theme_bw() +
labs(title = "Gráfico de Niveles del colesterol",
x = "Niveles del colestrol",
y = "Frecuencia") +
scale_fill_manual(values = c("darkolivegreen3", "firebrick2")) Alto : El grupo de personas con niveles de colesterol alto está representado por la barra verde. Menos de 1000 personas con colesterol alto no tuvieron una crisis cardíaca.
Muy Alto: La barra roja muestra que menos de 1500 personas con niveles de colesterol muy alto sí tuvieron una crisis cardíaca.
Normal: se muestra en el gráfico que las peronas que tienen riesgo cardíaco son 700 aproximadamente
resumen_imc <- datos %>%
group_by(Riesgo_Ataque_Cardiaco) %>%
summarise(
count = n(),
mean_imc = mean(IMC, na.rm = TRUE),
sd_imc = sd(IMC, na.rm = TRUE)
) %>%
mutate(Proporcion = count / sum(count) * 100)
# Crear el cuadro de resumen
knitr::kable(resumen_imc, col.names = c("Riesgo de Ataque Cardíaco", "Cantidad", "IMC Medio", "Desviación Estándar del IMC", "Proporción (%)"), align = 'c')| Riesgo de Ataque Cardíaco | Cantidad | IMC Medio | Desviación Estándar del IMC | Proporción (%) |
|---|---|---|---|---|
| No | 4506 | 28.9 | 6.32 | 64.3 |
| Sí | 2504 | 28.9 | 6.33 | 35.7 |
Después del análisis exhaustivo de la base de datos, concluimos que varias variables influyen significativamente en el riesgo cardíaco. Sin embargo, destacamos que algunas variables predictoras clave están particularmente involucradas. Estas incluyen la edad de los pacientes, la frecuencia cardíaca y los niveles de colesterol en la sangre. Estos factores no solo muestran correlaciones claras con el riesgo de eventos cardíacos, sino que también subrayan la importancia de monitorear y gestionar estos indicadores para la salud cardiovascular.
Banerjee, I. S. (s.f.). Heart attack prediction dataset. Kaggle. Recuperado el 1 de julio de 2024, de https://www.kaggle.com/datasets/iamsouravbanerjee/heart-attack-prediction-dataset