Primero, se cargan las librerías necesarias.

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.0.5
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.3     v purrr   0.3.4
## v tibble  3.1.0     v dplyr   1.0.5
## v tidyr   1.1.3     v stringr 1.4.0
## v readr   1.4.0     v forcats 0.5.1
## Warning: package 'ggplot2' was built under R version 4.0.5
## Warning: package 'tidyr' was built under R version 4.0.5
## Warning: package 'dplyr' was built under R version 4.0.5
## Warning: package 'stringr' was built under R version 4.0.5
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
library(sf)
## Warning: package 'sf' was built under R version 4.0.5
## Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1

Posteriormente se cargan los datos en formato geojson. El archivo agebs_cdmx contiene la geometría de las Áreas Geoestadísticas Básicas (AGEB), la unidad territorial más pequeña con información estadística en México.

agebs <- st_read("agebs_cdmx.geojson", stringsAsFactors = TRUE)
## Reading layer `agebs_cdmx' from data source `D:\Roberto\CursoCiudades\Clase1\agebs_cdmx.geojson' using driver `GeoJSON'
## Simple feature collection with 2431 features and 5 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: 2778446 ymin: 794914.6 xmax: 2820181 ymax: 846749.5
## Geodetic CRS:  WGS 84

Se pueder hacer un resumen de los datos con la función summary

summary(agebs)
##            CVEGEO     CVE_ENT      CVE_MUN       CVE_LOC        CVE_AGEB   
##  0900200010010:   1   09:2431   007    :458   0001   :2348   0012   :   2  
##  0900200010025:   1             005    :305   0026   :  20   0014   :   2  
##  090020001003A:   1             012    :207   0024   :  12   0017   :   2  
##  0900200010044:   1             010    :199   0011   :   9   001A   :   2  
##  0900200010097:   1             003    :156   0027   :   9   0021   :   2  
##  090020001010A:   1             015    :153   0021   :   7   0026   :   2  
##  (Other)      :2425             (Other):953   (Other):  26   (Other):2419  
##           geometry   
##  MULTIPOLYGON :2431  
##  epsg:4326    :   0  
##  +proj=long...:   0  
##                      
##                      
##                      
## 

En el resumen se puede observar que existen 2431 registros con cinco campos (Clave geo, Clave Entidad, Clave Municipio, Clave localidad y Clave AGEB). El archivo tiene una geometría de polígono y un EPSG: 4326. También se pueden visualizar los datos.

View(agebs)

Con esta información cargada, se puede generar el primer mapa de visualización con la función ggplot

ggplot(agebs) +
  geom_sf()
## Warning in st_is_longlat(x): bounding box has potentially an invalid value range
## for longlat data

Como se observó en el resumen, el archivo no contiene ninguna información estadística, por lo que es necesario agregar una base de datos del Instituto Nacional de Geografía y Estadística (INEGI) con información del censo 2020.

censo <- read.csv("censo_cdmx.csv", stringsAsFactors = TRUE, encoding = "UTF-8")

En este nuevo archivo de texto separado por comas, también es posible realizar un resumen y visualizar los datos.

