library(readxl)
library(tidyverse)
library(janitor)
library(lubridate)
library(zoo)
##
## Adjuntando el paquete: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
library(scales)
##
## Adjuntando el paquete: 'scales'
## The following object is masked from 'package:purrr':
##
## discard
## The following object is masked from 'package:readr':
##
## col_factor
library(gt)
library(readxl)
df <- read_excel("2. covid_example_data.xlsx")
head(df)
## # A tibble: 6 × 31
## PID reprt_creationdt_FALSE case_dob_FALSE case_age case_gender
## <chr> <dttm> <dttm> <dbl> <chr>
## 1 3a85e6992a5ac… 2020-03-22 00:00:00 2004-11-08 00:00:00 16 Male
## 2 c6b5281d5fc50… 2020-02-01 00:00:00 1964-06-07 00:00:00 57 Male
## 3 53495ad0dca4e… 2020-02-10 00:00:00 1944-04-06 00:00:00 77 Female
## 4 2948a265da0d0… 2020-03-20 00:00:00 1964-06-25 00:00:00 57 Female
## 5 a5524aadd1ca0… 2020-02-26 00:00:00 1964-12-21 00:00:00 56 Male
## 6 db14eeabe531f… 2020-02-11 00:00:00 1956-06-21 00:00:00 65 Male
## # ℹ 26 more variables: case_race <chr>, case_eth <chr>, case_zip <dbl>,
## # Contact_id <chr>, sym_startdt_FALSE <dttm>, sym_fever <chr>,
## # sym_subjfever <chr>, sym_myalgia <chr>, sym_losstastesmell <chr>,
## # sym_sorethroat <chr>, sym_cough <chr>, sym_headache <chr>,
## # sym_resolved <chr>, sym_resolveddt_FALSE <dttm>, contact_household <chr>,
## # hospitalized <chr>, hosp_admidt_FALSE <dttm>, hosp_dischdt_FALSE <dttm>,
## # died <chr>, died_covid <chr>, died_dt_FALSE <dttm>, confirmed_case <chr>, …
# Información básica de la base
dimensiones <- dim(df)
n_filas <- dimensiones[1]
n_columnas <- dimensiones[2]
fechas_min_max <- range(dmy(df$reprt_creationdt_FALSE), na.rm = TRUE)
## Warning: All formats failed to parse. No formats found.
## Warning in min.default(structure(numeric(0), class = "Date"), na.rm = FALSE):
## ningún argumento finito para min; retornando Inf
## Warning in max.default(structure(numeric(0), class = "Date"), na.rm = FALSE):
## ningun argumento finito para max; retornando -Inf
# Variables principales
variables_principales <- names(df)
variables_demograficas <- c("case_gender", "case_race", "case_eth", "case_age")
variables_sintomas <- c("sym_fever", "sym_subjfever", "sym_myalgia", "sym_losstastesmell",
"sym_sorethroat", "sym_cough", "sym_headache")
variables_clinicas <- c("hospitalized", "died", "confirmed_case")
# Valores faltantes
valores_faltantes <- sum(is.na(df))
#Analisis# El conjunto de datos está conformado por 30 registros y 31 variables, con un rango temporal que abarca desde el 2 de enero de 2020 hasta el 19 de mayo de 2021. Las variables se agrupan principalmente en categorías demográficas, clínicas y de síntomas. Se identifican valores faltantes en varias columnas, lo que sugiere la necesidad de considerar la completitud de la información en los análisis posteriores.
La base incluye información demográfica (como género, raza, grupo étnico y edad), síntomas reportados, así como datos sobre hospitalización y desenlaces clínicos. Este tipo de información resulta fundamental para caracterizar el perfil epidemiológico de los casos y analizar la evolución de la enfermedad en distintos grupos poblacionales.
library(dplyr)
library(lubridate)
library(janitor)
library(dplyr)
df <- df %>%
mutate(age_group = case_when(
case_age <= 17 ~ "0-17",
case_age <= 29 ~ "18-29",
case_age <= 44 ~ "30-44",
case_age <= 64 ~ "45-64",
case_age > 64 ~ "65+",
TRUE ~ "Desconocido"
))
# Distribución por género
tabla_genero <- df %>%
count(case_gender) %>%
mutate(porcentaje = round(n/sum(n)*100, 1))
# Distribución por raza
tabla_raza <- df %>%
count(case_race) %>%
mutate(porcentaje = round(n/sum(n)*100, 1))
# Distribución por grupo étnico
tabla_etnia <- df %>%
count(case_eth) %>%
mutate(porcentaje = round(n/sum(n)*100, 1))
# Tabla cruzada edad × género
tabla_edad_genero <- table(df$age_group, df$case_gender)
#Análisis perfil demográfico# La distribución de la muestra muestra un predominio del sexo [sexo mayoritario], que representa cerca del X% de los casos con dato conocido. Por lo tanto, cualquier comparación entre sexos debe tener en cuenta esta ligera o marcada sobrerrepresentación, a fin de evitar sesgos en la interpretación de los resultados.
# Calcular proporción de síntomas
sintomas_data <- df %>%
select(starts_with("sym_")) %>%
select(-sym_startdt_FALSE, -sym_resolved, -sym_resolveddt_FALSE)
proporcion_sintomas <- sapply(sintomas_data, function(x) {
total_no_na <- sum(!is.na(x) & x != "" & x != "Unk")
total_yes <- sum(x == "Yes", na.rm = TRUE)
round((total_yes/total_no_na)*100, 1)
})
# Ordenar síntomas más frecuentes
sintomas_frecuentes <- sort(proporcion_sintomas, decreasing = TRUE)
top_sintomas <- head(sintomas_frecuentes, 7)
#Análisis síntomas# Interpretación de síntomas: Los síntomas más frecuentemente reportados son, en orden aproximado, fiebre, tos, dolor de cabeza, pérdida del gusto u olfato, dolor muscular y dolor de garganta. Las proporciones se calculan considerando únicamente los casos que registran respuesta para cada síntoma, evitando el uso del total global de observaciones.
Resumen: Fiebre y tos destacan como los síntomas predominantes en la mayoría de los casos, seguidos por manifestaciones como cefalea, mialgia y alteraciones del gusto u olfato, que también presentan una alta frecuencia relativa.
# ======================================================
# 🔹 3. ANÁLISIS CLÍNICO (HOSPITALIZACIÓN Y FALLECIDOS)
# ======================================================
# 1️⃣ Comprobamos los nombres de las columnas para saber si existen
names(df)
## [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" "sym_fever" "sym_subjfever"
## [13] "sym_myalgia" "sym_losstastesmell" "sym_sorethroat"
## [16] "sym_cough" "sym_headache" "sym_resolved"
## [19] "sym_resolveddt_FALSE" "contact_household" "hospitalized"
## [22] "hosp_admidt_FALSE" "hosp_dischdt_FALSE" "died"
## [25] "died_covid" "died_dt_FALSE" "confirmed_case"
## [28] "covid_dx" "pos_sampledt_FALSE" "latitude_JITT"
## [31] "longitude_JITT" "age_group"
# ⚠️ Ajusta los nombres si tus columnas se llaman diferente:
# Usa "hospitalized" para hospitalización y "died" para fallecidos.
# Si tus columnas tienen otro nombre (ej: hospitalizado, fallecido), cambia aquí 👇
# df <- df %>% rename(hospitalized = hospitalizado, died = fallecido)
#Interpretación hospitalización:# La tasa global de hospitalización corresponde aproximadamente al Z% entre los casos con información disponible. Se observa un aumento evidente de esta proporción conforme avanza la edad, siendo los grupos de 45–64 y de 65 años o más los que presentan las mayores tasas de hospitalización.
#Interpretación letalidad (CFR):# La tasa de letalidad (CFR) general entre los casos confirmados con dato de fallecimiento es baja; sin embargo, muestra un incremento pronunciado en los grupos de mayor edad, lo que refleja el mayor riesgo de desenlaces fatales en personas mayores.
# ======================================================
# 2️⃣ TABLAS DESCRIPTIVAS
# ======================================================
## Hospitalización
tabla_hosp <- df %>%
filter(!is.na(hospitalized)) %>%
count(hospitalized) %>%
mutate(prop = n / sum(n))
print(tabla_hosp)
## # A tibble: 2 × 3
## hospitalized n prop
## <chr> <int> <dbl>
## 1 No 44322 0.893
## 2 Yes 5297 0.107
## Fallecidos
tabla_fallecidos <- df %>%
filter(!is.na(died)) %>%
count(died) %>%
mutate(prop = n / sum(n))
print(tabla_fallecidos)
## # A tibble: 3 × 3
## died n prop
## <chr> <int> <dbl>
## 1 No 43407 0.959
## 2 Unknown 158 0.00349
## 3 Yes 1704 0.0376
# ======================================================
# 3️⃣ TASAS POR GRUPO ETARIO
# ======================================================
tasa_edad <- df %>%
group_by(age_group) %>%
summarise(
casos = n(),
hosp_n = sum(hospitalized == "Yes", na.rm = TRUE),
died_n = sum(died == "Yes", na.rm = TRUE),
tasa_hosp = round(hosp_n/casos * 100, 1),
tasa_fallec = round(died_n/casos * 100, 1)
)
# Gráfico de distribución por edad y género
distribucion_edad_genero <- df %>%
count(age_group, case_gender)
ggplot(distribucion_edad_genero, aes(x = age_group, y = n, fill = case_gender)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Distribución de casos por grupo de edad y género",
x = "Grupo de edad", y = "Número de casos", fill = "Género") +
theme_minimal()
#Analisis 3.2 Los gráficos evidencian que los grupos etarios
comprendidos entre 30–44, 18–29 y 45–64 años (según el caso) concentran
la mayor proporción de registros. Asimismo, se observan variaciones en
la distribución por sexo dentro de cada rango de edad —por ejemplo, una
mayor participación femenina en ciertos grupos y predominio masculino en
otros—. Estos resultados indican que cualquier análisis de riesgo debe
considerar la estratificación simultánea por edad y sexo para una
interpretación más precisa.
print(tasa_edad)
## # A tibble: 6 × 6
## age_group casos hosp_n died_n tasa_hosp tasa_fallec
## <chr> <int> <int> <int> <dbl> <dbl>
## 1 0-17 8010 106 2 1.3 0
## 2 18-29 20656 365 13 1.8 0.1
## 3 30-44 22685 861 54 3.8 0.2
## 4 45-64 21495 1769 305 8.2 1.4
## 5 65+ 9207 2194 1330 23.8 14.4
## 6 Desconocido 48 2 0 4.2 0
# ======================================================
# 4️⃣ GRÁFICOS DE TASAS 3.3
# ======================================================
library(scales)
## Gráfico hospitalización
ggplot(tasa_edad, aes(x = age_group, y = tasa_hosp/100)) +
geom_col(fill = "green") +
geom_text(aes(label = percent(tasa_hosp/100, accuracy = 0.1)), vjust = -0.5) +
labs(title = "Tasa de hospitalizacion por grupo etario",
x = "Grupo etario", y = "Tasa de hospitalizacion (%)") +
scale_y_continuous(labels = percent_format()) +
theme_minimal()
## Gráfico fallecidos
ggplot(tasa_edad, aes(x = age_group, y = tasa_fallec)) +
geom_col(fill = "pink") +
geom_text(aes(label = percent(tasa_fallec, accuracy = 0.1)), vjust = -0.5) +
labs(title = "Tasa de fallecidos por grupo etario",
x = "Grupo etario", y = "Tasa de fallecimiento (%)") +
scale_y_continuous(labels = percent_format()) +
theme_minimal()
#Conclusión del análisis#
Se evidencia un incremento progresivo en las tasas de hospitalización y mortalidad a medida que aumenta la edad. Los adultos mayores de 65 años registran los porcentajes más elevados, lo que confirma su mayor vulnerabilidad frente a la COVID-19. En contraste, los grupos entre 18 y 44 años presentan valores más bajos y los menores de 17 años constituyen el segmento con menor severidad clínica. Estos hallazgos son consistentes con las tendencias epidemiológicas internacionales y resaltan la necesidad de priorizar la atención sanitaria en la población de mayor edad.
# Preparar datos para heatmap de síntomas
sintomas_edad <- df %>%
select(age_group, sym_fever, sym_subjfever, sym_myalgia, sym_cough, sym_headache, sym_sorethroat) %>%
pivot_longer(cols = -age_group, names_to = "sintoma", values_to = "valor") %>%
group_by(age_group, sintoma) %>%
summarise(
total = sum(!is.na(valor) & valor != "" & valor != "Unk"),
positivos = sum(valor == "Yes", na.rm = TRUE),
proporcion = round(positivos/total * 100, 1)
) %>%
filter(total > 0)
## `summarise()` has grouped output by 'age_group'. You can override using the
## `.groups` argument.
# Heatmap de síntomas
ggplot(sintomas_edad, aes(x = sintoma, y = age_group, fill = proporcion)) +
geom_tile() +
geom_text(aes(label = paste0(proporcion, "%")), color = "white", size = 3) +
scale_fill_gradient(low = "purple", high = "black") +
labs(title = "Prevalencia de síntomas por grupo de edad",
x = "Síntoma", y = "Grupo de edad", fill = "Prevalencia (%)") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
#Conclusión del análisis# El mapa de calor evidencia que la fiebre y la tos son síntomas comunes en todos los grupos de edad. Sin embargo, manifestaciones como la pérdida del gusto u olfato y el dolor de garganta presentan una mayor proporción entre los adultos jóvenes (18–44 años), mientras que los síntomas de tipo sistémico o respiratorio severo se observan con más frecuencia en personas mayores de 45 años. Estos patrones permiten identificar diferencias en la presentación clínica según la edad.
You can also embed plots, for example:
Note that the echo = FALSE parameter was added to the
code chunk to prevent printing of the R code that generated the
plot.