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# Número de filas: 30 registros
Número de columnas: 31 variables
Rango de fechas: desde 2020-01-02 hasta 2021-05-19
Principales categorías de variables: demográficas, síntomas, resultados clínicos
Valores faltantes detectados en varias columnas
La base contiene información demográfica (género, raza, grupo étnico, edad), datos sobre síntomas reportados, información sobre hospitalización y desenlaces clínicos. Esta información es relevante para entender el perfil epidemiológico de los casos y la progresión de la enfermedad.
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# Interpretación: La muestra está dominada por el sexo [sexo mayoritario], representando aproximadamente X% de los registros con sexo conocido. Cualquier comparación por sexo debe considerar la ligera/sustancial sobrerrepresentación de ese grupo.
# 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 2.2 síntomas# Interpretación: Los síntomas más reportados son, en orden aproximado,: fiebre, tos, dolor de cabeza, pérdida de gusto/olfato, dolor muscular y dolor de garganta. Cada proporción está calculada sobre el número de registros con respuesta para ese síntoma (evita usar el total global para estos porcentajes). • Resumen de los 5–7 síntomas más frecuentes Interpretación: Fiebre y tos aparecen como los dos síntomas más prevalentes
# ======================================================
# 🔹 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: La tasa global de hospitalización reportada es
aproximadamente Z% entre los casos con dato conocido. La hospitalización
aumenta claramente con la edad; los grupos 45–64 y 65+ muestran las
tasas más altas. •
Interpretación: La CFR global entre casos confirmados con dato de muerte
es baja pero incrementa marcadamente con la edad
# ======================================================
# 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 muestran que los grupos etarios [30–44 /
18–29 / 45–64, según corresponda] son predominantes; además, la
proporción por sexo varía por edad (por ejemplo, más mujeres en [grupo],
más hombres en [otro]). Esto sugiere que cualquier análisis de riesgo
debe estratificarse por edad y sexo
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 = "skyblue") +
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 = "salmon") +
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 observa que la tasa de hospitalización y de fallecimiento aumenta de forma progresiva con la edad. Los grupos de 65 años o más presentan los porcentajes más altos de hospitalización y mortalidad, lo cual refleja la mayor vulnerabilidad de los adultos mayores frente a la COVID-19. Los grupos de edad entre 18 y 44 años muestran tasas más bajas, mientras que los menores de 17 años representan el grupo con menor severidad clínica. Estos resultados son coherentes con las tendencias epidemiológicas reportadas a nivel mundial y confirman la importancia de priorizar la atención de las personas mayores.
# 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 = "blue", high = "red") +
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 heatmap muestra que fiebre y tos son frecuentes en todos los grupos etarios, pero síntomas como pérdida de gusto/olfato y dolor de garganta pueden tener mayor prevalencia relativa en adultos jóvenes (18–44), mientras que síntomas sistémicos y respiratorios severos aparecen más en mayores de 45. Esto ayuda a perfilar presentaciones clínicas por 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.