summary(censo)
##            CVEGEO         POBTOT          POBFEM          POBMAS     
##  0900200010010:   1   Min.   :    0   Min.   :    0   Min.   :    0  
##  0900200010025:   1   1st Qu.: 2045   1st Qu.: 1084   1st Qu.:  974  
##  090020001003A:   1   Median : 3396   Median : 1784   Median : 1616  
##  0900200010044:   1   Mean   : 3759   Mean   : 1971   Mean   : 1805  
##  0900200010097:   1   3rd Qu.: 4992   3rd Qu.: 2618   3rd Qu.: 2391  
##  090020001010A:   1   Max.   :21198   Max.   :11128   Max.   :10616  
##  (Other)      :2427                   NA's   :11      NA's   :10     
##     PNACENT          PNACOE          POB_AFRO          GRAPROES    
##  Min.   :    0   Min.   :   0.0   Min.   :   0.00   Min.   : 0.00  
##  1st Qu.: 1640   1st Qu.: 347.0   1st Qu.:  24.00   1st Qu.:10.35  
##  Median : 2754   Median : 571.0   Median :  50.00   Median :11.40  
##  Mean   : 3036   Mean   : 686.2   Mean   :  77.90   Mean   :11.61  
##  3rd Qu.: 4032   3rd Qu.: 915.5   3rd Qu.:  97.75   3rd Qu.:13.20  
##  Max.   :15331   Max.   :4459.0   Max.   :1189.00   Max.   :16.20  
##  NA's   :10      NA's   :11       NA's   :51        NA's   :10     
##    VIVPAR_HAB     PROM_OCUP       VPH_C_ELEC     VPH_AGUADV     VPH_DRENAJ  
##  Min.   :   0   Min.   :0.000   Min.   :   0   Min.   :   0   Min.   :   0  
##  1st Qu.: 609   1st Qu.:3.000   1st Qu.: 637   1st Qu.: 633   1st Qu.: 637  
##  Median : 964   Median :3.400   Median :1005   Median : 998   Median :1004  
##  Mean   :1069   Mean   :3.317   Mean   :1128   Mean   :1120   Mean   :1127  
##  3rd Qu.:1400   3rd Qu.:3.700   3rd Qu.:1469   3rd Qu.:1460   3rd Qu.:1469  
##  Max.   :6297   Max.   :5.600   Max.   :8062   Max.   :8047   Max.   :8038  
##  NA's   :12     NA's   :10      NA's   :13     NA's   :12     NA's   :13    
##    VPH_REFRI      VPH_AUTOM          VPH_TV         VPH_PC      
##  Min.   :   0   Min.   :   0.0   Min.   :   0   Min.   :   0.0  
##  1st Qu.: 610   1st Qu.: 286.0   1st Qu.: 616   1st Qu.: 369.0  
##  Median : 941   Median : 455.0   Median : 972   Median : 571.0  
##  Mean   :1061   Mean   : 531.9   Mean   :1088   Mean   : 680.7  
##  3rd Qu.:1367   3rd Qu.: 662.0   3rd Qu.:1418   3rd Qu.: 839.0  
##  Max.   :7906   Max.   :6072.0   Max.   :7838   Max.   :6919.0  
##  NA's   :12     NA's   :20       NA's   :12     NA's   :16      
##    VPH_INTER     
##  Min.   :   0.0  
##  1st Qu.: 488.0  
##  Median : 749.0  
##  Mean   : 859.5  
##  3rd Qu.:1083.0  
##  Max.   :7512.0  
##  NA's   :15
View(censo)

Se puede observar que existen datos de población total, población masculina, población femenina, grado promedio de escolaridad, total de viviendas, viviendas con energía eléctrica, agua, drenaje, internet, entre otras variables.

Se procede a unir la geometría con la información estadística con una columna llave que en el archivo “agebs” se llama CVEGEO y en el archvo “censo” se llama CLAVE

agebs <- left_join(agebs, censo, by = "CVEGEO")

Con esta unión, es posible realizar un mapa de población total.

ggplot(agebs) +
  geom_sf(aes(fill= POBTOT))
## Warning in st_is_longlat(x): bounding box has potentially an invalid value range
## for longlat data

El mapa no es particularmente atractivo, así que se agregarán algunas mejoras como el título, se cambiarán los colores y se cambiará la simbología.

ggplot(agebs) +
  geom_sf(aes(fill= POBTOT), colour = "NA") +
  labs(title = "Ciudad de México: Población total por AGEB urbana",
       subtitle = "Fuente: INEGI, 2020",
       caption = "@geogracelis") +
  scale_fill_viridis_c("Población Total", option = "rocket", direction=-1) +
  theme_bw() +
  theme (plot.title = element_text(family = "sans",
                                   size = rel(1), 
                                   vjust = 2, 
                                   face = "bold.italic", 
                                   color = "black", 
                                   lineheight = 1.5)) +
  theme (plot.subtitle = element_text(family = "sans",
                                   size = rel(0.8),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray40", 
                                   lineheight = 1.5)) +
  theme (plot.caption = element_text(family = "sans",
                                   size = rel(0.7),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray30", 
                                   lineheight = 1.5)) +
  theme(legend.title = element_text(face = "bold", colour="darkgray", size=rel(0.75))) +
  theme(legend.text = element_text(face="italic", colour="gray", size=rel(0.6)))
## Warning in st_is_longlat(x): bounding box has potentially an invalid value range
## for longlat data

