El análisis exploratorio de datos (EDA) constituye la primera etapa del proceso analítico y tiene como propósito conocer la estructura, calidad y comportamiento general de la información antes de realizar análisis estadísticos de mayor complejidad. En este informe se utiliza una base de datos obtenida por encuesta de vigilancia de factores de riesgo en población adulta de EE.UU, que contiene aproximadamente 401.958 registros y 279 variables en la versión oficial de 2020, y pertenece al Sistema de Vigilancia de Factores de Riesgo Conductuales (BRFSS), de donde se conservan solo un subconjunto de 19 variables como propósito de análisis del informe.
Pregunta central: ¿Cómo se acumulan los factores de riesgo modificables (tabaquismo, sedentarismo, obesidad y sueño insuficiente) y las barreras económicas de acceso según el ingreso y la edad, y cómo se relacionan con la mala salud autopercibida y la enfermedad coronaria en adultos de EE. UU.?
Objetivo del EDA: Describir la estructura y la calidad de la base, identificar los grupos con mayor carga de riesgo y traducir los hallazgos en prioridades de gestión del riesgo y prevención.
Se instalan solo los paquetes que falten y se cargan.
paquetes <- c("tidyverse", "skimr", "janitor", "plotly", "knitr")
faltantes_pkg <- paquetes[!paquetes %in% installed.packages()[, "Package"]]
if (length(faltantes_pkg) > 0) install.packages(faltantes_pkg)
library(tidyverse)
library(skimr)
library(janitor)
library(plotly)
library(knitr)
# Paleta institucional del informe
paleta <- c(azul = "#1F4E79", naranja = "#E67E22", verde = "#2E8B57", gris = "#7F8C8D")# Importación de la base de datos
ruta_archivo <- "brfss2020.csv"
base_completa <- read_csv(ruta_archivo, col_types = cols(.default = col_double()))
# Datos generales de la base completa
n_registros <- nrow(base_completa)
n_variables <- ncol(base_completa)
tipos_var <- table(sapply(base_completa, class))
n_estados <- n_distinct(base_completa$`_STATE`)
faltantes_por_variable <- base_completa |>
summarise(across(everything(), ~ mean(is.na(.x)) * 100)) |>
pivot_longer(everything(), names_to = "variable", values_to = "pct_faltante")
# Visualización inicial
head(base_completa)# Nombres originales -> nombres en español
nombres_es <- c(
estado_eeuu = "_STATE", sexo = "SEXVAR",
salud_general = "GENHLTH", dias_mala_salud_fisica = "PHYSHLTH",
dias_mala_salud_mental = "MENTHLTH", tiene_seguro = "HLTHPLN1",
barrera_costo = "MEDCOST", ultimo_chequeo = "CHECKUP1",
actividad_fisica = "EXERANY2", horas_sueno = "SLEPTIM1",
tabaquismo = "_SMOKER3", enf_coronaria = "_MICHD",
acv = "CVDSTRK3", diabetes = "DIABETE4",
imc = "_BMI5", edad = "_AGE80",
ingreso = "_INCOMG", educacion = "_EDUCAG",
peso_muestral = "_LLCPWT"
)
base_sel <- base_completa |>
select(all_of(nombres_es)) |>
clean_names()
rm(base_completa); invisible(gc()) Se convierten en NA (dato faltante) o en su valor real,
cada categoría se traduce al español y se crean los indicadores
de riesgo (1 = presente, 0 = ausente)
dias_validos <- function(x) case_when(x == 88 ~ 0, x >= 1 & x <= 30 ~ x, TRUE ~ NA_real_)
base_eda <- base_sel |>
mutate(
sexo = factor(sexo, levels = 1:2, labels = c("Hombre", "Mujer")),
salud_general = factor(salud_general, levels = 1:5,
labels = c("Excelente", "Muy buena", "Buena", "Regular", "Mala")),
dias_mala_salud_fisica = dias_validos(dias_mala_salud_fisica),
dias_mala_salud_mental = dias_validos(dias_mala_salud_mental),
tiene_seguro = factor(tiene_seguro, levels = 1:2, labels = c("Sí", "No")),
barrera_costo = factor(barrera_costo, levels = 1:2, labels = c("Sí", "No")),
ultimo_chequeo = factor(ultimo_chequeo, levels = c(1, 2, 3, 4, 8),
labels = c("< 1 año", "1-2 años", "2-5 años", "5+ años", "Nunca")),
actividad_fisica = factor(actividad_fisica, levels = 1:2, labels = c("Sí", "No")),
horas_sueno = if_else(horas_sueno <= 24, horas_sueno, NA_real_),
tabaquismo = factor(tabaquismo, levels = 1:4,
labels = c("Fuma diario", "Fuma algunos días", "Exfumador", "Nunca fumó")),
enf_coronaria = factor(enf_coronaria, levels = 1:2, labels = c("Sí", "No")),
acv = factor(acv, levels = 1:2, labels = c("Sí", "No")),
diabetes = factor(diabetes, levels = 1:4,
labels = c("Sí", "Solo en embarazo", "No", "Prediabetes")),
imc = imc / 100, # la base trae el IMC con 2 decimales implícitos
ingreso = factor(ingreso, levels = 1:5, ordered = TRUE,
labels = c("< 15 mil", "15-25 mil", "25-35 mil", "35-50 mil", "50 mil o más")),
educacion = factor(educacion, levels = 1:4,
labels = c("Sin bachillerato", "Bachiller", "Superior incompleta", "Universitario")),
grupo_edad = cut(edad, breaks = c(17, 34, 49, 64, 80),
labels = c("18-34", "35-49", "50-64", "65+")),
# Indicadores de riesgo (1 = presente)
fuma_actual = case_when(tabaquismo %in% c("Fuma diario", "Fuma algunos días") ~ 1,
tabaquismo %in% c("Exfumador", "Nunca fumó") ~ 0),
sedentarismo = case_when(actividad_fisica == "No" ~ 1, actividad_fisica == "Sí" ~ 0),
obesidad = if_else(imc >= 30, 1, 0),
sueno_corto = if_else(horas_sueno < 7, 1, 0),
n_factores_riesgo = fuma_actual + sedentarismo + obesidad + sueno_corto,
mala_salud = case_when(salud_general %in% c("Regular", "Mala") ~ 1,
!is.na(salud_general) ~ 0)
)diccionario <- tibble(
variable_original = unname(nombres_es),
variable_espanol = names(nombres_es),
descripcion = c(
"Estado o territorio de residencia", "Sexo del encuestado",
"Salud general autopercibida", "Días con mala salud física (últimos 30)",
"Días con mala salud mental (últimos 30)", "Tiene algún seguro de salud",
"No consultó al médico por costo (último año)", "Tiempo desde el último chequeo",
"Actividad física fuera del trabajo (último mes)", "Horas de sueño en 24 h",
"Condición de fumador", "Enfermedad coronaria o infarto (calculada)",
"Antecedente de ACV", "Diagnóstico de diabetes", "Índice de masa corporal (kg/m²)",
"Edad en años (tope 80)", "Ingreso anual del hogar (USD)", "Nivel educativo",
"Peso muestral (factor de expansión)"),
tipo = c("Categórica", "Categórica", "Ordinal", "Numérica", "Numérica", "Categórica",
"Categórica", "Ordinal", "Categórica", "Numérica", "Categórica", "Categórica",
"Categórica", "Categórica", "Numérica", "Numérica", "Ordinal", "Ordinal", "Numérica"),
dimension = c("Identificación", "Demografía", "Resultado en salud", "Resultado en salud",
"Resultado en salud", "Acceso / financiero", "Acceso / financiero", "Uso de servicios",
"Riesgo modificable", "Riesgo modificable", "Riesgo modificable", "Enfermedad crónica",
"Enfermedad crónica", "Enfermedad crónica", "Riesgo modificable", "Demografía",
"Socioeconómica / financiero", "Socioeconómica", "Diseño muestral")
)
diccionariotibble(
Indicador = c("Número de registros", "Número de variables", "Estados/territorios",
"Variables seleccionadas para el EDA"),
Valor = c(format(n_registros, big.mark = "."), n_variables, n_estados, ncol(base_sel))
)peso_muestral. Este EDA
reporta valores sin ponderar; la diferencia es pequeña
(mala salud: 15,4 % sin ponderar vs. 14,7 % ponderado; obesidad: 32,0 %
vs. 31,9 %).##
## numeric
## 279
##
## factor numeric ordered
## 12 13 1
faltantes_por_variable |>
mutate(rango = cut(pct_faltante, breaks = c(-Inf, 0, 10, 50, Inf),
labels = c("Sin faltantes", "Hasta 10 %", "10 % a 50 %", "Más de 50 %"))) |>
count(rango, name = "n_variables")# Faltantes en las variables del EDA, después de convertir códigos 7/9/77/99 a NA
base_eda |>
summarise(across(c(salud_general, dias_mala_salud_fisica, dias_mala_salud_mental, barrera_costo,
horas_sueno, tabaquismo, enf_coronaria, imc, ingreso, n_factores_riesgo),
~ round(mean(is.na(.x)) * 100, 1))) |>
pivot_longer(everything(), names_to = "variable", values_to = "pct_faltante") |>
arrange(desc(pct_faltante))Interpretación:
## tibble [401,958 × 26] (S3: tbl_df/tbl/data.frame)
## $ estado_eeuu : num [1:401958] 1 1 1 1 1 1 1 1 1 1 ...
## $ sexo : Factor w/ 2 levels "Hombre","Mujer": 2 2 2 2 2 1 2 2 2 2 ...
## $ salud_general : Factor w/ 5 levels "Excelente","Muy buena",..: 2 3 3 1 2 4 3 4 2 4 ...
## $ dias_mala_salud_fisica: num [1:401958] 3 0 0 0 0 20 0 15 28 6 ...
## $ dias_mala_salud_mental: num [1:401958] 30 0 0 0 0 30 0 10 0 0 ...
## $ tiene_seguro : Factor w/ 2 levels "Sí","No": 2 1 1 1 1 1 1 1 1 1 ...
## $ barrera_costo : Factor w/ 2 levels "Sí","No": 1 1 2 2 2 2 2 2 2 2 ...
## $ ultimo_chequeo : Factor w/ 5 levels "< 1 año","1-2 años",..: 4 1 1 2 1 2 1 1 1 1 ...
## $ actividad_fisica : Factor w/ 2 levels "Sí","No": 1 1 1 2 1 1 2 1 1 2 ...
## $ horas_sueno : num [1:401958] 5 7 7 6 7 8 6 6 8 12 ...
## $ tabaquismo : Factor w/ 4 levels "Fuma diario",..: 1 NA 4 4 4 3 4 1 4 3 ...
## $ enf_coronaria : Factor w/ 2 levels "Sí","No": 2 2 2 2 2 2 2 2 2 1 ...
## $ acv : Factor w/ 2 levels "Sí","No": 2 2 2 2 1 2 2 2 2 2 ...
## $ diabetes : Factor w/ 4 levels "Sí","Solo en embarazo",..: 1 3 3 3 3 1 3 1 3 3 ...
## $ imc : num [1:401958] 16.6 29.2 NA NA 20.3 ...
## $ edad : num [1:401958] 56 65 65 80 80 66 75 69 41 78 ...
## $ ingreso : Ord.factor w/ 5 levels "< 15 mil"<"15-25 mil"<..: 1 NA 5 NA NA 3 4 3 4 NA ...
## $ educacion : Factor w/ 4 levels "Sin bachillerato",..: 4 4 3 2 4 2 2 2 4 1 ...
## $ peso_muestral : num [1:401958] 284 171 1334 1297 455 ...
## $ grupo_edad : Factor w/ 4 levels "18-34","35-49",..: 3 4 4 4 4 4 4 4 2 4 ...
## $ fuma_actual : num [1:401958] 1 NA 0 0 0 0 0 1 0 0 ...
## $ sedentarismo : num [1:401958] 0 0 0 1 0 0 1 0 0 1 ...
## $ obesidad : num [1:401958] 0 0 NA NA 0 0 0 0 0 0 ...
## $ sueno_corto : num [1:401958] 1 0 0 1 0 0 1 1 0 0 ...
## $ n_factores_riesgo : num [1:401958] 2 NA NA NA 0 0 2 2 0 1 ...
## $ mala_salud : num [1:401958] 0 0 0 0 0 1 0 1 0 1 ...
## edad imc horas_sueno dias_mala_salud_fisica
## Min. :18.00 Min. :12.02 Min. : 1.000 Min. : 0.000
## 1st Qu.:40.00 1st Qu.:23.99 1st Qu.: 6.000 1st Qu.: 0.000
## Median :57.00 Median :27.32 Median : 7.000 Median : 0.000
## Mean :54.43 Mean :28.31 Mean : 7.097 Mean : 3.458
## 3rd Qu.:69.00 3rd Qu.:31.38 3rd Qu.: 8.000 3rd Qu.: 2.000
## Max. :80.00 Max. :98.43 Max. :24.000 Max. :30.000
## NA's :41357 NA's :4694 NA's :8691
## dias_mala_salud_mental
## Min. : 0.000
## 1st Qu.: 0.000
## Median : 0.000
## Mean : 3.916
## 3rd Qu.: 3.000
## Max. :30.000
## NA's :7929
Resume en una tabla: faltantes, media, desviación estándar, percentiles y un mini histograma.
base_eda |>
select(edad, imc, horas_sueno, dias_mala_salud_fisica, dias_mala_salud_mental, n_factores_riesgo) |>
skim()| Name | select(…) |
| Number of rows | 401958 |
| Number of columns | 6 |
| _______________________ | |
| Column type frequency: | |
| numeric | 6 |
| ________________________ | |
| Group variables | None |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| edad | 0 | 1.00 | 54.43 | 17.67 | 18.00 | 40.00 | 57.00 | 69.00 | 80.00 | ▃▅▆▇▇ |
| imc | 41357 | 0.90 | 28.31 | 6.38 | 12.02 | 23.99 | 27.32 | 31.38 | 98.43 | ▇▅▁▁▁ |
| horas_sueno | 4694 | 0.99 | 7.10 | 1.47 | 1.00 | 6.00 | 7.00 | 8.00 | 24.00 | ▁▇▁▁▁ |
| dias_mala_salud_fisica | 8691 | 0.98 | 3.46 | 8.08 | 0.00 | 0.00 | 0.00 | 2.00 | 30.00 | ▇▁▁▁▁ |
| dias_mala_salud_mental | 7929 | 0.98 | 3.92 | 8.05 | 0.00 | 0.00 | 0.00 | 3.00 | 30.00 | ▇▁▁▁▁ |
| n_factores_riesgo | 53108 | 0.87 | 1.00 | 0.95 | 0.00 | 0.00 | 1.00 | 2.00 | 4.00 | ▇▇▅▂▁ |
Interpretación:
variables_cat <- c("sexo", "salud_general", "tiene_seguro", "barrera_costo", "ultimo_chequeo",
"actividad_fisica", "tabaquismo", "diabetes", "enf_coronaria", "ingreso")
base_eda |>
select(all_of(variables_cat)) |>
mutate(across(everything(), as.character)) |>
pivot_longer(everything(), names_to = "variable", values_to = "categoria") |>
mutate(categoria = replace_na(categoria, "Sin dato")) |>
count(variable, categoria) |>
group_by(variable) |>
mutate(porcentaje = round(100 * n / sum(n), 1)) |>
ungroup()Se genera Tabla cruzada de la dimensión financiera: porcentaje que
no consultó por costo según ingreso (con
janitor::tabyl).
base_eda |>
tabyl(ingreso, barrera_costo, show_na = FALSE) |>
adorn_percentages("row") |>
adorn_pct_formatting(digits = 1) |>
adorn_ns()Interpretación:
Un boxplot (diagrama de caja) muestra la mediana (línea central), el 50 % central de los datos (la caja) y los valores atípicos (puntos fuera de 1,5 veces el rango intercuartílico, es decir, la distancia entre el percentil 25 y el 75).
datos_box <- base_eda |>
select(`IMC (kg/m²)` = imc, `Horas de sueño` = horas_sueno,
`Días mala salud física` = dias_mala_salud_fisica,
`Días mala salud mental` = dias_mala_salud_mental) |>
pivot_longer(everything(), names_to = "variable", values_to = "valor") |>
drop_na()
ggplot(datos_box, aes(x = variable, y = valor, fill = variable)) +
geom_boxplot(outlier.alpha = 0.05, outlier.colour = paleta["gris"], width = 0.5) +
facet_wrap(~ variable, scales = "free") +
scale_fill_manual(values = unname(paleta)) +
labs(title = "Valores extremos en variables numéricas clave", x = NULL, y = NULL) +
theme_minimal(base_size = 12) +
theme(legend.position = "none", axis.text.x = element_blank())# Cuantificación de atípicos
datos_box |>
group_by(variable) |>
summarise(mediana = median(valor), q1 = quantile(valor, 0.25), q3 = quantile(valor, 0.75),
limite_superior = q3 + 1.5 * (q3 - q1),
pct_atipicos = round(100 * mean(valor < q1 - 1.5 * (q3 - q1) | valor > limite_superior), 1),
maximo = max(valor))Interpretación:
ggplot(filter(base_eda, imc <= 60), aes(x = imc)) +
geom_histogram(binwidth = 1, fill = paleta["azul"], colour = "white") +
geom_vline(xintercept = c(25, 30), linetype = "dashed", colour = paleta["naranja"], linewidth = 0.8) +
annotate("text", x = c(25, 30), y = Inf, vjust = 1.5, hjust = -0.1,
label = c("Sobrepeso", "Obesidad"), colour = paleta["naranja"]) +
labs(title = "Distribución del índice de masa corporal",
subtitle = "Se muestran valores hasta 60 kg/m² para facilitar la lectura",
x = "IMC (kg/m²)", y = "Número de personas") +
theme_minimal(base_size = 12)Interpretación: la distribución tiene sesgo a la derecha (cola larga hacia valores altos). El pico está en sobrepeso y el 32 % de los adultos con dato tiene obesidad (IMC ≥ 30). La obesidad es el factor de riesgo modificable más frecuente de los cuatro analizados.
Los siguientes gráficos son interactivos: al pasar el cursor se ve el valor exacto
gradiente_ingreso <- base_eda |>
filter(!is.na(ingreso)) |>
group_by(ingreso) |>
summarise(`Mala salud autopercibida` = mean(mala_salud, na.rm = TRUE) * 100,
`No consultó por costo` = mean(barrera_costo == "Sí", na.rm = TRUE) * 100,
`Sin seguro de salud` = mean(tiene_seguro == "No", na.rm = TRUE) * 100,
`Sedentarismo` = mean(sedentarismo, na.rm = TRUE) * 100) |>
pivot_longer(-ingreso, names_to = "indicador", values_to = "porcentaje")
plot_ly(gradiente_ingreso, x = ~ingreso, y = ~porcentaje, color = ~indicador,
colors = unname(paleta), type = "bar",
text = ~paste0(round(porcentaje, 1), "%"), textposition = "outside",
hovertemplate = "%{x}<br>%{y:.1f}%<extra></extra>") |>
layout(title = "A menor ingreso, mayor riesgo y menor acceso",
barmode = "group",
xaxis = list(title = "Ingreso anual del hogar (USD)"),
yaxis = list(title = "% de adultos", range = c(0, 50)),
legend = list(orientation = "h", y = -0.2))Interpretación: los cuatro indicadores descienden de forma escalonada a medida que sube el ingreso (gradiente). En el grupo de menor ingreso, 38,9 % reporta mala salud, frente a 7,1 % en el de mayor ingreso (5,5 veces más). El sedentarismo pasa de 41,7 % a 14,5 %, la falta de seguro de 16,2 % a 4,1 % y la barrera de costo de 18,2 % a 4,8 %.
Para la gestión: el ingreso funciona como un criterio de focalización: un mismo recurso preventivo tiene más impacto potencial en los quintiles bajos, donde coinciden más riesgo y menos acceso.
matriz_coronaria <- base_eda |>
filter(!is.na(grupo_edad), !is.na(n_factores_riesgo), !is.na(enf_coronaria)) |>
group_by(grupo_edad, n_factores_riesgo) |>
summarise(prevalencia = mean(enf_coronaria == "Sí") * 100, .groups = "drop") |>
pivot_wider(names_from = n_factores_riesgo, values_from = prevalencia)
z_prevalencia <- as.matrix(matriz_coronaria[, -1]) # filas = edad, columnas = n.º factores
plot_ly(x = 0:4, y = 1:4, z = z_prevalencia, type = "surface",
colorscale = list(c(0, paleta[["verde"]]), c(0.5, paleta[["gris"]]), c(1, paleta[["naranja"]])),
colorbar = list(title = "% coronaria"),
hovertemplate = "Factores de riesgo: %{x}<br>Grupo de edad: %{y}<br>Prevalencia: %{z:.1f}%<extra></extra>") |>
layout(title = "Riesgo acumulado: la edad no modificable y los factores modificables se suman",
scene = list(
xaxis = list(title = "N.º factores de riesgo"),
yaxis = list(title = "Edad", tickvals = 1:4, ticktext = levels(base_eda$grupo_edad)),
zaxis = list(title = "% enfermedad coronaria", color = paleta[["azul"]]),
camera = list(eye = list(x = 1.6, y = -1.6, z = 0.9))))Interpretación: la superficie sube en las dos direcciones. Con la edad (factor no modificable) y con el número de factores de riesgo (factores modificables).
Para la gestión: el número de factores de riesgo es una regla simple de estratificación (clasificar a la población por nivel de riesgo) que se puede aplicar en el primer nivel de atención. La ventana de mayor rendimiento preventivo está en 35-64 años, donde los factores modificables todavía cambian mucho el resultado.
Nota: es una asociación transversal (medida en un solo momento), no causal; las celdas de 4 factores en jóvenes tienen pocos casos.
burbujas <- base_eda |>
filter(!is.na(ingreso), !is.na(grupo_edad)) |>
group_by(ingreso, grupo_edad) |>
summarise(pct_mala_salud = mean(mala_salud, na.rm = TRUE) * 100,
pct_costo = mean(barrera_costo == "Sí", na.rm = TRUE) * 100,
n = n(), .groups = "drop") |>
mutate(tamano = scales::rescale(sqrt(n), to = c(8, 30)))
plot_ly(burbujas, x = ~as.numeric(ingreso), y = ~as.numeric(grupo_edad), z = ~pct_mala_salud,
type = "scatter3d", mode = "markers",
marker = list(size = ~tamano, color = ~pct_costo, opacity = 0.85,
colorscale = list(c(0, paleta[["azul"]]), c(0.5, paleta[["gris"]]), c(1, paleta[["naranja"]])),
colorbar = list(title = "% no consultó<br>por costo"), line = list(width = 0)),
text = ~paste0("Ingreso: ", ingreso, "<br>Edad: ", grupo_edad,
"<br>Mala salud: ", round(pct_mala_salud, 1), "%",
"<br>Barrera de costo: ", round(pct_costo, 1), "%",
"<br>Personas: ", format(n, big.mark = ".")),
hoverinfo = "text") |>
layout(title = "Dónde se concentran la mala salud y la barrera económica",
scene = list(
xaxis = list(title = "Ingreso (USD)", tickvals = 1:5, ticktext = levels(base_eda$ingreso)),
yaxis = list(title = "Edad", tickvals = 1:4, ticktext = levels(base_eda$grupo_edad)),
zaxis = list(title = "% mala salud")))Interpretación:
Para la gestión: el segmento adulto 35-64 de bajo ingreso combina la peor salud y la mayor barrera económica. Es el grupo prioritario para programas de prevención con subsidio o con atención sin copago.
Se usa la correlación de Spearman (mide si dos variables aumentan o disminuyen juntas, basada en el orden de los valores; va de -1 a +1). Es adecuada porque varias variables son asimétricas u ordinales.
matriz_cor <- base_eda |>
transmute(Edad = edad, IMC = imc, `Horas sueño` = horas_sueno,
`Días salud física` = dias_mala_salud_fisica, `Días salud mental` = dias_mala_salud_mental,
Ingreso = as.numeric(ingreso), `Salud general (1=excelente)` = as.numeric(salud_general),
`N.º factores riesgo` = n_factores_riesgo) |>
cor(method = "spearman", use = "pairwise.complete.obs")
plot_ly(x = colnames(matriz_cor), y = rownames(matriz_cor), z = matriz_cor, type = "heatmap",
zmin = -1, zmax = 1,
colorscale = list(c(0, paleta[["naranja"]]), c(0.5, "#F2F2F2"), c(1, paleta[["azul"]])),
text = round(matriz_cor, 2), texttemplate = "%{text}",
hovertemplate = "%{x} vs %{y}: %{z:.2f}<extra></extra>") |>
layout(title = "Matriz de correlación (Spearman)",
xaxis = list(tickangle = -35), yaxis = list(autorange = "reversed"))Interpretación (en salud general, valores altos significan peor salud):
| # | Hallazgo | Implicación para la gestión del riesgo |
|---|---|---|
| 1 | Base grande (401.958 adultos), pero con 45,7 % de celdas vacías por diseño modular; ingreso sin dato en ~20 %. | Analizar por módulo y documentar faltantes; no eliminar registros en bloque. Mejorar la captura de variables socioeconómicas en los propios sistemas de información. |
| 2 | Gradiente socioeconómico claro: la mala salud es 5,5 veces mayor en ingreso bajo que en alto; la barrera de costo, casi 4 veces mayor. | Focalizar recursos de prevención por nivel socioeconómico; el costo de bolsillo es una barrera de acceso medible y modificable. |
| 3 | Los factores de riesgo modificables se acumulan (28 % tiene 2 o más) y la prevalencia coronaria crece con cada factor adicional en todos los grupos de edad. | Usar el conteo de factores como herramienta sencilla de estratificación del riesgo en atención primaria. |
| 4 | El segmento de 35-64 años de bajo ingreso concentra la peor salud y la mayor barrera económica, mientras que en 65+ la barrera cae. | Priorizar este segmento en programas de detección temprana y control de riesgo; la cobertura financiera reduce la barrera de acceso. |
| 5 | Los valores extremos en días de mala salud (~15 %) representan población de alta carga, no errores. | Identificar y gestionar a los usuarios de alta carga (gestión de casos); revisar solo los extremos de IMC biológicamente improbables. |
| 6 | Las correlaciones son débiles a moderadas y multifactoriales. | Justifica la siguiente fase: modelamiento con varias variables y uso del peso muestral. |