Capítulo 3 Mapas

Seguramente has visto mapas temáticos en las publicaciones del INEI, como el Mapa de Pobreza Monetaria 2018 (https://www.inei.gob.pe/media/MenuRecursivo/boletines/mapa-de-pobreza-25022020_ponencia.pdf) u otros de diversas temáticas en páginas de otras instituciones. En esta sección te mostraré como elaborarlos tú mismo.

Partamos del siguiente mapa, cuya información se puede obtener de https://www.inei.gob.pe/media/MenuRecursivo/publicaciones_digitales/Est/Lib1718/Anexos.xlsx

Una vez trabajado el archivo 1 lo podemos importar a R.

library(readxl)
pobr <- read_excel("AnexoPobreza.xlsx")
library(dplyr)
glimpse(pobr)
## Rows: 1,874
## Columns: 9
## $ Ubigeo                            <chr> "010101", "010102", "010103", "01010…
## $ Departamento                      <chr> "AMAZONAS", "AMAZONAS", "AMAZONAS", …
## $ Provincia                         <chr> "CHACHAPOYAS", "CHACHAPOYAS", "CHACH…
## $ Distrito                          <chr> "CHACHAPOYAS", "ASUNCIÓN", "BALSAS",…
## $ Población_proyectada_2020         <dbl> 39051, 278, 1180, 702, 589, 1933, 53…
## $ Intervalo_de_confianza_Inferior   <dbl> 5.773728, 25.308002, 36.793306, 27.9…
## $ Intervalo_de_confianza_Superior   <dbl> 12.29552, 47.73190, 54.67262, 50.392…
## $ Grupos_robustos                   <dbl> 19, 10, 8, 10, 6, 7, 8, 11, 8, 14, 9…
## $ Ubicación_pobreza_monetaria_total <dbl> 1747, 852, 506, 754, 261, 315, 581, …

El dato del UBIGEO será crucial para combinar esta información estadística con la información georeferenciada.

Crearemos una columna con la agrupación que queremos representar en el mapa. En este caso, utilizaremos la información del Cuadro 4 (página 40) del documento https://www.inei.gob.pe/media/MenuRecursivo/publicaciones_digitales/Est/Lib1718/Libro.pdf para agrupar los grupos robustos por el rango de pobreza monetaria total.

pobr$RangoPobreza <- 
  case_when(pobr$Grupos_robustos>=15 & pobr$Grupos_robustos<=28 ~ "Menor a 20%",
            pobr$Grupos_robustos>=10 & pobr$Grupos_robustos<=14 ~ "De 20% a 39.9%",
            pobr$Grupos_robustos>=6 & pobr$Grupos_robustos<=9 ~ "De 40% a 59.9%",
            pobr$Grupos_robustos>=1 & pobr$Grupos_robustos<=5 ~ "De 60% a más")
pobr$RangoPobreza <- ordered(pobr$RangoPobreza,
                             levels=c("Menor a 20%",
                                      "De 20% a 39.9%",
                                      "De 40% a 59.9%",
                                      "De 60% a más"))

table(pobr$RangoPobreza, useNA="alw")
## 
##    Menor a 20% De 20% a 39.9% De 40% a 59.9%   De 60% a más           <NA> 
##            476            662            594            142              0

La información georeferenciada del Perú a nivel de región, departamento, provincia y distrito la podemos obtener del paquete mapsPERU.

library(mapsPERU)
## For examples, please visit https://github.com/musajajorge/mapsPERU
## 
df <- map_DIST

Importamos el paquete sf para poder visualizar correctamente los multipolígonos.

library(sf)

glimpse(df)
## Rows: 1,891
## Columns: 13
## $ COD_REGION           <chr> "010000", "010000", "010000", "010000", "010000",…
## $ COD_DEPARTAMENTO     <chr> "010000", "010000", "010000", "010000", "010000",…
## $ COD_PROVINCIA        <chr> "010100", "010100", "010100", "010100", "010100",…
## $ COD_DISTRITO         <chr> "010101", "010102", "010103", "010104", "010105",…
## $ REGION               <chr> "Amazonas", "Amazonas", "Amazonas", "Amazonas", "…
## $ DEPARTAMENTO         <chr> "Amazonas", "Amazonas", "Amazonas", "Amazonas", "…
## $ PROVINCIA            <chr> "Chachapoyas", "Chachapoyas", "Chachapoyas", "Cha…
## $ DISTRITO             <chr> "Chachapoyas", "Asunción", "Balsas", "Cheto", "Ch…
## $ NOMBRE_CAPITAL_LEGAL <chr> "CHACHAPOYAS", "ASUNCION", "BALSAS", "CHETO", "CH…
## $ REGION_NATURAL       <chr> "Sierra", "Sierra", "Selva", "Sierra", "Sierra", …
## $ coords_x             <dbl> -77.8566, -77.7432, -77.9491, -77.6773, -77.7558,…
## $ coords_y             <dbl> -6.2477, -5.9962, -6.8078, -6.2979, -6.0784, -6.9…
## $ geometry             <MULTIPOLYGON [°]> MULTIPOLYGON (((-77.8858 -6..., MULT…

Ahora combinaremos la información de pobreza monetaria con el data.frame de información georeferenciada. Para ello, usaremos como campo común el COD_DISTRITO o UBIGEO.

df <- inner_join(df, pobr, by=c("COD_DISTRITO"="Ubigeo"))

Para no hacer tan cargado el mapa, filtraremos solo una región.

df <- df |>
  filter(REGION=="Puno")

Ahora elaboramos el mapa temático con el paquete ggplot2. Nótese que estamos usando geom_sf y para ello fue necesario importar el paquete sf.

library(sf)
library(ggplot2)
ggplot(df, aes(geometry=geometry)) +
  geom_sf(aes(fill=RangoPobreza)) 

Por supuesto, podemos personalizar aún más el mapa.

colores <- c('#feebe2','#fbb4b9','#f768a1','#ae017e')

library(sf)
library(ggplot2)
ggplot(df, aes(geometry=geometry)) +
  scale_fill_manual(values=colores) +
  geom_sf(aes(fill=RangoPobreza)) +
  labs(fill = "Rango de pobreza monetaria 2018",
       title = "Mapa de Puno")

3.1 Añadir puntos específicos

Si conocemos puntos GPS específicos, también los podemos plasmar en un mapa. Por ejemplo, importemos el listado de establecimientos de salud, disponible en https://www.datosabiertos.gob.pe/dataset/establecimientos-de-salud

library(readr)

hh <- read_delim("TB_EESS.csv", delim = ";", 
    escape_double = FALSE, trim_ws = TRUE)

hh
## # A tibble: 32,194 × 10
##    id_eess codigo_renaes categoria nombre        diresa red   direccion longitud
##      <dbl>         <dbl> <chr>     <chr>         <chr>  <chr> <chr>        <dbl>
##  1       1             1 II-2      "HOSPITAL IQ… LORETO NO P… CALLE CO…    -73.3
##  2       2             2 SD        "CENTRO REHA… LORETO NO P… CALLE 3 …     NA  
##  3       3             3 III-1     "HOSPITAL RE… LORETO NO P… AVENIDA …    -73.3
##  4       4             4 I-3       "C.S. I-3 SA… LORETO MAYN… OTROS CA…    -73.7
##  5       5             5 I-1       "SAMITO"      LORETO MAYN… OTROS CA…    -73.6
##  6       6             6 I-1       "P.S. 1 DIAM… LORETO MAYN… OTROS CA…    -73.8
##  7       7             7 I-4       "I-4 CENTRO … LORETO MAYN… OTROS CA…    -73.3
##  8       8             8 I-3       "C.S. I-3 TU… LORETO MAYN… OTROS SE…     NA  
##  9       9             9 I-3       "SAN ANTONIO… LORETO MAYN… OTROS AC…    -73.3
## 10      10            10 I-2       "1RO. DE ENE… LORETO MAYN… PROLONGA…    -73.3
## # ℹ 32,184 more rows
## # ℹ 2 more variables: latitud <dbl>, id_ubigeo <dbl>

Particularmemte, estoy interesado en los hospitales de Lima Metropolitana que no pertenecen a Lima Centro.

library(dplyr)

hh <- hh[grep("HOSPITAL", hh$nombre),] |>
  filter(diresa=="LIMA DIRIS ESTE" | diresa=="LIMA DIRIS NORTE" |
           diresa=="LIMA DIRIS SUR")

Nos quedaremos solo con aquellos con información en latitud y longitud

hh <- hh |>
  filter(is.na(latitud)==F & is.na(longitud)==F)
library(sf)

hh <- hh %>% 
  st_as_sf(coords = c("longitud", "latitud"), remove=F)

hh
## Simple feature collection with 21 features and 10 fields
## Geometry type: POINT
## Dimension:     XY
## Bounding box:  xmin: -77.07934 ymin: -12.2326 xmax: -76.69349 ymax: -11.86318
## CRS:           NA
## # A tibble: 21 × 11
##    id_eess codigo_renaes categoria nombre        diresa red   direccion longitud
##      <dbl>         <dbl> <chr>     <chr>         <chr>  <chr> <chr>        <dbl>
##  1    5880          5883 II-1      HOSPITAL DE … LIMA … NO P… AVENIDA …    -76.8
##  2    5942          5945 II-1      HOSPITAL VIT… LIMA … NO P… AVENIDA …    -76.9
##  3    5943          5946 III-1     HOSPITAL NAC… LIMA … NO P… AVENIDA …    -77.0
##  4    5944          5947 II-2      HOSPITAL DE … LIMA … NO P… JIRÓN JR…    -76.7
##  5    5945          5948 III-1     HOSPITAL HER… LIMA … NO P… CARRETER…    -76.9
##  6    5984          5987 III-1     HOSPITAL MAR… LIMA … NO P… CALLE CA…    -77.0
##  7    7436          7632 II-2      HOSPITAL CAR… LIMA … NO P… AVENIDA …    -77.1
##  8    7437          7633 III-1     HOSPITAL NAC… LIMA … NO P… AVENIDA …    -77.1
##  9    7438          7634 III-1     HOSPITAL SER… LIMA … NO P… AVENIDA …    -77.0
## 10    8025          8318 II-1      ESSALUD - HO… LIMA … NO P… CARRETER…    -76.9
## # ℹ 11 more rows
## # ℹ 3 more variables: latitud <dbl>, id_ubigeo <dbl>, geometry <POINT>

Ahora los incluimos en un mapa filtrado para la provincia de Lima

library(mapsPERU)

df <- map_DIST

df <- df |>
  filter(DEPARTAMENTO=="Lima", PROVINCIA=="Lima")
library(ggplot2)
library(ggrepel)

ggplot(df, aes(geometry=geometry)) +
  geom_sf(aes()) +
  geom_sf(data=hh, aes(geometry=geometry),
             color="red", size=2.5) +
  geom_text_repel(data = hh, aes(longitud, latitud, label=nombre),
                  size=1.5, min.segment.length=0, max.overlaps=200, color="black")


  1. El archivo trabajado se puede descargar en https://zenodo.org/records/10564373↩︎