También se puede realizar un mapa del número de ocupantes promedio por vivienda para identificar zonas con hacinamiento.

ggplot(agebs) +
  geom_sf(aes(fill= PROM_OCUP), colour = "NA") +
  labs(title = "Ciudad de México: Promedio de Ocupantes por Vivienda",
       subtitle = "Fuente: INEGI, 2020",
       caption = "@geogracelis") +
  scale_fill_viridis_c("Ocupantes por vivienda", option = "magma", direction=-1) +
  theme_bw() +
  theme (plot.title = element_text(family = "sans",
                                   size = rel(1), 
                                   vjust = 2, 
                                   face = "bold.italic", 
                                   color = "black", 
                                   lineheight = 1.5)) +
  theme (plot.subtitle = element_text(family = "sans",
                                   size = rel(0.8),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray40", 
                                   lineheight = 1.5)) +
  theme (plot.caption = element_text(family = "sans",
                                   size = rel(0.7),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray30", 
                                   lineheight = 1.5)) +
  theme(legend.title = element_text(face = "bold", colour="darkgray", size=rel(0.75))) +
  theme(legend.text = element_text(face="italic", colour="gray", size=rel(0.6)))
## Warning in st_is_longlat(x): bounding box has potentially an invalid value range
## for longlat data

En este mapa se puede observar que la zona centro, parte del poniente y sur de la ciudad de México presentan valores menores del promedio de ocupantes por vivienda y conforme nos desplazamos a la periferia, el número promedio de ocupantes por vivienda es mayor.

También se puede crear una nueva variable a partir de las existentes. Por ejemplo, para obtener el porcentaje de personas nacidas en otra entidad e identificar zonas de inmigrantes.

ggplot(agebs) +
  geom_sf(aes(fill= PNACOE/POBTOT*100), colour = "NA") +
  labs(title = "Ciudad de México: Zonas de inmigración",
       subtitle = "Fuente: INEGI, 2020",
       caption = "@geogracelis") +
  scale_fill_viridis_c("% de inmigrantes", option = "inferno", direction=-1) +
  theme_bw() +
  theme (plot.title = element_text(family = "sans",
                                   size = rel(1), 
                                   vjust = 2, 
                                   face = "bold.italic", 
                                   color = "black", 
                                   lineheight = 1.5)) +
  theme (plot.subtitle = element_text(family = "sans",
                                   size = rel(0.8),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray40", 
                                   lineheight = 1.5)) +
  theme (plot.caption = element_text(family = "sans",
                                   size = rel(0.7),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray30", 
                                   lineheight = 1.5)) +
  theme(legend.title = element_text(face = "bold", colour="darkgray", size=rel(0.75))) +
  theme(legend.text = element_text(face="italic", colour="gray", size=rel(0.6)))
## Warning in st_is_longlat(x): bounding box has potentially an invalid value range
## for longlat data

En el mapa anterior, no es posible identificar un patrón espacial, sin embargo la zona centro, norte y oriente de la ciudad presenta los porcentajes más elevados de personas nacidas en otra entidad (distinta a la ciudad de México), también se observan valores elevados cerca de Ciudad Universitaria y del Instituto Politécnico Nacional ya que muchos de sus estudiantes son de otras entidades del país.

La ciudad de México se divide en 16 alcaldías por lo que se puede realizar un filtro a partir de una de ellas. Aquí el ejemplo del promedio de ocupantes de vivienda en Iztapalapa, la más poblada de todas.

ggplot(agebs %>% filter(CVE_MUN == "007")) +
  geom_sf(aes(fill= GRAPROES), colour = "NA") +
  labs(title = "Iztapalapa: Grado Promedio de Escolaridad",
       subtitle = "Fuente: INEGI, 2020",
       caption = "@geogracelis") +
  scale_fill_viridis_c("Años de estudio", option = "viridis", direction=-1) +
  theme_bw() +
  theme (plot.title = element_text(family = "sans",
                                   size = rel(1), 
                                   vjust = 2, 
                                   face = "bold.italic", 
                                   color = "black", 
                                   lineheight = 1.5)) +
  theme (plot.subtitle = element_text(family = "sans",
                                   size = rel(0.8),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray40", 
                                   lineheight = 1.5)) +
  theme (plot.caption = element_text(family = "sans",
                                   size = rel(0.7),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray30", 
                                   lineheight = 1.5)) +
  theme(legend.title = element_text(face = "bold", colour="darkgray", size=rel(0.75))) +
  theme(legend.text = element_text(face="italic", colour="gray", size=rel(0.6)))
