# Limpiar el espacio de trabajo
rm(list = ls())
# Cargar librerías necesarias
library(rio)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(stringr)
# Importar datasets
positivos_covid <- import("positivos_covid.csv")
fallecidos_covid <- import("fallecidos_covid.csv")
EleccionesPresidenciales <- import("EleccionesPresidenciales.csv")
## Warning in (function (input = "", file = NULL, text = NULL, cmd = NULL, :
## Detected 15 column names but the data has 16 columns (i.e. invalid file). Added
## an extra default column name for the first column which is guessed to be row
## names or an index. Use setnames() afterwards if this guess is not correct, or
## fix the file write command that created the file to create a valid file.
reporte <- import("reporte.xlsx")
## New names:
## • `Total` -> `Total...5`
## • `Total` -> `Total...8`
## • `Total` -> `Total...11`
## • `Total` -> `Total...14`
reporte_hogar <- import("reporte_hogar.xlsx")
## New names:
## • `Total` -> `Total...5`
## • `Total` -> `Total...15`
# Función para limpiar datasets de manera robusta
limpiar_dataset <- function(df) {
df %>%
mutate(across(where(is.character), ~ str_trim(.))) %>% # Eliminar espacios
mutate(across(where(is.character), ~ na_if(., ""))) %>% # Vacíos a NA
filter(if_any(everything(), ~ !is.na(.))) %>% # Quitar filas totalmente vacías
filter(complete.cases(.)) # Quitar filas con NA
}
# Filtrar y limpiar datos de COVID-19 (solo año 2020)
filtro_covid_2020 <- tryCatch({
positivos_covid %>%
mutate(Año = substr(as.character(FECHA_RESULTADO), 1, 4)) %>%
filter(Año == "2020") %>%
limpiar_dataset()
}, error = function(e) {
cat("❌ Error al procesar positivos COVID-2020:", conditionMessage(e), "\n")
NULL
})
filtro_fallecidos_2020 <- tryCatch({
fallecidos_covid %>%
mutate(Año = substr(as.character(FECHA_FALLECIMIENTO), 1, 4)) %>%
filter(Año == "2020") %>%
limpiar_dataset()
}, error = function(e) {
cat("❌ Error al procesar fallecidos COVID-2020:", conditionMessage(e), "\n")
NULL
})
# Validar que los datos filtrados existen
if (is.null(filtro_covid_2020) || is.null(filtro_fallecidos_2020)) {
stop("❌ No se pudieron crear los datasets filtrados. Revisa los errores.")
}
# Diagnóstico: mostrar nombres de columnas y primeras filas
cat("📋 Columnas de filtro_covid_2020:\n")
## 📋 Columnas de filtro_covid_2020:
print(colnames(filtro_covid_2020))
## [1] "FECHA_CORTE" "DEPARTAMENTO" "PROVINCIA" "DISTRITO"
## [5] "METODODX" "EDAD" "SEXO" "FECHA_RESULTADO"
## [9] "UBIGEO" "id_persona" "Año"
cat("\n📋 Columnas de filtro_fallecidos_2020:\n")
##
## 📋 Columnas de filtro_fallecidos_2020:
print(colnames(filtro_fallecidos_2020))
## [1] "FECHA_CORTE" "FECHA_FALLECIMIENTO" "EDAD_DECLARADA"
## [4] "SEXO" "CLASIFICACION_DEF" "DEPARTAMENTO"
## [7] "PROVINCIA" "DISTRITO" "UBIGEO"
## [10] "UUID" "Año"
cat("\n🔍 Primeras filas de filtro_covid_2020:\n")
##
## 🔍 Primeras filas de filtro_covid_2020:
print(head(filtro_covid_2020))
## FECHA_CORTE DEPARTAMENTO PROVINCIA DISTRITO METODODX EDAD SEXO
## 1 20241203 TUMBES ZARUMILLA AGUAS VERDES AG 52 MASCULINO
## 2 20241203 TUMBES ZARUMILLA ZARUMILLA AG 42 FEMENINO
## 3 20241203 SAN MARTIN SAN MARTIN TARAPOTO AG 48 MASCULINO
## 4 20241203 PIURA SULLANA IGNACIO ESCUDERO AG 43 FEMENINO
## 5 20241203 PIURA SULLANA IGNACIO ESCUDERO AG 42 FEMENINO
## 6 20241203 SAN MARTIN SAN MARTIN TARAPOTO AG 83 FEMENINO
## FECHA_RESULTADO UBIGEO id_persona Año
## 1 20201229 240302 233066 2020
## 2 20201229 240301 307679 2020
## 3 20201230 220901 301845 2020
## 4 20201216 200603 1063754 2020
## 5 20201230 200603 909317 2020
## 6 20201230 220901 524671 2020
cat("\n🔍 Primeras filas de filtro_fallecidos_2020:\n")
##
## 🔍 Primeras filas de filtro_fallecidos_2020:
print(head(filtro_fallecidos_2020))
## FECHA_CORTE FECHA_FALLECIMIENTO EDAD_DECLARADA SEXO
## 1 20240317 20200711 64 MASCULINO
## 2 20240317 20200505 50 MASCULINO
## 3 20240317 20200803 92 FEMENINO
## 4 20240317 20200622 56 MASCULINO
## 5 20240317 20200626 85 MASCULINO
## 6 20240317 20200829 72 MASCULINO
## CLASIFICACION_DEF DEPARTAMENTO PROVINCIA
## 1 Criterio SINADEF LIMA LIMA
## 2 Criterio investigación Epidemiológica LORETO MARISCAL RAMON CASTILLA
## 3 Criterio SINADEF MADRE DE DIOS TAMBOPATA
## 4 Criterio investigación Epidemiológica SAN MARTIN BELLAVISTA
## 5 Criterio clínico SAN MARTIN SAN MARTIN
## 6 Criterio radiológico PIURA MORROPON
## DISTRITO UBIGEO UUID Año
## 1 LOS OLIVOS 150117 846252 2020
## 2 YAVARI 160403 278625 2020
## 3 INAMBARI 170102 846841 2020
## 4 BELLAVISTA 220201 204560 2020
## 5 TARAPOTO 220901 297348 2020
## 6 CHULUCANAS 200401 1016628 2020
# Merge por UBIGEO si es posible, si no, por DEPARTAMENTO, PROVINCIA, DISTRITO
merge_covid_fallecidos <- tryCatch({
inner_join(filtro_covid_2020, filtro_fallecidos_2020, by = "UBIGEO")
}, error = function(e) {
cat("⚠️ Merge por UBIGEO falló:", conditionMessage(e), "\n")
cat("🔁 Probando merge por DEPARTAMENTO, PROVINCIA, DISTRITO...\n")
inner_join(filtro_covid_2020, filtro_fallecidos_2020,
by = c("DEPARTAMENTO", "PROVINCIA", "DISTRITO"))
})
## Warning in inner_join(filtro_covid_2020, filtro_fallecidos_2020, by = "UBIGEO"): Detected an unexpected many-to-many relationship between `x` and `y`.
## ℹ Row 1 of `x` matches multiple rows in `y`.
## ℹ Row 552 of `y` matches multiple rows in `x`.
## ℹ If a many-to-many relationship is expected, set `relationship =
## "many-to-many"` to silence this warning.
# Mostrar columnas del merge
cat("\n📋 Columnas del merge:\n")
##
## 📋 Columnas del merge:
print(colnames(merge_covid_fallecidos))
## [1] "FECHA_CORTE.x" "DEPARTAMENTO.x" "PROVINCIA.x"
## [4] "DISTRITO.x" "METODODX" "EDAD"
## [7] "SEXO.x" "FECHA_RESULTADO" "UBIGEO"
## [10] "id_persona" "Año.x" "FECHA_CORTE.y"
## [13] "FECHA_FALLECIMIENTO" "EDAD_DECLARADA" "SEXO.y"
## [16] "CLASIFICACION_DEF" "DEPARTAMENTO.y" "PROVINCIA.y"
## [19] "DISTRITO.y" "UUID" "Año.y"
# Crear resumen de casos y fallecidos
resumen <- tryCatch({
merge_covid_fallecidos %>%
group_by(UBIGEO) %>%
summarise(
Casos = n_distinct(id_persona),
Fallecidos = n(),
.groups = "drop"
)
}, error = function(e) {
cat("⚠️ Error al agrupar por UBIGEO:", conditionMessage(e), "\n")
cat("🔁 Probando agrupar por DEPARTAMENTO, PROVINCIA, DISTRITO...\n")
merge_covid_fallecidos %>%
group_by(DEPARTAMENTO, PROVINCIA, DISTRITO) %>%
summarise(
Casos = n_distinct(id_persona),
Fallecidos = n(),
.groups = "drop"
)
})
# Mostrar y exportar resumen
cat("\n📊 Resumen de casos y fallecidos:\n")
##
## 📊 Resumen de casos y fallecidos:
print(resumen)
## # A tibble: 35 × 3
## UBIGEO Casos Fallecidos
## <int> <int> <int>
## 1 21101 1 62
## 2 21801 2 2732
## 3 21809 1 316
## 4 30201 1 46
## 5 40112 1 473
## 6 60301 8 280
## 7 60312 1 1
## 8 70101 3 9705
## 9 80101 1 288
## 10 100101 1 297
## # ℹ 25 more rows
# Guardar en archivo
export(resumen, "resumen_covid_fallecidos.csv")
cat("\n✅ Resumen guardado como 'resumen_covid_fallecidos.csv'\n")
##
## ✅ Resumen guardado como 'resumen_covid_fallecidos.csv'
EleccionesPresidenciales[is.na(EleccionesPresidenciales)] <- 0
str(reporte)
## 'data.frame': 25 obs. of 14 variables:
## $ Código : num 1 2 3 4 5 6 7 8 9 10 ...
## $ Departamento : chr "Departamento: Amazonas" "Departamento: Áncash" "Departamento: Apurímac" "Departamento: Arequipa" ...
## $ No usa electricidad : chr "106 081" "306 824" "124 688" "412 644" ...
## $ Sí usa electricidad : chr "1 283" "6 837" "1 360" "12 878" ...
## $ Total...5 : chr "107 364" "313 661" "126 048" "425 522" ...
## $ No usa gas (balón GLP): chr "54 413" "125 218" "69 604" "42 709" ...
## $ Sí usa gas (balón GLP): chr "52 951" "188 443" "56 444" "382 813" ...
## $ Total...8 : chr "107 364" "313 661" "126 048" "425 522" ...
## $ No usa carbón : chr "106 421" "311 253" "125 577" "423 733" ...
## $ Sí usa carbón : chr "943.0" "2 408" "471.0" "1 789" ...
## $ Total...11 : chr "107 364" "313 661" "126 048" "425 522" ...
## $ No usa leña : chr "32 444" "164 374" "36 851" "367 407" ...
## $ Sí usa leña : chr "74 920" "149 287" "89 197" "58 115" ...
## $ Total...14 : chr "107 364" "313 661" "126 048" "425 522" ...
str(reporte_hogar)
## 'data.frame': 196 obs. of 15 variables:
## $ Código : num 101 102 103 104 105 106 107 201 202 203 ...
## $ Provincia : chr "Amazonas, provincia: Chachapoyas" "Amazonas, provincia: Bagua" "Amazonas, provincia: Bongara" "Amazonas, provincia: Condorcanqui" ...
## $ Urbano encuesta: chr "9 640" "10 869" "3 674" "945.0" ...
## $ Rural encuesta : chr "5 697" "9 605" "4 139" "8 922" ...
## $ Total...5 : chr "15 337" "20 474" "7 813" "9 867" ...
## $ Hogar 1 : chr "13 999" "19 520" "7 308" "9 716" ...
## $ Hogar 2 : chr "1 032" "666.0" "380.0" "107.0" ...
## $ Hogar 3 : chr "210.0" "165.0" "87.0" "32.0" ...
## $ Hogar 4 : chr "61.0" "71.0" "24.0" "6.0" ...
## $ Hogar 5 : chr "27.0" "33.0" "8.0" "2.0" ...
## $ Hogar 6 : chr "7.0" "13.0" "5.0" "2.0" ...
## $ Hogar 7 : num 1 5 1 2 0 1 1 7 0 0 ...
## $ Hogar 8 : num 0 1 0 0 0 0 0 1 0 0 ...
## $ Hogar 9 : num 0 0 0 0 0 0 0 0 0 0 ...
## $ Total...15 : chr "15 337" "20 474" "7 813" "9 867" ...
str(EleccionesPresidenciales)
## 'data.frame': 86488 obs. of 16 variables:
## $ V1 : int 10101 10101 10101 10101 10101 10201 10101 10107 10112 10112 ...
## $ UBIGEO : chr "AMAZONAS" "AMAZONAS" "AMAZONAS" "AMAZONAS" ...
## $ DEPARTAMENTO : chr "CHACHAPOYAS" "CHACHAPOYAS" "CHACHAPOYAS" "CHACHAPOYAS" ...
## $ PROVINCIA : chr "CHACHAPOYAS" "CHACHAPOYAS" "CHACHAPOYAS" "CHACHAPOYAS" ...
## $ DISTRITO : chr "PRESIDENCIAL" "PRESIDENCIAL" "PRESIDENCIAL" "PRESIDENCIAL" ...
## $ TIPO_ELECCION : int 13 26 30 36 40 148 59 90 117 119 ...
## $ MESA_DE_VOTACION : chr "CONTABILIZADA" "CONTABILIZADA" "CONTABILIZADA" "CONTABILIZADA" ...
## $ DESCRIP_ESTADO_ACTA: num 0 0 0 0 0 0 0 0 0 0 ...
## $ TIPO_OBSERVACION : num 220 144 129 202 228 171 220 138 178 185 ...
## $ N_CVAS : int 300 300 300 252 300 300 300 213 240 240 ...
## $ N_ELEC_HABIL : num 115 71 71 66 125 112 90 93 113 116 ...
## $ VOTOS_P1 : num 87 58 50 105 87 51 101 34 54 58 ...
## $ VOTOS_P2 : num 0 0 0 5 0 4 7 3 3 3 ...
## $ VOTOS_VB : num 18 15 8 26 16 4 22 8 8 8 ...
## $ VOTOS_VN : num 0 0 0 0 0 0 0 0 0 0 ...
## $ VOTOS_VI : num 0 0 0 0 0 0 0 0 0 0 ...
colnames(resumen)
## [1] "UBIGEO" "Casos" "Fallecidos"
str(reporte_hogar)
## 'data.frame': 196 obs. of 15 variables:
## $ Código : num 101 102 103 104 105 106 107 201 202 203 ...
## $ Provincia : chr "Amazonas, provincia: Chachapoyas" "Amazonas, provincia: Bagua" "Amazonas, provincia: Bongara" "Amazonas, provincia: Condorcanqui" ...
## $ Urbano encuesta: chr "9 640" "10 869" "3 674" "945.0" ...
## $ Rural encuesta : chr "5 697" "9 605" "4 139" "8 922" ...
## $ Total...5 : chr "15 337" "20 474" "7 813" "9 867" ...
## $ Hogar 1 : chr "13 999" "19 520" "7 308" "9 716" ...
## $ Hogar 2 : chr "1 032" "666.0" "380.0" "107.0" ...
## $ Hogar 3 : chr "210.0" "165.0" "87.0" "32.0" ...
## $ Hogar 4 : chr "61.0" "71.0" "24.0" "6.0" ...
## $ Hogar 5 : chr "27.0" "33.0" "8.0" "2.0" ...
## $ Hogar 6 : chr "7.0" "13.0" "5.0" "2.0" ...
## $ Hogar 7 : num 1 5 1 2 0 1 1 7 0 0 ...
## $ Hogar 8 : num 0 1 0 0 0 0 0 1 0 0 ...
## $ Hogar 9 : num 0 0 0 0 0 0 0 0 0 0 ...
## $ Total...15 : chr "15 337" "20 474" "7 813" "9 867" ...
str(EleccionesPresidenciales)
## 'data.frame': 86488 obs. of 16 variables:
## $ V1 : int 10101 10101 10101 10101 10101 10201 10101 10107 10112 10112 ...
## $ UBIGEO : chr "AMAZONAS" "AMAZONAS" "AMAZONAS" "AMAZONAS" ...
## $ DEPARTAMENTO : chr "CHACHAPOYAS" "CHACHAPOYAS" "CHACHAPOYAS" "CHACHAPOYAS" ...
## $ PROVINCIA : chr "CHACHAPOYAS" "CHACHAPOYAS" "CHACHAPOYAS" "CHACHAPOYAS" ...
## $ DISTRITO : chr "PRESIDENCIAL" "PRESIDENCIAL" "PRESIDENCIAL" "PRESIDENCIAL" ...
## $ TIPO_ELECCION : int 13 26 30 36 40 148 59 90 117 119 ...
## $ MESA_DE_VOTACION : chr "CONTABILIZADA" "CONTABILIZADA" "CONTABILIZADA" "CONTABILIZADA" ...
## $ DESCRIP_ESTADO_ACTA: num 0 0 0 0 0 0 0 0 0 0 ...
## $ TIPO_OBSERVACION : num 220 144 129 202 228 171 220 138 178 185 ...
## $ N_CVAS : int 300 300 300 252 300 300 300 213 240 240 ...
## $ N_ELEC_HABIL : num 115 71 71 66 125 112 90 93 113 116 ...
## $ VOTOS_P1 : num 87 58 50 105 87 51 101 34 54 58 ...
## $ VOTOS_P2 : num 0 0 0 5 0 4 7 3 3 3 ...
## $ VOTOS_VB : num 18 15 8 26 16 4 22 8 8 8 ...
## $ VOTOS_VN : num 0 0 0 0 0 0 0 0 0 0 ...
## $ VOTOS_VI : num 0 0 0 0 0 0 0 0 0 0 ...
str((fallecidos_covid))
## 'data.frame': 220918 obs. of 10 variables:
## $ FECHA_CORTE : int 20240317 20240317 20240317 20240317 20240317 20240317 20240317 20240317 20240317 20240317 ...
## $ FECHA_FALLECIMIENTO: int 20220219 20210529 20210623 20210824 20210627 20210423 20210401 20220914 20210409 20211030 ...
## $ EDAD_DECLARADA : int 63 74 72 85 46 58 73 92 66 64 ...
## $ SEXO : chr "MASCULINO" "MASCULINO" "FEMENINO" "MASCULINO" ...
## $ CLASIFICACION_DEF : chr "Criterio virológico" "Criterio virológico" "Criterio SINADEF" "Criterio investigación Epidemiológica" ...
## $ DEPARTAMENTO : chr "TUMBES" "TUMBES" "TACNA" "TUMBES" ...
## $ PROVINCIA : chr "TUMBES" "TUMBES" "TACNA" "TUMBES" ...
## $ DISTRITO : chr "TUMBES" "TUMBES" "ALTO DE LA ALIANZA" "TUMBES" ...
## $ UBIGEO : int 240101 240101 230102 240101 230102 240301 240301 240102 200104 210901 ...
## $ UUID : int 203506 203532 203584 212541 203665 221184 221211 229901 846032 846152 ...
# 1. Limpiar y calcular % hogares sin agua
library(dplyr)
reporte_hogar_clean <- reporte_hogar %>%
mutate(across(starts_with("Hogar"), ~as.numeric(gsub(",", "", .)))) %>%
rowwise() %>%
mutate(
total_hogares = sum(c_across(`Hogar 1`:`Hogar 9`), na.rm = TRUE),
hogares_sin_agua = sum(c_across(`Hogar 2`:`Hogar 9`), na.rm = TRUE),
pct_hogares_sin_agua = hogares_sin_agua / total_hogares * 100
) %>%
ungroup() %>%
select(Código, Provincia, pct_hogares_sin_agua)
## Warning: There were 6 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `across(starts_with("Hogar"), ~as.numeric(gsub(",", "", .)))`.
## Caused by warning:
## ! NAs introduced by coercion
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 5 remaining warnings.
# 2. Agrupar fallecidos por provincia
fallecidos_por_provincia <- fallecidos_covid %>%
group_by(DEPARTAMENTO, PROVINCIA) %>%
summarise(fallecidos_covid = n(), .groups = 'drop')
# 3. Calcular razón de voto por provincia (P1 / P2)
votos_por_provincia <- EleccionesPresidenciales %>%
group_by(DEPARTAMENTO, PROVINCIA) %>%
summarise(
votos_p1 = sum(VOTOS_P1, na.rm = TRUE),
votos_p2 = sum(VOTOS_P2, na.rm = TRUE),
razon_voto = ifelse(votos_p2 == 0, NA, votos_p1 / votos_p2),
.groups = 'drop'
)
# 4. Extraer PROVINCIA y DEPARTAMENTO desde `Provincia` de reporte_hogar
reporte_hogar_clean <- reporte_hogar_clean %>%
mutate(
PROVINCIA = sub(".*provincia:\\s*", "", Provincia),
DEPARTAMENTO = sub(",.*", "", Provincia)
)
# 5. Unir los tres datasets
dataset_final <- reporte_hogar_clean %>%
left_join(fallecidos_por_provincia, by = c("DEPARTAMENTO", "PROVINCIA")) %>%
left_join(votos_por_provincia, by = c("DEPARTAMENTO", "PROVINCIA")) %>%
select(DEPARTAMENTO, PROVINCIA, pct_hogares_sin_agua, fallecidos_covid, razon_voto)