Las personas usuarias de información estadística territorial frecuentemente se enfrentan al problema de disponer de datos confiables y actualizados, en formatos apropiados para una diversidad de aplicaciones y análisis. En México, el INEGI es la institución que se encarga de recolectar, sistematizar y difundir información de todos los sectores. A pesar de que la disponibilidad y calidad de información ha aumentado considerablemente en las últimas dos décadas, es evidente que resulta imposible satisfacer todas las necesidades particulares con productos terminados y listos para utilizarse.
Un ejemplo de esto pueden ser los indicadores básicos del territorio, desagregados no por municipios ni localidades, sino por ciudades, conurbaciones, o áreas metropolitanas. La jerarquía territorial que estructura la información del INEGI, no necesariamente tiene una relación directa con la organización metropolitana y las conurbaciones que definen el Sistema Urbano Nacional (SUN).En este documento se realiza una búsqueda, limpieza y análisis de información para conformar una base de datos a nivel ciudad para la se presentan de manera inicial las variable de población y extensión territorial.
Este trabajo se realiza partiendo del producto “Principales resultados por localidad (ITER) del Censo de Población y Vivienda 2020” que como su nombre lo indica contiene los resultados para las variables censales hasta el nivel de localidades. Para calcular la superficie territorial que ocupa cada localidad se ha recurrido a los achivos tipo shapefiles (.shp) que comprenden el Marco Geoestadístico Nacional, mismos que fueron procesados utlizando un software de sistemas de información geográfica (QGIS 3.16).
En el presente documento se expone el procesamiento y tratamiento de los datos. Y se presentan algunas gráficas generales que nos permiten tener una perspectiva general de los indicadores básicos analizados. Finalente se genera una tabla que contiene los datos de población y extensión territorial para las ciudades del SUN para su utilización como insumo en otros análisis.
Se requiere la instalación de los paquetes dplyr, readr, foreign y ggplot2. Se creará una carpeta y subcarpeta dentro del directorio de “Mis Documentos” del usuario.
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(readr)
library(foreign)
library(ggplot2)
setwd("~/")
if (!dir.exists("R_Data")) {
dir.create("R_Data")
}
setwd("~/R_Data")
if (!dir.exists("ciudades")) {
dir.create("ciudades")
}
setwd("ciudades")
En este paso se descargarán los arhivos necesarios para realizar el análisis. Se descargarán los principales resultados por localidad (ITER) del Censo INEGI 2020, la base de datos conteniendo la superficie en hectáreas de las localidades de acuerdo al Marco Geoestadístico Nacional 2020 de INEGI, y el listado de ciudades del Sistema Urbano Nacoional (SUN 2018) que contiene las conirbaciones y áreas o zonas metropolitanas del país.
# INEGI - ITER 2020
url_iter00 <- "https://www.inegi.org.mx/contenidos/programas/ccpv/2020/datosabiertos/iter/iter_00_cpv2020_csv.zip"
iter00 <- "iter_00_cpv2020_csv.zip"
if (!file.exists(iter00)) {
download.file(url_iter00, iter00, mode = "wb")
}
if (!dir.exists("iter_00_cpv2020")) {
unzip(iter00)
}
# Urban surface by Locality
url_loc_areas <- "https://github.com/santanaluis/inegidata/raw/main/00l_areascalc.dbf"
loc_areas <- "00l_areascalc.dbf"
if (!file.exists(loc_areas)) {
download.file(url_loc_areas, loc_areas, mode = "wb")
}
#Metropolitan Areas List
url_zmetro <- "http://www.conapo.gob.mx/work/models/CONAPO/Marginacion/Datos_Abiertos/SUN/Base_SUN_2018.csv"
if (!file.exists("Base_SUN_2018.csv")) {
download.file(url_zmetro, "Base_SUN_2018.csv")
}
base_sun_2018 <- read.csv("Base_SUN_2018.csv", as.is = T)
Se leen los tres data-frames y se exploran sus encabezados para dar una idea de su estructura.
iter_2020 <- read_csv("conjunto_de_datos/conjunto_de_datos_iter_00CSV20.csv", na = "*")
## Warning: One or more parsing issues, see `problems()` for details
## Rows: 195662 Columns: 232
## -- Column specification --------------------------------------------------------
## Delimiter: ","
## chr (9): ENTIDAD, NOM_ENT, MUN, NOM_MUN, LOC, NOM_LOC, LONGITUD, LATITUD, ...
## dbl (223): POBTOT, POBFEM, POBMAS, P_0A2, P_0A2_F, P_0A2_M, P_3YMAS, P_3YMAS...
##
## i Use `spec()` to retrieve the full column specification for this data.
## i Specify the column types or set `show_col_types = FALSE` to quiet this message.
loc_areas <- read.dbf(loc_areas, as.is = FALSE)
base_sun_2018 <- read.csv("Base_SUN_2018.csv", as.is = T)
head(iter_2020)
## # A tibble: 6 x 232
## ENTIDAD NOM_ENT MUN NOM_MUN LOC NOM_LOC LONGITUD LATITUD ALTITUD POBTOT
## <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl>
## 1 00 Total n~ 000 Total n~ 0000 Total n~ "" "" "" 1.26e8
## 2 00 Total n~ 000 Total n~ 9998 Localid~ "" "" "" 2.50e5
## 3 00 Total n~ 000 Total n~ 9999 Localid~ "" "" "" 1.47e5
## 4 01 Aguasca~ 000 Total d~ 0000 Total d~ "" "" "" 1.43e6
## 5 01 Aguasca~ 000 Total d~ 9998 Localid~ "" "" "" 3.70e3
## 6 01 Aguasca~ 000 Total d~ 9999 Localid~ "" "" "" 3.02e3
## # ... with 222 more variables: POBFEM <dbl>, POBMAS <dbl>, P_0A2 <dbl>,
## # P_0A2_F <dbl>, P_0A2_M <dbl>, P_3YMAS <dbl>, P_3YMAS_F <dbl>,
## # P_3YMAS_M <dbl>, P_5YMAS <dbl>, P_5YMAS_F <dbl>, P_5YMAS_M <dbl>,
## # P_12YMAS <dbl>, P_12YMAS_F <dbl>, P_12YMAS_M <dbl>, P_15YMAS <dbl>,
## # P_15YMAS_F <dbl>, P_15YMAS_M <dbl>, P_18YMAS <dbl>, P_18YMAS_F <dbl>,
## # P_18YMAS_M <dbl>, P_3A5 <dbl>, P_3A5_F <dbl>, P_3A5_M <dbl>, P_6A11 <dbl>,
## # P_6A11_F <dbl>, P_6A11_M <dbl>, P_8A14 <dbl>, P_8A14_F <dbl>, ...
head(loc_areas)
## CVEGEO CVE_ENT CVE_MUN CVE_LOC NOMGEO
## 1 010060024 01 006 0024 Ojo Zarco [Colonia]
## 2 010060045 01 006 0045 Santiago
## 3 010060233 01 006 0233 San Carlos [Fraccionamiento Campestre]
## 4 010060258 01 006 0258 El Canal
## 5 010060287 01 006 0287 Las Flores
## 6 010060302 01 006 0302 Santa Isabel [Fraccionamiento]
## AMBITO SUP_HAS
## 1 Rural 18.9909
## 2 Rural 26.3988
## 3 Rural 124.8151
## 4 Rural 6.2208
## 5 Rural 2.3346
## 6 Rural 7.7799
head(base_sun_2018)
## CVE_ENT NOM_ENT CVE_MUN NOM_MUN CVE_LOC NOM_LOC
## 1 1 Aguascalientes 1011 San Francisco de los Romo NA
## 2 1 Aguascalientes 1005 Jesús María NA
## 3 1 Aguascalientes 1001 Aguascalientes NA
## 4 2 Baja California 2005 Playas de Rosarito NA
## 5 2 Baja California 2003 Tecate NA
## 6 2 Baja California 2004 Tijuana NA
## CVE_SUN NOM_SUN POB_2018
## 1 M01.01 Aguascalientes 42531
## 2 M01.01 Aguascalientes 116700
## 3 M01.01 Aguascalientes 897331
## 4 M02.03 Tijuana 110683
## 5 M02.03 Tijuana 115570
## 6 M02.03 Tijuana 1798741
Esta base de datos contiene aproximadamente 193 mil registros. En esta se mezclan observaciones de diferentes escalas (nacional, estatal, municipal y a nivel localidad). La tabla original descargada de INEGI requiere ser procesada para separarla en data sets utiles para el análisis estadístico.
## Separar filas que expresan totales por nacional, estatal o municipal.
iter_2020_ent <- filter(iter_2020, startsWith(iter_2020$NOM_MUN, "Total de la entidad"))
iter_2020_nal <- filter(iter_2020, iter_2020$NOM_MUN == "Total nacional")
iter_2020_mun <- filter(iter_2020, iter_2020$NOM_LOC == "Total del Municipio")
## Crar un segundo dataframe de localidades omitiendo filas de totales y
## subtotales para lograr tener siempre solo una observación por cada fila
iter_2020_loc <- filter(iter_2020, !startsWith(iter_2020$NOM_MUN, "Total"))
iter_2020_loc <- filter(iter_2020_loc, !startsWith(iter_2020_loc$NOM_LOC, "Total"))
## Crear campo de clave geografica
iter_2020_loc <- mutate(iter_2020_loc, CVEGEOL = paste(ENTIDAD, MUN, LOC, sep = ""))
## Crear campo de clave entidad+municipio
iter_2020_loc <- mutate(iter_2020_loc, CVEEMUN = paste(ENTIDAD, MUN, sep = ""))
head(iter_2020_loc)
## # A tibble: 6 x 234
## ENTIDAD NOM_ENT MUN NOM_MUN LOC NOM_LOC LONGITUD LATITUD ALTITUD POBTOT
## <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <dbl>
## 1 01 Aguasca~ 001 Aguasca~ 0001 Aguasca~ "102°17~ "21°52~ 1878 863893
## 2 01 Aguasca~ 001 Aguasca~ 0094 Granja ~ "102°22~ "21°52~ 1902 5
## 3 01 Aguasca~ 001 Aguasca~ 0096 Agua Az~ "102°21~ "21°53~ 1861 41
## 4 01 Aguasca~ 001 Aguasca~ 0102 Los Arb~ "102°21~ "21°46~ 1861 8
## 5 01 Aguasca~ 001 Aguasca~ 0104 Ardilla~ "102°11~ "21°56~ 1989 1
## 6 01 Aguasca~ 001 Aguasca~ 0106 Arellano "102°16~ "21°48~ 1892 1169
## # ... with 224 more variables: POBFEM <dbl>, POBMAS <dbl>, P_0A2 <dbl>,
## # P_0A2_F <dbl>, P_0A2_M <dbl>, P_3YMAS <dbl>, P_3YMAS_F <dbl>,
## # P_3YMAS_M <dbl>, P_5YMAS <dbl>, P_5YMAS_F <dbl>, P_5YMAS_M <dbl>,
## # P_12YMAS <dbl>, P_12YMAS_F <dbl>, P_12YMAS_M <dbl>, P_15YMAS <dbl>,
## # P_15YMAS_F <dbl>, P_15YMAS_M <dbl>, P_18YMAS <dbl>, P_18YMAS_F <dbl>,
## # P_18YMAS_M <dbl>, P_3A5 <dbl>, P_3A5_F <dbl>, P_3A5_M <dbl>, P_6A11 <dbl>,
## # P_6A11_F <dbl>, P_6A11_M <dbl>, P_8A14 <dbl>, P_8A14_F <dbl>, ...
Este paso se efectua la unión datos calculados de superficie con el data set de localidades del MGN. Adicionalmente creamos un nuevo dataframe con un listado corto de variables.
loc_datau <- inner_join(iter_2020_loc, loc_areas, by = c("CVEGEOL" = "CVEGEO"))
## Subset incluyendo población y grupos de edad y calculo densidad
loc_subs1 <- select(loc_datau, c(1:57, 231:240))
loc_poblysup <- select(loc_subs1, c(1:10, 58:61, 66, 67))
loc_poblysup <- mutate(loc_poblysup, DEN_LOC = loc_poblysup$POBTOT/loc_poblysup$SUP_HAS)
loc_poblysup <- mutate(loc_poblysup, CVE_MUN = CVEEMUN)
loc_poblysup <- select(loc_poblysup, !CVEEMUN)
Algo que podemos observar, es que al unir la tabla de localidades con superficies procedente del MGN, con la de las localidades del ITER, se pierden una gran cantidad de registros, pasando de 193 mil a poco menos de 50 mil en el dataframe unido. Podemos verificar las implicaciones de esto a nivel de volumen de población que representa:
paste("Población total en base ITER 2020:", sum(iter_2020_loc$POBTOT))
## [1] "Población total en base ITER 2020: 126411503"
paste("Población total Dataframe unido:", sum(loc_subs1$POBTOT))
## [1] "Población total Dataframe unido: 121716575"
loc.lostdata <- 100*(1-(sum(loc_subs1$POBTOT)/sum(iter_2020_loc$POBTOT)))
paste("Perdida en volúmen de población:", round(loc.lostdata, 2) , "%")
## [1] "Perdida en volúmen de población: 3.71 %"
La pérdida de este volumen de población al unir las tablas puede deberse a que no todas las localidades reportadas en los resultados del ITER están registradas en el MGN. Aunque esto podría no tener un impacto significativo en el análisis, es importante no perderlo de vista, ya que puede implicar la invisibilización de las localidades más marginadas en posteriores análisis.
En este apartado vamos a integrar la información de población y superficie de las Localidades del MGN a partir de la estructura del SUN. El primer paso consiste en la agrupación de los datos por municipio en el que se encuentran las localidades, y posterioremente por conurbación o zona metropolitana al que pertenece el municipio.
# Corregir clases de variables para poder indexar
base_sun_2018$CVE_MUN <- as.character(base_sun_2018$CVE_MUN)
sun_2018_clave <- base_sun_2018[, c(3,7,8)]
# length(unique(sun_2018_clave$CVE_SUN))
# Agrupar localidades por municipios
loc_poblysup <- group_by(loc_poblysup, CVE_MUN)
mun.supurb.pob <- summarise(loc_poblysup, POB_TOT = sum(POBTOT), SUP_TOT = sum(SUP_HAS))
mun.supurb.pob$CVE_MUN <- as.numeric(mun.supurb.pob$CVE_MUN)
mun.supurb.pob$CVE_MUN <- as.character(mun.supurb.pob$CVE_MUN)
df.ciudades <- inner_join(sun_2018_clave, mun.supurb.pob)
## Joining, by = "CVE_MUN"
# Aagrupar municipios por ciudades
df.ciudades <- group_by(df.ciudades, CVE_SUN, NOM_SUN)
df.ciudades.list <- summarise(df.ciudades, PTOT_CD = sum(POB_TOT), SUPT_CD = sum(SUP_TOT))
## `summarise()` has grouped output by 'CVE_SUN'. You can override using the `.groups` argument.
df.ciudades.list <- mutate(df.ciudades.list, DENS_HAS = PTOT_CD/SUPT_CD) #Crea campo de densidad
Como resultado obtenemos un data frame de 401 registros que contiene las ciudades del SUN, con los datos calculados de población y extensión territorial. A continuación se presentan los primeros y últimos 10 registros del data frame.
head(df.ciudades.list, 10)
## # A tibble: 10 x 5
## # Groups: CVE_SUN [10]
## CVE_SUN NOM_SUN PTOT_CD SUPT_CD DENS_HAS
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 C01.01 Rincón de Romos 163368 3239. 50.4
## 2 C05.01 Nueva Rosita-Cloete 106626 5410. 19.7
## 3 C06.01 Manzanillo 379284 12459. 30.4
## 4 C07.01 Cacahoatán 85260 8182. 10.4
## 5 C07.02 Frontera Comalapa 297492 8853. 33.6
## 6 C07.03 Huehuetán 64000 3831. 16.7
## 7 C07.04 Huixtla 229707 9709. 23.7
## 8 C07.05 Pichucalco 52392 2473. 21.2
## 9 C07.06 San Cristóbal de las Casas 1038490 28569. 36.4
## 10 C07.07 Teopisca 94240 3387. 27.8
tail(df.ciudades.list, 10)
## # A tibble: 10 x 5
## # Groups: CVE_SUN [10]
## CVE_SUN NOM_SUN PTOT_CD SUPT_CD DENS_HAS
## <chr> <chr> <dbl> <dbl> <dbl>
## 1 P31.08 Valladolid 84291 3214. 26.2
## 2 P32.01 Víctor Rosales 45137 1114. 40.5
## 3 P32.02 Jerez de García Salinas 58339 3453. 16.9
## 4 P32.03 Juan Aldama 19634 1510. 13.0
## 5 P32.04 Loreto_ZS 52448 1378. 38.1
## 6 P32.05 Miguel Auza 22692 2365. 9.59
## 7 P32.06 Nochistlán de Mejía 23873 977. 24.4
## 8 P32.07 Ojocaliente 43503 1803. 24.1
## 9 P32.08 Sombrerete 62247 4315. 14.4
## 10 P32.09 Tlaltenango de Sánchez Román 24811 987. 25.1
Finalmente, presentamos algunas gráficas resultado del análisis realizado en este trabajo.
A manera de ejemplo se presentan dos histogramas a partir de las variables de población total y grado promedio de escolaridad, ambas a nivel de localidad urbana.
ggplot(data = iter_2020_loc, aes(POBTOT/1000)) + geom_histogram(fill="#FD7C69") +
labs(x="Population (Thousands)", y="Frequency",
title="Population histogram, Localities, Data year:2020")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot(data = iter_2020_loc, aes(GRAPROES)) + geom_histogram(fill="#66A65F") +
labs(x="Númber of Years", y="Frequency",
title="Average years of education histogram, Localities, Data year:2020")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 82163 rows containing non-finite values (stat_bin).
Histogramas con datos de población, superficie y densidad.
ggplot(data = df.ciudades.list, aes(PTOT_CD/1000000)) + geom_histogram(fill="#665C51") +
labs(x="Population in millions", y="Frequency",
title="Total Population of Mexican Cities, Data year:2020")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot(data = df.ciudades.list, aes(SUPT_CD/1000)) + geom_histogram(fill="#C26B51") +
labs(x="Thousands of hectares", y="Frequency",
title="Ocupied surface of Mexican Cities, Data year:2020")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot(data = df.ciudades.list, aes(DENS_HAS)) + geom_histogram(fill="#41B7C4") +
labs(x="Density (inhabitants per hectare)", y="Frequency",
title="Density histogram of Mexican Cities, Data year:2020")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Relación entre Población y Superficie ocupada
ggplot(data = df.ciudades.list, aes(PTOT_CD/1000000, SUPT_CD/1000)) + geom_point(alpha = .6, size = 2) +
labs(x="Population (Millions)", y="Surface in hectares(Thousands)",
title = "Cities in Mexico by Population and Surface")+
geom_smooth(method = lm)
## `geom_smooth()` using formula 'y ~ x'