## Warning in st_is_longlat(x): bounding box has potentially an invalid value range
## for longlat data

Se observa que el número de años promedio de escolaridad es menor en la parte sureste de la alcaldía, ya que son zonas marginadas por ubicarse en zonas serranas.

Se va a agregar una nueva columna para identificar si el número de años de escolaridad es mayor a 12, que son los años que una persona requiere para terminar el nivel medio superior (bachillerato o preparatoria) y que es el grado de escolaridad obligatorio en México y así tener un mapa de una variable categórica.

agebs <- mutate(agebs, GPE_NMS = if_else(GRAPROES >= 12.0, "NIvel medio superior o mayor", "Menor que preparatoria terminada"))

Se visualiza para asegura que la nueva variable ha sido creada.

View(agebs)

Y se realiza el mapa de una variable categórica.

ggplot(agebs) +
  geom_sf(aes(fill= GPE_NMS), colour = "NA") +
  labs(title = "Ciudad de México: Promedio de Escolaridad",
       subtitle = "Fuente: INEGI, 2020",
       caption = "@geogracelis") +
  scale_fill_viridis_d("Nivel de estudios", direction=-1) +
  theme_bw() +
  theme (plot.title = element_text(family = "sans",
                                   size = rel(1), 
                                   vjust = 2, 
                                   face = "bold.italic", 
                                   color = "black", 
                                   lineheight = 1.5)) +
  theme (plot.subtitle = element_text(family = "sans",
                                   size = rel(0.8),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray40", 
                                   lineheight = 1.5)) +
  theme (plot.caption = element_text(family = "sans",
                                   size = rel(0.7),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray30", 
                                   lineheight = 1.5)) +
  theme(legend.title = element_text(face = "bold", colour="darkgray", size=rel(0.75))) +
  theme(legend.text = element_text(face="italic", colour="gray", size=rel(0.6)))
## Warning in st_is_longlat(x): bounding box has potentially an invalid value range
## for longlat data

Se observa en el mapa un patrón de distribución interesante, ya que en el centro y poniente de la ciudad existe una mayor cantidad de personas que han estudiado 12 años o más, mientras que el sur, el oriente y algunas zonas del norte tienen un promedio de escolaridad menor.

Finalmente, se va a agregar una nueva columna para identificar si el número de ocupantes por vivienda es mayor que 3.0, pra identificar zonas con posible hacinamiento y así tener un mapa de otra variable categórica.

agebs <- mutate(agebs, POV = if_else(PROM_OCUP >= 3.0, "Mayor de 3.0", "Menor de 3.0"))

Y se realiza el último mapa.

ggplot(agebs) +
  geom_sf(aes(fill= POV), colour = "NA") +
  labs(title = "Ciudad de México: Grado de Hacinamiento",
       subtitle = "Fuente: INEGI, 2020",
       caption = "@geogracelis") +
  scale_fill_viridis_d("Ocupantes") +
  theme_bw() +
  theme (plot.title = element_text(family = "sans",
                                   size = rel(1), 
                                   vjust = 2, 
                                   face = "bold.italic", 
                                   color = "black", 
                                   lineheight = 1.5)) +
  theme (plot.subtitle = element_text(family = "sans",
                                   size = rel(0.8),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray40", 
                                   lineheight = 1.5)) +
  theme (plot.caption = element_text(family = "sans",
                                   size = rel(0.7),
                                   vjust = 2, 
                                   face = "italic", 
                                   color = "gray30", 
                                   lineheight = 1.5)) +
  theme(legend.title = element_text(face = "bold", colour="darkgray", size=rel(0.75))) +
  theme(legend.text = element_text(face="italic", colour="gray", size=rel(0.6)))
## Warning in st_is_longlat(x): bounding box has potentially an invalid value range
## for longlat data

Se aprecia en el mapa que la zona centro y poniente de la ciudad (en amarillo) es la que presenta los valores del promedio de ocupantes más bajo, mientras que la periferia del sur, norte y oriente presenta una mayor cantidad de ocupantes en promedio.