Guatemala, como país centroamericano con dinámicas poblacionales complejas, enfrenta desafíos críticos en materia de salud pública y planificación demográfica. Este estudio surge de la necesidad de comprender los patrones fundamentales que gobiernan los eventos vitales de la población, particularmente en el contexto postpandémico entre 2021 y 2023.
La base del proyecto radica en datos oficiales de registros civiles, proporcionando información detallada sobre más de 30 variables demográficas, socioeconómicas y geográficas asociadas a nacimientos y defunciones. Estos datos, aunque ricos en contenido, presentaban desafíos técnicos significativos en su estructuración, incluyendo codificaciones complejas, dispersión en múltiples archivos anuales y necesidad de normalización semántica.
El análisis se centra en tres ejes principales: la evolución temporal de los indicadores vitales, las disparidades regionales en el acceso a servicios de salud, y los factores sociodemográficos que influyen en los resultados perinatales y la mortalidad general. La relevancia trasciende lo académico, apuntando a identificar puntos críticos para intervenciones públicas efectivas.
evolution <- bind_rows(
birth$data %>%
count(year = `Añoocu`, month = `Mesocu`) %>%
mutate(type = "birth"),
death$data %>%
count(year = `Añoocu`, month = `Mesocu`) %>%
mutate(type = "death")
) %>%
mutate(year = as.numeric(year), month = as.numeric(month)) %>%
arrange(year, month)
ggplot(evolution, aes(x = month, y = n, fill = type)) +
geom_area(position = "identity") +
facet_wrap(~year, ncol = 1) +
scale_x_continuous(breaks = seq(1, 12), labels = month_names) +
scale_fill_catppuccin(palette = "mocha", alpha = 0.8) +
labs(
title = "Evolución Mensual Comparada de Nacimientos y Defunciones",
x = "Mes", y = "Cantidad", fill = "Tipo"
) +
dark_theme
Lectura: El gráfico muestra la superposición temporal de nacimientos (tonos azules) y defunciones (tonos duraznos) mes a mes. Las áreas más amplias indican mayor volumen de eventos. Se observan picos estacionales en nacimientos durante enero, marzo, mayo y septiembre, y un volumen constante de mortalidad en general. La altura relativa de las áreas permite comparar proporciones interanuales.
births_kg <- birth$data %>%
mutate(weight = to_kg(`Libras`, `Onzas`)) %>%
mutate(mothers_age = as.numeric(`Edadm`)) %>%
filter(`Libras` != "99", `Onzas` != "99", `Edadm` != 999) %>%
select(weight, mothers_age)
ggplot(births_kg, aes(x = mothers_age, y = weight)) +
geom_hex(bins = 30) +
scale_fill_viridis(option = "C", alpha = 0.8) +
labs(
title = "Densidad de Edad Materna vs Peso al Nacer",
x = "Edad de la Madre", y = "Peso (kg)", fill = "Nacimientos"
) +
dark_theme
Lectura: La densidad de puntos revela concentraciones poblacionales. Los hexágonos más cercanos al amarillo indican mayor frecuencia de casos, mientras que los cercanos al azul obscuro indican la menor frecuencia de casos. Mientras que la falta de los mismos significa que no hay casos.
survived <- death$data %>%
inner_join(death$vars$`Puedif`, by = c("Puedif" = "code")) %>%
mutate(age = as.numeric(`Edadif`)) %>%
select(pueblo = label, age) %>%
filter(pueblo != "Ignorado", age != 999)
fit <- survfit(Surv(age) ~ pueblo, data = survived)
ggsurvplot(fit,
data = survived,
title = "Supervivencia por Grupo Étnico",
xlab = "Edad",
ylab = "Probabilidad de supervivencia",
legend.title = "Pueblo",
legend.labs = c("Garifuna", "Xinca", "Mestizo / Ladino", "Otro", "Xinka"),
risk.table = TRUE,
legend = "right",
ggtheme = dark_theme,
tables.col = "strata",
risk.table.title = "Supervivencia",
)
Lectura: Las curvas muestran probabilidad acumulada de supervivencia por edad. La brecha entre líneas indica disparidades. La tabla inferior cuantifica población en riesgo por grupo. La caída abrupta en ciertas edades sugiere causas específicas de mortalidad.
causes <- death$data %>%
mutate(age_group = cut(as.numeric(`Edadif`),
breaks = c(0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
)) %>%
count(`Caudef`, age_group) %>%
inner_join(death$vars$`Caudef`, by = c("Caudef" = "code")) %>%
select(cause = label, age_group, n) %>%
group_by(age_group) %>%
top_n(5, n)
treemap(causes,
index = c("age_group", "cause"),
vSize = "n",
title = "Principales Causas de Muerte por Grupo de Edad"
)
Lectura: El tamaño de cada rectángulo representa frecuencia relativa. Los colores distinguen grupos etarios. La distribución vertical jerarquiza causas principales por franja.
ocupation <- birth$data %>%
select(father_ocupation = `Ocupap`, mother_ocupation = `Ocupam`) %>%
inner_join(birth$vars$`Ocupap`, by = c("father_ocupation" = "code")) %>%
select(father_ocupation = label, mother_ocupation) %>%
inner_join(birth$vars$`Ocupam`, by = c("mother_ocupation" = "code")) %>%
select(father_ocupation, mother_ocupation = label) %>%
gather(parents, ocupation) %>%
count(parents, ocupation) %>%
top_n(20, n)
ggplot(ocupation, aes(label = ocupation, size = n, color = parents)) +
geom_text_wordcloud_area(shape = "square", eccentricity = 0.35) +
scale_size_area(max_size = 50, trans = power_trans(0.55)) +
facet_wrap(~parents, ncol = 1, labeller = as_labeller(c(
`father_ocupation` = "Ocupación del Padre",
`mother_ocupation` = "Ocupación de la Madre"
))) +
labs(title = "Ocupaciones más Comunes de Padres vs Madres") +
dark_theme
Lectura: El tamaño de palabra corresponde a frecuencia. La disposición vertical separa géneros. Las ocupaciones alineadas arriba muestran predominio masculino, abajo femenino. La densidad superior indica mayor diversidad ocupacional en un género.
education_vs_cause <- death$data %>%
select(`Escodif`, `Caudef`) %>%
inner_join(death$vars$`Escodif`, by = c("Escodif" = "code")) %>%
mutate(cause = substr(`Caudef`, 0, 3)) %>%
select(education = label, cause) %>%
inner_join(death$vars$`Caudef`, by = c("cause" = "code")) %>%
select(education, cause = label) %>%
group_by(education, cause) %>%
summarise(count = n(), .groups = "drop") %>%
filter(count > 500)
ggplot(education_vs_cause, aes(x = education, y = cause)) +
geom_tile(aes(fill = count), color = "white") +
scale_fill_viridis(option = "C", alpha = 0.8) +
labs(
title = "Causas de Muerte más relacionadas con Escolaridad",
x = "Escolaridad",
y = "Causa de Muerte",
fill = "Count"
) +
dark_theme
Lectura: Los cuadros más amarillos representan mayor asociación. Las columnas muestran nivel educativo, filas causas de muerte. Los vacíos indican combinaciones improbables o sin datos significativos.
temporal_pattern <- birth$data %>%
mutate(month = as.numeric(`Mesocu`), year = as.numeric(`Añoocu`)) %>%
count(month, year) %>%
arrange(year, month)
ggplot(temporal_pattern, aes(x = month, y = n, color = factor(year))) +
geom_line(linewidth = 1.2) +
coord_polar() +
scale_x_continuous(breaks = seq(1, 12), labels = month_names) +
scale_fill_catppuccin(palette = "mocha", alpha = 0.8) +
labs(
title = "Patrón Estacional de Nacimientos",
fill = "Año",
color = "Año",
x = "Mes",
y = "Cantidad"
) +
dark_theme
Lectura: La disposición circular muestra periodicidad anual. Los radios representan meses, los anillos años. La proximidad al centro indica menor cantidad. Los picos coincidentes en múltiples años revelan patrones estacionales consistentes.
top_causes <- death$data %>%
mutate(cause = substr(`Caudef`, 0, 3)) %>%
inner_join(death$vars$`Caudef`, by = c("cause" = "code")) %>%
count(cause = label) %>%
top_n(10, n) %>%
arrange(desc(n))
ggplot(top_causes, aes(x = n, y = cause, fill = cause)) +
geom_col(orientation = "y") +
geom_text(aes(label = n), hjust = 1.5, color = "#1e1e2e", size = 5) +
scale_fill_catppuccin(palette = "mocha", alpha = 0.8) +
labs(
title = "10 Principales Causas de Muerte",
x = "Cantidad de casos",
y = ""
) +
dark_theme +
theme(axis.text.y = element_blank())
Lectura: Las barras horizontales priorizan frecuencia. El contraste cromático destaca las diez principales causas. Los valores numéricos permiten comparación cuantitativa directa. La longitud relativa muestra dominancia de causas específicas.
birth_type <- birth$data %>%
inner_join(birth$vars$`Tipar`, by = c("Tipar" = "code")) %>%
count(type = label, year = `Añoocu`) %>%
filter(type != "Simple")
ggplot(birth_type, aes(x = type, y = n, fill = type)) +
geom_bar(stat = "identity", color = "#1e1e2e") +
coord_polar() +
facet_wrap(~year, ncol = 1) +
scale_y_log10(labels = scales::comma) +
scale_fill_catppuccin(palette = "mocha", alpha = 0.8) +
labs(
title = "Distribución de Tipos de Parto No Simples",
x = "Año",
y = "Número de Partos"
) +
dark_theme
Lectura: Los segmentos circulares representan proporciones. Los colores distinguen categorías. El espacio central vacío enfatiza relaciones parte-todo. La distribución por año muestra estabilidad temporal.
civil_status <- death$data %>%
inner_join(death$vars$Ecidif, by = c("Ecidif" = "code")) %>%
select(civil_status = label, `Sexo`) %>%
inner_join(death$vars$Sexo, by = c("Sexo" = "code")) %>%
count(civil_status, sex = label) %>%
filter(!str_detect(civil_status, "Ignorado"))
ggplot(civil_status, aes(axis1 = civil_status, axis2 = sex, y = n)) +
geom_alluvium(aes(fill = sex)) +
geom_stratum() +
geom_text(stat = "stratum", aes(label = after_stat(stratum))) +
scale_y_log10() +
scale_fill_catppuccin(palette = "mocha", alpha = 0.8) +
labs(
title = "Mortalidad por Estado Civil y Sexo",
x = "",
y = ""
) +
dark_theme
Lectura: El flujo entre columnas muestra transiciones. El ancho de las bandas indica volumen. Los colores distinguen género. La altura de los estratos representa proporciones. Los patrones de conexión revelan asociaciones demográficas complejas.