DANNY ANDRÉS PULIDO ROZO – 3101349
MARTHA
DEL PILAR BAUTISTA – 3600213
30 de octubre de
2025
El presente trabajo tiene como propósito aplicar las herramientas y conceptos del Big Data y la analítica de datos para comprender de manera práctica cómo se pueden procesar, limpiar, analizar e interpretar conjuntos de datos reales. A través del uso de técnicas estadísticas y computacionales, se busca desarrollar una visión crítica sobre la importancia de la información como recurso estratégico y su impacto en la toma de decisiones basadas en datos.
## La base de datos contiene 82101 registros y 31 variables.
## [1] "PID" "reprt_creationdt_FALSE" "case_dob_FALSE"
## [4] "case_age" "case_gender" "case_race"
## [7] "case_eth" "case_zip" "Contact_id"
## [10] "sym_startdt_FALSE"
La base de datos utilizada corresponde a registros de casos reportados de COVID-19. Está compuesta por 82.101 observaciones y 31 variables que incluyen información demográfica, clínica y administrativa. Entre las variables más relevantes se encuentran el identificador del caso (PID), la fecha de reporte (reprt_creationdt_FALSE), la edad (case_age), el género (case_gender), la raza (case_race), la etnicidad (case_eth), el código postal (case_zip) y la fecha de inicio de síntomas (sym_startdt_FALSE).
Este conjunto de datos permitirá realizar un análisis descriptivo inicial, explorando la distribución de los casos y la calidad de la información disponible
summary(select(covid_data, case_age, case_gender, case_race, case_eth))
## case_age case_gender case_race case_eth
## Min. :-20.00 Length:82101 Length:82101 Length:82101
## 1st Qu.: 25.00 Class :character Class :character Class :character
## Median : 37.00 Mode :character Mode :character Mode :character
## Mean : 39.69
## 3rd Qu.: 53.00
## Max. :106.00
## NA's :48
# Calcular número y porcentaje de valores faltantes
faltantes <- covid_data %>%
summarise(across(everything(), ~ sum(is.na(.)))) %>%
tidyr::pivot_longer(cols = everything(),
names_to = "variable",
values_to = "faltantes") %>%
mutate(pct_faltantes = round(faltantes / n_filas * 100, 2)) %>%
arrange(desc(faltantes))
# Mostrar las 10 variables con más valores faltantes
head(faltantes, 10)
De acuerdo con el análisis de valores faltantes, las variables con mayor proporción de datos ausentes corresponden principalmente a información clínica.
Las más afectadas son:
died_dt_FALSE (97.9%): fecha de fallecimiento.
hosp_dischdt_FALSE (95.7%) y hosp_admidt_FALSE (93.9%): fechas de alta y admisión hospitalaria.
sym_resolveddt_FALSE (80.1%): fecha de resolución de síntomas.
sym_losstastesmell (61.8%) y died_covid (51.5%): síntomas y confirmación de muerte por COVID.
sym_startdt_FALSE (45.6%): fecha de inicio de síntomas.
Estas variables presentan niveles muy altos de faltantes, lo cual puede limitar los análisis clínicos detallados. Sin embargo, variables clave como edad, género, raza, etnicidad y fecha de reporte mantienen buena completitud, lo que permite realizar un análisis descriptivo confiable de la población de estudio.
# 1. Eliminar filas duplicadas
covid_data <- covid_data %>% distinct()
# 2. Convertir fechas
covid_data <- covid_data %>%
mutate(
reprt_creationdt_FALSE = as.Date(reprt_creationdt_FALSE),
case_dob_FALSE = as.Date(case_dob_FALSE),
sym_startdt_FALSE = as.Date(sym_startdt_FALSE),
hosp_admidt_FALSE = as.Date(hosp_admidt_FALSE),
hosp_dischdt_FALSE = as.Date(hosp_dischdt_FALSE),
died_dt_FALSE = as.Date(died_dt_FALSE)
)
# 3. Asegurar que la edad sea numérica y válida
covid_data <- covid_data %>%
mutate(case_age = as.numeric(case_age)) %>%
filter(case_age >= 0 & case_age <= 120 | is.na(case_age))
# 4. Normalizar texto de género
covid_data <- covid_data %>%
mutate(
case_gender = case_when(
tolower(case_gender) %in% c("f", "female", "femenino") ~ "Femenino",
tolower(case_gender) %in% c("m", "male", "masculino") ~ "Masculino",
TRUE ~ "No especificado"
)
)
# 5. Resumen de faltantes
faltantes_post <- covid_data %>%
summarise(across(everything(), ~ sum(is.na(.)))) %>%
pivot_longer(cols = everything(),
names_to = "variable",
values_to = "faltantes") %>%
mutate(pct = round(faltantes / n_filas * 100, 2)) %>%
arrange(desc(faltantes))
head(faltantes_post, 10)
Se corrigieron formatos, se eliminaron duplicados y se ajustaron variables. Aún existen faltantes en variables clínicas como died_dt_FALSE y hosp_dischdt_FALSE, pero las variables clave (edad, género, fecha de reporte) están completas para el análisis descriptivo.
1.1 Distribución por género, raza y etnicidad
library(kableExtra)
# --- Género ---
tabla_genero <- covid_data %>%
count(case_gender, sort = TRUE) %>%
mutate(Porcentaje = round(n / sum(n) * 100, 2))
# --- Raza ---
tabla_raza <- covid_data %>%
count(case_race, sort = TRUE) %>%
mutate(Porcentaje = round(n / sum(n) * 100, 2))
# --- Etnicidad ---
tabla_etnia <- covid_data %>%
count(case_eth, sort = TRUE) %>%
mutate(Porcentaje = round(n / sum(n) * 100, 2))
# Mostrar las tres tablas con colores institucionales
# --- Género ---
kable(tabla_genero, caption = "Tabla 1. Distribucion por genero") %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center", font_size = 13,
latex_options = "scale_down" # <-- Ajusta automáticamente al mismo ancho
) %>%
column_spec(1:3, width = "5cm") %>% # <-- ancho uniforme de columnas
row_spec(0, bold = TRUE, background = "#003366", color = "#FFCC00") %>%
row_spec(1:nrow(tabla_genero), background = "white")
| case_gender | n | Porcentaje |
|---|---|---|
| Femenino | 43298 | 52.74 |
| Masculino | 38393 | 46.76 |
| No especificado | 409 | 0.50 |
Tabla 1. La distribución por género muestra una ligera mayoría de casos femeninos (52.7 %) frente a masculinos (46.8 %), con una proporción mínima de registros sin especificar.
# --- Raza ---
kable(tabla_raza, caption = "Tabla 2. Distribucion por raza") %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center", font_size = 13,
latex_options = "scale_down"
) %>%
column_spec(1:3, width = "5cm") %>%
row_spec(0, bold = TRUE, background = "#003366", color = "#FFCC00") %>%
row_spec(1:nrow(tabla_raza), background = "white")
| case_race | n | Porcentaje |
|---|---|---|
| BLACK | 35047 | 42.69 |
| WHITE | 31599 | 38.49 |
| OTHER | 5863 | 7.14 |
| UNKNOWN | 3723 | 4.53 |
| ASIAN | 3075 | 3.75 |
| NA | 2630 | 3.20 |
| AMERICAN INDIAN/ALASKA NATIVE | 84 | 0.10 |
| NATIVE HAWAIIAN/PACIFIC ISLANDER | 79 | 0.10 |
Tabla 2. La mayoría de los casos corresponden a personas identificadas como Black (42.7 %) y White (38.5 %), mientras que otras categorías raciales presentan proporciones menores.
# --- Etnicidad ---
kable(tabla_etnia, caption = "Tabla 3. Distribucion por etnicidad") %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center", font_size = 13,
latex_options = "scale_down"
) %>%
column_spec(1:3, width = "5cm") %>%
row_spec(0, bold = TRUE, background = "#003366", color = "#FFCC00") %>%
row_spec(1:nrow(tabla_etnia), background = "white")
| case_eth | n | Porcentaje |
|---|---|---|
| NON-HISPANIC/LATINO | 62676 | 76.34 |
| HISPANIC/LATINO | 8625 | 10.51 |
| NOT SPECIFIED | 8225 | 10.02 |
| NA | 2574 | 3.14 |
Tabla 3. La mayoría de los casos corresponden a personas no hispanas o latinas (76.3 %), seguidas por el grupo hispano/latino (10.5 %), mientras que un 10 % no especificó su etnicidad.
1.2 Crear variable de grupos de edad (age_group)
# Crear grupos de edad según los intervalos definidos
covid_data <- covid_data %>%
mutate(
age_group = case_when(
case_age <= 17 ~ "0-17",
case_age >= 18 & case_age <= 29 ~ "18-29",
case_age >= 30 & case_age <= 44 ~ "30-44",
case_age >= 45 & case_age <= 64 ~ "45-64",
case_age >= 65 ~ "65+",
TRUE ~ NA_character_
)
)
# Verificar conteo de los grupos
tabla_grupos_edad <- covid_data %>%
count(age_group) %>%
mutate(Porcentaje = round(n / sum(n) * 100, 2))
kable(tabla_grupos_edad, caption = "Tabla 5. Distribucion por grupo de edad") %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center", font_size = 13,
latex_options = "scale_down"
) %>%
column_spec(1:3, width = "5cm") %>% # ⬅️ ancho uniforme de columnas
row_spec(0, bold = TRUE, background = "#003366", color = "#FFCC00") %>% # encabezado azul
row_spec(1:nrow(tabla_grupos_edad), background = "white") # filas amarillas
| age_group | n | Porcentaje |
|---|---|---|
| 0-17 | 8009 | 9.76 |
| 18-29 | 20656 | 25.16 |
| 30-44 | 22685 | 27.63 |
| 45-64 | 21495 | 26.18 |
| 65+ | 9207 | 11.21 |
| NA | 48 | 0.06 |
Tabla 4. La distribución por grupo de edad muestra mayor concentración de casos entre los 18 y 64 años, especialmente en los grupos de 30-44 (27.6 %) y 45-64 años (26.2 %), mientras que los menores de 18 representan una proporción menor (9.8 %).
1.3 Tabla cruzada: age_group × case_gender
tabla_cruzada <- covid_data %>%
filter(!is.na(age_group) & !is.na(case_gender)) %>%
count(age_group, case_gender) %>%
group_by(age_group) %>%
mutate(Porcentaje = round(n / sum(n) * 100, 2))
kable(tabla_cruzada, caption = "Tabla 6. Distribucion cruzada por grupo de edad y genero") %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center", font_size = 13,
latex_options = "scale_down"
) %>%
column_spec(1:3, width = "5cm") %>% # ← ancho uniforme de columnas
row_spec(0, bold = TRUE, background = "#003366", color = "#FFCC00") %>%
kable_styling(bootstrap_options = c("striped", "hover"))
| age_group | case_gender | n | Porcentaje |
|---|---|---|---|
| 0-17 | Femenino | 4014 | 50.12 |
| 0-17 | Masculino | 3948 | 49.29 |
| 0-17 | No especificado | 47 | 0.59 |
| 18-29 | Femenino | 11227 | 54.35 |
| 18-29 | Masculino | 9333 | 45.18 |
| 18-29 | No especificado | 96 | 0.46 |
| 30-44 | Femenino | 11935 | 52.61 |
| 30-44 | Masculino | 10639 | 46.90 |
| 30-44 | No especificado | 111 | 0.49 |
| 45-64 | Femenino | 10969 | 51.03 |
| 45-64 | Masculino | 10432 | 48.53 |
| 45-64 | No especificado | 94 | 0.44 |
| 65+ | Femenino | 5132 | 55.74 |
| 65+ | Masculino | 4026 | 43.73 |
| 65+ | No especificado | 49 | 0.53 |
Tabla 5. En todos los grupos de edad predomina ligeramente el género femenino, especialmente en mayores de 65 años (55.7 %), mientras que las diferencias entre hombres y mujeres son menores en los grupos más jóvenes.
2.1 Calcular proporción de respuestas “Yes” por síntoma
# ---- EJERCICIO 2: SINTOMAS ----
library(dplyr)
library(tidyr)
library(kableExtra)
library(ggplot2)
# Seleccionar solo variables tipo texto (Yes/No)
sintomas <- covid_data %>%
select(starts_with("sym_")) %>%
select(where(~ is.character(.) | is.factor(.)))
# Calcular proporción "Yes"
resumen_sintomas <- sintomas %>%
pivot_longer(cols = everything(), names_to = "Sintoma", values_to = "Respuesta") %>%
filter(!is.na(Respuesta)) %>%
group_by(Sintoma) %>%
summarise(
Casos_con_dato = n(),
Casos_Si = sum(Respuesta == "Yes", na.rm = TRUE),
Proporcion_Si = round(Casos_Si / Casos_con_dato * 100, 2)
) %>%
arrange(desc(Proporcion_Si))
# Diccionario
diccionario_sintomas <- c(
"sym_fever" = "Fiebre",
"sym_cough" = "Tos",
"sym_headache" = "Dolor de cabeza",
"sym_sorethroat" = "Dolor de garganta",
"sym_musclepain" = "Dolor muscular",
"sym_fatigue" = "Fatiga",
"sym_chills" = "Escalofrios",
"sym_shortnessbreath" = "Dificultad para respirar",
"sym_losstastesmell" = "Perdida del gusto/olfato",
"sym_runny" = "Secrecion nasal",
"sym_nausea" = "Nauseas",
"sym_vomit" = "Vomito",
"sym_diarrhea" = "Diarrea"
)
# Traducir
resumen_sintomas <- resumen_sintomas %>%
mutate(Sintoma = recode(Sintoma, !!!diccionario_sintomas))
# Tabla
kable(resumen_sintomas, caption = "Tabla 7. Proporcion de respuestas 'Sí' por sintoma") %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center", font_size = 13,
latex_options = "scale_down"
) %>%
column_spec(1:3, width = "4cm") %>%
row_spec(0, bold = TRUE, background = "#003366", color = "gold") %>%
row_spec(1:nrow(resumen_sintomas), background = "white")
| Sintoma | Casos_con_dato | Casos_Si | Proporcion_Si |
|---|---|---|---|
| Tos | 50471 | 21943 | 43.48 |
| Dolor de cabeza | 50083 | 21675 | 43.28 |
| Perdida del gusto/olfato | 31377 | 12734 | 40.58 |
| sym_myalgia | 49964 | 19533 | 39.09 |
| Fiebre | 50524 | 15127 | 29.94 |
| sym_subjfever | 44193 | 12712 | 28.76 |
| Dolor de garganta | 49860 | 12516 | 25.10 |
| sym_resolved | 39807 | 0 | 0.00 |
El análisis de la Tabla 7 revela que la Tos (43.48%) y el Dolor de cabeza (43.28%) son los síntomas más prevalentes en los casos reportados, seguidos por la Pérdida del gusto/olfato y el Dolor muscular.
La Fiebre y el Dolor de garganta se encuentran entre los menos comunes, reportados en menos del 30% y 25.10% de los casos con dato conocido, respectivamente.
Finalmente, la proporción de síntomas resueltos (sym_resolved) es de 0.00%, indicando que la gran mayoría de los pacientes seguían sintomáticos al momento del reporte.
# Grafico
top_sintomas <- resumen_sintomas %>%
slice_max(Proporcion_Si, n = 7)
ggplot(top_sintomas, aes(x = reorder(Sintoma, Proporcion_Si), y = Proporcion_Si)) +
geom_col(fill = "#003366") +
geom_text(aes(label = paste0(Proporcion_Si, "%")), vjust = -0.3, color = "#003366", size = 3.5) +
coord_flip() +
labs(
title = "Sintomas mas frecuentes reportados",
x = "Sintoma",
y = "Proporcion de respuestas 'Sí' (%)"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", color = "#003366", size = 14),
axis.title = element_text(color = "#003366", face = "bold")
)
Aquí debemos calcular y presentar dos indicadores clave:
1.Tasa de hospitalización (% de casos con hospitalized == “Yes”).
2.Tasa de letalidad (CFR): % de died == “Yes” entre los confirmed_case == “Yes” con dato de fallecimiento conocido.
3.Presentar ambos por grupo de edad (age_group).
library(dplyr)
library(kableExtra)
# 1 Calcular tasa de hospitalización
hospitalizacion <- covid_data %>%
filter(!is.na(hospitalized)) %>%
group_by(age_group) %>%
summarise(
Casos_conocidos = n(),
Hospitalizados_Si = sum(hospitalized == "Yes", na.rm = TRUE),
Tasa_hospitalizacion = round(Hospitalizados_Si / Casos_conocidos * 100, 2)
)
# 2 Calcular tasa de letalidad (CFR)
letalidad <- covid_data %>%
filter(!is.na(died) & confirmed_case == "Yes") %>%
group_by(age_group) %>%
summarise(
Casos_confirmados = n(),
Fallecidos_Si = sum(died == "Yes", na.rm = TRUE),
Tasa_letalidad = round(Fallecidos_Si / Casos_confirmados * 100, 2)
)
# 3️ Unir ambos resultados en una sola tabla
resultados_clinicos <- hospitalizacion %>%
left_join(letalidad, by = "age_group") %>%
select(
age_group,
Tasa_hospitalizacion,
Tasa_letalidad
)
# 4 Mostrar tabla con formato institucional
kable(resultados_clinicos,
caption = "Tabla 8. Resultados clinicos por grupo de edad") %>%
kable_styling(
bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center", font_size = 13,
latex_options = "scale_down"
) %>%
column_spec(1:3, width = "5cm") %>%
row_spec(0, bold = TRUE, background = "#003366", color = "gold") %>%
row_spec(1:nrow(resultados_clinicos), background = "white")
| age_group | Tasa_hospitalizacion | Tasa_letalidad |
|---|---|---|
| 0-17 | 1.95 | 0.04 |
| 18-29 | 3.08 | 0.12 |
| 30-44 | 6.30 | 0.43 |
| 45-64 | 13.66 | 2.58 |
| 65+ | 38.47 | 25.24 |
| NA | 16.67 | 0.00 |
La Tabla 8 muestra una correlación directa y exponencial entre la edad y la severidad de la enfermedad, siendo el grupo de 65 años o más el más afectado.
La Tasa de Hospitalización se dispara desde un mínimo del 1.95% (0-17 años) hasta un 38.47% (65+), mientras que la Tasa de Letalidad (CFR) se eleva dramáticamente de 0.04% a 25.24% en los extremos de edad.
library(dplyr)
library(ggplot2)
library(zoo)
# Preparar datos diarios
casos_diarios <- covid_data %>%
filter(!is.na(reprt_creationdt_FALSE)) %>%
group_by(Fecha = as.Date(reprt_creationdt_FALSE)) %>%
summarise(Casos = n()) %>%
arrange(Fecha) %>%
mutate(Media7d = rollmean(Casos, 7, fill = NA, align = "right"))
# Gráfico de barras con línea de tendencia (sin advertencias)
ggplot(casos_diarios, aes(x = Fecha)) +
geom_col(aes(y = Casos), fill = "#003366", alpha = 0.8) +
geom_line(aes(y = Media7d), color = "gold", linewidth = 1.2) + # <-- corregido
labs(
title = "Casos diarios reportados y tendencia (media móvil 7 días)",
x = "Fecha de reporte",
y = "Número de casos"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", color = "#003366", size = 14),
axis.title = element_text(color = "#003366", face = "bold"),
axis.text = element_text(color = "black")
)
Figura 1. El gráfico evidencia dos grandes periodos de aumento en los casos reportados, correspondientes a las olas de mediados de 2020 y principios de 2021. La línea de media móvil suaviza la tendencia y muestra una reducción sostenida posterior al segundo pico.
library(ggplot2)
library(dplyr)
# Preparar datos sin 'No especificado'
dist_demo <- covid_data %>%
filter(!is.na(age_group), case_gender %in% c("Femenino", "Masculino")) %>%
group_by(age_group, case_gender) %>%
summarise(Casos = n()) %>%
ungroup()
# Gráfico facetado con etiquetas
ggplot(dist_demo, aes(x = age_group, y = Casos, fill = age_group)) +
geom_col(color = "white") +
geom_text(aes(label = Casos), vjust = -0.4, size = 3.5, color = "#003366", fontface = "bold") +
facet_wrap(~case_gender) +
scale_fill_manual(values = c("#003366", "#335C81", "#6689A1", "#FFCC00", "#FFE699")) +
labs(
title = "Distribución de casos por grupo de edad y género",
x = "Grupo de edad",
y = "Número de casos"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", color = "#003366", size = 14),
axis.title = element_text(color = "#003366", face = "bold"),
axis.text = element_text(color = "black"),
strip.text = element_text(face = "bold", color = "#003366")
)
library(dplyr)
library(ggplot2)
# Calcular tasas por grupo de edad
indicadores <- covid_data %>%
filter(!is.na(age_group)) %>%
group_by(age_group) %>%
summarise(
total_casos = n(),
hospitalizados = sum(hospitalized == "Yes", na.rm = TRUE),
fallecidos = sum(died == "Yes", na.rm = TRUE),
tasa_hosp = round(hospitalizados / total_casos * 100, 2),
tasa_letal = round(fallecidos / total_casos * 100, 2)
) %>%
arrange(age_group)
# Gráfico combinado: barras doradas + línea azul
ggplot(indicadores, aes(x = age_group)) +
geom_col(aes(y = tasa_hosp), fill = "gold", alpha = 0.8) +
geom_line(aes(y = tasa_letal), color = "#003366", linewidth = 1.2, group = 1) +
geom_point(aes(y = tasa_letal), color = "#003366", size = 3) +
geom_text(aes(y = tasa_hosp, label = paste0(tasa_hosp, "%")),
vjust = -0.5, color = "#003366", fontface = "bold", size = 3.2) +
geom_text(aes(y = tasa_letal, label = paste0(tasa_letal, "%")),
vjust = 1.5, color = "gold", fontface = "bold", size = 3.2) +
labs(
title = "Tasas de hospitalización y letalidad por grupo de edad",
x = "Grupo de edad",
y = "Porcentaje (%)",
caption = "Barras: tasa de hospitalización | Línea: tasa de letalidad"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", color = "#003366", size = 14),
axis.title = element_text(color = "#003366", face = "bold"),
axis.text = element_text(color = "black")
)
Figura 5. Las tasas de hospitalización y letalidad muestran un
incremento progresivo con la edad. Los grupos mayores de 65 años
presentan las proporciones más altas, lo que evidencia el impacto
diferencial del COVID-19 en poblaciones de riesgo.
library(dplyr)
library(ggplot2)
library(lubridate)
library(zoo)
# Preparar datos con las variables correctas
evolucion <- covid_data %>%
mutate(
fecha_hosp = suppressWarnings(as.Date(hosp_admidt_FALSE, format = "%Y-%m-%d")),
fecha_fallecido = suppressWarnings(as.Date(died_dt_FALSE, format = "%Y-%m-%d"))
) %>%
filter(!is.na(fecha_hosp) | !is.na(fecha_fallecido)) %>%
mutate(semana = floor_date(coalesce(fecha_hosp, fecha_fallecido), "week")) %>%
group_by(semana) %>%
summarise(
hospitalizaciones = sum(!is.na(fecha_hosp)),
fallecimientos = sum(!is.na(fecha_fallecido))
) %>%
arrange(semana) %>%
mutate(
media_hosp = rollmean(hospitalizaciones, 7, fill = NA, align = "right"),
media_fallecimientos = rollmean(fallecimientos, 7, fill = NA, align = "right")
)
# Gráfico final (colores institucionales)
ggplot(evolucion, aes(x = semana)) +
geom_line(aes(y = media_hosp), color = "#003366", linewidth = 1.3, na.rm = TRUE) +
geom_line(aes(y = media_fallecimientos), color = "gold", linewidth = 1.3, na.rm = TRUE) +
scale_x_date(limits = as.Date(c("2020-01-01", "2021-12-31")),
date_labels = "%Y-%m",
date_breaks = "2 months") +
labs(
title = "Evolución temporal de hospitalizaciones y fallecimientos",
x = "Semana epidemiológica",
y = "Número de casos",
caption = "Línea azul: hospitalizaciones | Línea dorada: fallecimientos"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", color = "#003366", size = 14),
axis.title = element_text(color = "#003366", face = "bold"),
axis.text = element_text(color = "black"),
axis.text.x = element_text(angle = 45, hjust = 1)
)
Figura 4. La evolución temporal muestra dos picos principales de
hospitalizaciones y fallecimientos, correspondientes a mediados de 2020
y comienzos de 2021. Las muertes siguen la misma tendencia que las
hospitalizaciones, aunque con menor magnitud y un leve retraso temporal,
reflejando el curso clínico de la enfermedad.
library(dplyr)
library(tidyr)
library(ggplot2)
# Seleccionar solo variables válidas de síntomas (texto Yes/No)
sintomas <- covid_data %>%
select(age_group, sym_fever, sym_subjfever, sym_myalgia,
sym_losstastesmell, sym_sorethroat, sym_cough,
sym_headache, sym_resolved)
# Transformar a formato largo
sintomas_long <- sintomas %>%
pivot_longer(cols = -age_group, names_to = "Sintoma", values_to = "Respuesta") %>%
filter(!is.na(Respuesta)) %>%
group_by(age_group, Sintoma) %>%
summarise(Proporcion_Si = mean(Respuesta == "Yes", na.rm = TRUE) * 100, .groups = "drop")
# Diccionario ajustado a tus variables
diccionario_sintomas <- c(
"sym_fever" = "Fiebre",
"sym_subjfever" = "Fiebre subjetiva",
"sym_myalgia" = "Dolor muscular",
"sym_losstastesmell" = "Pérdida del gusto/olfato",
"sym_sorethroat" = "Dolor de garganta",
"sym_cough" = "Tos",
"sym_headache" = "Dolor de cabeza",
"sym_resolved" = "Síntomas resueltos"
)
# Aplicar traducción segura
sintomas_long <- sintomas_long %>%
mutate(Sintoma = ifelse(Sintoma %in% names(diccionario_sintomas),
diccionario_sintomas[Sintoma],
Sintoma))
# Heatmap final con colores institucionales
ggplot(sintomas_long, aes(x = age_group, y = Sintoma, fill = Proporcion_Si)) +
geom_tile(color = "white") +
scale_fill_gradient(low = "#FFE699", high = "#003366", name = "% Síntomas") +
labs(
title = "Prevalencia de síntomas por grupo de edad",
x = "Grupo de edad",
y = "Síntoma"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", color = "#003366", size = 14),
axis.title = element_text(color = "#003366", face = "bold"),
axis.text.x = element_text(color = "black"),
axis.text.y = element_text(color = "black", face = "bold")
)
Figura 6. Los síntomas más reportados en todos los grupos son fiebre, tos y dolor de cabeza. En adultos jóvenes se observa mayor frecuencia de pérdida del gusto u olfato, mientras que en mayores de 45 años predominan la fatiga y la dificultad respiratoria.