Rodrigo Zumaya Tapia · Ana Laura Salguero Melgar
En Geotitlán, los saberes antiguos se entrelazan con
las nuevas geotecnologías.
Guiados por Tochtli, la teporingo programadora, este
taller nos invita a descubrir cómo la automatización puede transformar
la forma en que entendemos el territorio.
A partir del uso de R y sus librerías geoespaciales, aprenderemos a descargar, procesar y mapear datos del INEGI, construyendo indicadores que revelan la diversidad y complejidad del espacio.
Así, lo que antes requería horas de trabajo manual, hoy puede convertirse en un flujo ágil y reproducible: un ritual de código y cartografía, donde la ciencia de datos se convierte en herramienta de cuidado y reflexión sobre el territorio.
Tochtli, la teporingo programadora, nos guía por los senderos del código y la cartografía 🐇💻
Explorar cómo R y sus herramientas geoespaciales permiten automatizar el análisis territorial y crear mapas temáticos, fortaleciendo una lectura crítica y creativa del territorio desde la mirada de Tochtli, guardiana de la geointeligencia en Geotitlán.
En el viaje por Geotitlán, cada punto, línea y
polígono guarda una historia.
Los nuevos exploradores del territorio necesitan no solo observar, sino
interpretar y automatizar los procesos que transforman
esos datos en conocimiento.
Inspirados por Tochtli, aprenderemos que
programar también es una forma de tejer vínculos con la
Tierra:
cada línea de código es un trazo que une el pasado con el futuro, la
técnica con la memoria.
En los caminos de Geotitlán, un Sistema de
Información Geográfica (SIG) es como un gran códice que guarda
las huellas del territorio.
Permite:
Tochtli, la teporingo Usuaria de SIG 🐇💻
“Si Tochtli abre shapefiles, calcula áreas, genera buffers y produce mapas… ¿acaso R es un SIG?”
Respuesta: No exactamente.
R no es un SIG tradicional, pero sí puede comportarse como
uno gracias a sus librerías geoespaciales.
En lugar de hacerlo con clics, R lo hace con código, y
eso le da algo más poderoso: repetición, automatización y
reproducibilidad.
🧩 Tochtli sonríe mientras dice:
> “Un SIG puede hacer un mapa.
> R puede hacer mil mapas con solo cambiar una línea.”
🔹 R no es un SIG porque:
- No tiene una interfaz visual donde arrastrar capas.
- No administra bases espaciales de forma nativa (aunque puede
conectarse a PostGIS o GeoPackage).
- No fue creado para la cartografía, sino para pensar con
datos.
🔹 Pero sí es una plataforma geoespacial
porque:
- Interpreta geometrías, proyecciones y coordenadas.
- Calcula, combina y transforma información espacial.
- Permite integrar análisis estadístico, modelado y
visualización geográfica en un mismo lenguaje.
💬 Tochtli lo explica así:
> “Mientras un SIG tradicional analiza el territorio una vez,
> R aprende a hacerlo para siempre.”
Gracias a sus librerías geoespaciales, R entiende las formas del territorio y las convierte en objetos que se pueden analizar, transformar y mapear.
| Función | Librería | Descripción |
|---|---|---|
| Lectura y manejo de geometrías | sf (simple features) | Abre shapefiles, GeoPackage, GeoJSON; maneja puntos, líneas y polígonos. |
| Análisis y operaciones espaciales | sf, terra, rmapshaper | Calcula distancias, buffers, uniones espaciales e intersecciones. |
| Estadística espacial | spdep, spatialreg, gstat | Evalúa autocorrelación espacial, modelos SAR/SEM, interpolaciones. |
| Visualización y cartografía | tmap, ggplot2, leaflet, plotly | Genera mapas estáticos, temáticos e interactivos. |
| Conexión y datos externos | readr, geojsonio, httr, RPostgres | Conecta R con APIs, PostGIS o fuentes abiertas. |
🪶 Tochtli dice mientras dibuja un mapa:
> “Cada librería es como una herramienta del viajero:
> una para leer el suelo, otra para medir el aire, otra para pintar
la historia.”
Antes de que Tochtli inicie su viaje de datos, debe
abrir su mochila digital y decirle a R dónde guardará
sus hallazgos.
Esto se llama definir el directorio de trabajo, el
lugar donde se almacenan los mapas y tablas del viaje.
“Aquí están mis semillas de código y mis rutas geográficas.”
En RStudio, puedes crear un nuevo chunk (una celda de código) con:
Ctrl + Alt + I (Windows)Cmd + Option + I (Mac)# Definir la ruta del taller
ruta_trabajo <- "C:\\geodatos" # O también: "C:/geodatos"
# Establecer el directorio de trabajo
setwd(ruta_trabajo)
# Confirmar el cambio
getwd()
## [1] "C:/geodatos"
Para Tochtli, un data frame es como una
milpa ordenada:
cada fila es una parcela (una observación) y cada
columna una planta distinta (una variable).
🌾 Cada fila = una unidad territorial
(municipio, AGEB, colonia).
🌿 Cada columna = una característica (población,
densidad, índice de juventud, etc.).
💡 En resumen:
Un data frame es una tabla viva, donde cada
columna puede tener números, texto o coordenadas,
y donde se siembran los datos que luego florecen en mapas.
🧩 Tochtli concluye:
> “R es nuestro códice digital.
> Si aprendemos a leerlo, el territorio se revela línea a línea, dato
a dato, mapa a mapa.”
Tochtli, la teporingo Usuaria de datos de SIG 🐇💻
Antes de abrir los códices, Tochtli revisa sus
herramientas.
En R, estas herramientas se llaman
librerías, y permiten leer, limpiar y explorar los
datos.
Con ellas puede:
“Sin librerías, el código no florece —recuerda Tochtli—.
Cada función es una semilla que hace crecer el conocimiento.”
library(readr) # para leer archivos CSV
library(dplyr) # para manipular datos (filtrar, seleccionar, agrupar)
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(janitor) # para limpiar nombres de columnas fácilmente
##
## Adjuntando el paquete: 'janitor'
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
# 🧭 Cargando los códices del territorio
# Tochtli abre los registros del INEGI para iniciar su viaje de datos
# Cargar los archivos de los censos desde la nueva carpeta
iter_2010 <- read_csv("C:/geodatos/Censos/iter_2010.csv")
## Rows: 198488 Columns: 200
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (195): entidad, nom_ent, mun, nom_mun, loc, nom_loc, longitud, altitud, ...
## dbl (5): latitud, pobtot, vivtot, tvivhab, tam_loc
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
iter_2020 <- read_csv("C:/geodatos/Censos/iter_2020.csv")
## Rows: 195662 Columns: 286
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (283): ENTIDAD, NOM_ENT, MUN, NOM_MUN, LOC, NOM_LOC, LONGITUD, LATITUD, ...
## dbl (3): POBTOT, VIVTOT, TVIVHAB
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# Confirmar que las tablas fueron leídas correctamente
glimpse(iter_2010)
## Rows: 198,488
## Columns: 200
## $ entidad <chr> "00", "00", "00", "01", "01", "01", "01", "01", "01", "01",…
## $ nom_ent <chr> "Total nacional", "Total nacional", "Total nacional", "Agua…
## $ mun <chr> "000", "000", "000", "000", "000", "000", "001", "001", "00…
## $ nom_mun <chr> "Total nacional", "Total nacional", "Total nacional", "Tota…
## $ loc <chr> "0000", "9998", "9999", "0000", "9998", "9999", "0000", "00…
## $ nom_loc <chr> "Total nacional", "Localidades de una vivienda", "Localidad…
## $ longitud <chr> NA, NA, NA, NA, NA, NA, NA, "1021746", "1022225", "1022127"…
## $ latitud <dbl> NA, NA, NA, NA, NA, NA, NA, 215251, 215219, 215303, 215116,…
## $ altitud <chr> NA, NA, NA, NA, NA, NA, NA, "1885", "1903", "1863", "1880",…
## $ pobtot <dbl> 112336538, 260087, 173056, 1184996, 3395, 2800, 797010, 722…
## $ pobmas <chr> "54855231", "152757", "98232", "576638", "1803", "1634", "3…
## $ pobfem <chr> "57481307", "107330", "74824", "608358", "1592", "1166", "4…
## $ p_0a2 <chr> "6157867", "12459", "9369", "71484", "194", "178", "44873",…
## $ p_0a2_m <chr> "3132624", "6281", "4767", "36375", "94", "99", "22835", "2…
## $ p_0a2_f <chr> "3025243", "6178", "4602", "35109", "100", "79", "22038", "…
## $ p_3ymas <chr> "104781265", "245319", "162593", "1109480", "3191", "2609",…
## $ p_3ymas_m <chr> "51022388", "145291", "92885", "538279", "1705", "1530", "3…
## $ p_3ymas_f <chr> "53758877", "100028", "69708", "571201", "1486", "1079", "3…
## $ p_5ymas <chr> "100410810", "236360", "156057", "1059407", "3043", "2507",…
## $ p_5ymas_m <chr> "48808069", "140703", "89629", "512713", "1624", "1482", "3…
## $ p_5ymas_f <chr> "51602741", "95657", "66428", "546694", "1419", "1025", "37…
## $ p_12ymas <chr> "84927468", "205923", "133734", "879679", "2517", "2103", "…
## $ p_12ymas_m <chr> "40947872", "124895", "77973", "421255", "1342", "1260", "2…
## $ p_12ymas_f <chr> "43979596", "81028", "55761", "458424", "1175", "843", "315…
## $ p_15ymas <chr> "78423336", "191195", "124165", "806727", "2268", "1945", "…
## $ p_15ymas_m <chr> "37656281", "116592", "73001", "384526", "1220", "1181", "2…
## $ p_15ymas_f <chr> "40767055", "74603", "51164", "422201", "1048", "764", "291…
## $ p_18ymas <chr> "71712388", "176265", "114519", "732571", "2032", "1796", "…
## $ p_18ymas_m <chr> "34279833", "108213", "67873", "347337", "1096", "1089", "2…
## $ p_18ymas_f <chr> "37432555", "68052", "46646", "385234", "936", "707", "2678…
## $ p_3a5 <chr> "6535234", "13306", "9686", "75453", "224", "171", "47951",…
## $ p_3a5_m <chr> "3316316", "6795", "4869", "38521", "122", "83", "24520", "…
## $ p_3a5_f <chr> "3218918", "6511", "4817", "36932", "102", "88", "23431", "…
## $ p_6a11 <chr> "13318563", "26090", "19173", "154348", "450", "335", "9822…
## $ p_6a11_m <chr> "6758200", "13601", "10043", "78503", "241", "187", "50005"…
## $ p_6a11_f <chr> "6560363", "12489", "9130", "75845", "209", "148", "48216",…
## $ p_8a14 <chr> "15443365", "32498", "22366", "176175", "544", "378", "1128…
## $ p_8a14_m <chr> "7831926", "17695", "11715", "89301", "286", "200", "57191"…
## $ p_8a14_f <chr> "7611439", "14803", "10651", "86874", "258", "178", "55629"…
## $ p_12a14 <chr> "6504132", "14728", "9569", "72952", "249", "158", "47148",…
## $ p_12a14_m <chr> "3291591", "8303", "4972", "36729", "122", "79", "23725", "…
## $ p_12a14_f <chr> "3212541", "6425", "4597", "36223", "127", "79", "23423", "…
## $ p_15a17 <chr> "6710948", "14930", "9646", "74156", "236", "149", "47860",…
## $ p_15a17_m <chr> "3376448", "8379", "5128", "37189", "124", "92", "23913", "…
## $ p_15a17_f <chr> "3334500", "6551", "4518", "36967", "112", "57", "23947", "…
## $ p_18a24 <chr> "14207435", "31095", "21749", "153577", "426", "360", "1036…
## $ p_18a24_m <chr> "6956877", "18069", "12205", "74878", "245", "196", "51067"…
## $ p_18a24_f <chr> "7250558", "13026", "9544", "78699", "181", "164", "52537",…
## $ p_15a49_f <chr> "30703546", "52730", "36553", "327632", "772", "586", "2239…
## $ p_60ymas <chr> "10055379", "34340", "20494", "89605", "376", "244", "61285…
## $ p_60ymas_m <chr> "4679538", "22119", "11928", "41163", "225", "146", "27248"…
## $ p_60ymas_f <chr> "5375841", "12221", "8566", "48442", "151", "98", "34037", …
## $ rel_h_m <chr> "95.43", "*", "*", "94.79", "*", "*", "94.12", "93.36", "*"…
## $ pob0_14 <chr> "32515796", "66583", "47797", "374237", "1117", "842", "238…
## $ pob15_64 <chr> "71484423", "166964", "109473", "746380", "2008", "1790", "…
## $ pob65_mas <chr> "6938913", "24231", "14692", "60347", "260", "155", "40309"…
## $ prom_hnv <chr> "2.34", "*", "*", "2.35", "*", "*", "2.20", "2.16", "*", "1…
## $ pnacent <chr> "89918571", "214116", "147458", "936435", "2707", "2145", "…
## $ pnacent_m <chr> "44019967", "123701", "82083", "459070", "1434", "1224", "2…
## $ pnacent_f <chr> "45898604", "90415", "65375", "477365", "1273", "921", "306…
## $ pnacoe <chr> "19747511", "39947", "22462", "233073", "637", "570", "1869…
## $ pnacoe_m <chr> "9490776", "25764", "14434", "109757", "338", "356", "87621…
## $ pnacoe_f <chr> "10256735", "14183", "8028", "123316", "299", "214", "99351…
## $ pres2005 <chr> "95431977", "219565", "147917", "998392", "2785", "2280", "…
## $ pres2005_m <chr> "46127432", "128555", "84233", "479423", "1469", "1316", "3…
## $ pres2005_f <chr> "49304545", "91010", "63684", "518969", "1316", "964", "350…
## $ presoe05 <chr> "3292310", "12401", "5279", "41061", "194", "133", "32756",…
## $ presoe05_m <chr> "1640195", "9055", "3408", "20167", "108", "97", "16011", "…
## $ presoe05_f <chr> "1652115", "3346", "1871", "20894", "86", "36", "16745", "1…
## $ p3ym_hli <chr> "6913362", "25138", "21198", "2493", "10", "10", "1790", "1…
## $ p3ym_hli_m <chr> "3397199", "14563", "11414", "1453", "6", "10", "1032", "94…
## $ p3ym_hli_f <chr> "3516163", "10575", "9784", "1040", "4", "0", "758", "695",…
## $ p3hlinhe <chr> "1096512", "3552", "4315", "5", "0", "0", "4", "4", "*", "0…
## $ p3hlinhe_m <chr> "422143", "1420", "1687", "3", "0", "0", "2", "2", "*", "0"…
## $ p3hlinhe_f <chr> "674369", "2132", "2628", "2", "0", "0", "2", "2", "*", "0"…
## $ p3hli_he <chr> "5562979", "20637", "16247", "1223", "8", "6", "939", "875"…
## $ p3hli_he_m <chr> "2849099", "12556", "9375", "741", "5", "6", "563", "525", …
## $ p3hli_he_f <chr> "2713880", "8081", "6872", "482", "3", "0", "376", "350", "…
## $ p5_hli <chr> "6695228", "24305", "20290", "2436", "10", "10", "1752", "1…
## $ p5_hli_nhe <chr> "980894", "3144", "3814", "4", "0", "0", "3", "3", "*", "0"…
## $ p5_hli_he <chr> "5467527", "20243", "15864", "1212", "8", "6", "933", "870"…
## $ phog_ind <chr> "10788615", "31908", "26036", "5660", "20", "5", "4018", "3…
## $ pcon_lim <chr> "4527784", "14949", "9237", "49226", "197", "165", "30563",…
## $ pclim_mot <chr> "2437397", "7766", "4768", "27580", "103", "70", "17286", "…
## $ pclim_vis <chr> "1292201", "4485", "2645", "13345", "46", "54", "8176", "74…
## $ pclim_leng <chr> "401534", "1275", "838", "4339", "28", "18", "2738", "2438"…
## $ pclim_aud <chr> "498640", "1733", "1182", "5011", "28", "17", "3041", "2767…
## $ pclim_mot2 <chr> "229029", "612", "371", "2837", "8", "5", "1874", "1721", "…
## $ pclim_men <chr> "209306", "641", "349", "2992", "15", "12", "1876", "1638",…
## $ pclim_men2 <chr> "448873", "1744", "1023", "5490", "18", "17", "3645", "3244…
## $ psin_lim <chr> "105646736", "240607", "157833", "1128583", "3172", "2562",…
## $ p3a5_noa <chr> "2942092", "8467", "6172", "37663", "132", "107", "23224", …
## $ p3a5_noa_m <chr> "1500801", "4376", "3106", "19324", "74", "54", "11967", "1…
## $ p3a5_noa_f <chr> "1441291", "4091", "3066", "18339", "58", "53", "11257", "9…
## $ p6a11_noa <chr> "407458", "4035", "2884", "3748", "32", "26", "2415", "2116…
## $ p6a11_noam <chr> "215711", "2061", "1504", "2031", "22", "15", "1316", "1138…
## $ p6a11_noaf <chr> "191747", "1974", "1380", "1717", "10", "11", "1099", "978"…
## $ p12a14noa <chr> "538920", "3596", "2565", "5941", "45", "25", "3574", "3071…
## $ p12a14noam <chr> "283536", "1947", "1328", "3184", "25", "13", "1894", "1631…
## $ p12a14noaf <chr> "255384", "1649", "1237", "2757", "20", "12", "1680", "1440…
## $ p15a17a <chr> "4499305", "6780", "4048", "47571", "116", "80", "32330", "…
## $ p15a17a_m <chr> "2233341", "3922", "2187", "23334", "60", "53", "15929", "1…
## $ p15a17a_f <chr> "2265964", "2858", "1861", "24237", "56", "27", "16401", "1…
## $ p18a24a <chr> "3955759", "4758", "2972", "42172", "89", "62", "33116", "3…
## $ p18a24a_m <chr> "1978232", "3074", "1876", "20731", "57", "38", "16580", "1…
## $ p18a24a_f <chr> "1977527", "1684", "1096", "21441", "32", "24", "16536", "1…
## $ p8a14an <chr> "554204", "3930", "2928", "3006", "33", "25", "1742", "1509…
## $ p8a14an_m <chr> "315715", "2196", "1654", "1838", "23", "16", "1044", "906"…
## $ p8a14an_f <chr> "238489", "1734", "1274", "1168", "10", "9", "698", "603", …
## $ p15ym_an <chr> "5393665", "32262", "22243", "26269", "223", "179", "14326"…
## $ p15ym_an_m <chr> "2099269", "18111", "11285", "11391", "126", "98", "5715", …
## $ p15ym_an_f <chr> "3294396", "14151", "10958", "14878", "97", "81", "8611", "…
## $ p15ym_se <chr> "5646147", "35502", "24022", "32064", "245", "199", "18759"…
## $ p15ym_se_m <chr> "2326976", "20731", "12686", "14799", "148", "111", "8178",…
## $ p15ym_se_f <chr> "3319171", "14771", "11336", "17265", "97", "88", "10581", …
## $ p15pri_in <chr> "9947945", "50636", "31182", "86763", "575", "417", "44967"…
## $ p15pri_inm <chr> "4707350", "31110", "18493", "41421", "322", "233", "20243"…
## $ p15pri_inf <chr> "5240595", "19526", "12689", "45342", "253", "184", "24724"…
## $ p15pri_co <chr> "12565410", "39138", "25058", "128807", "471", "310", "8240…
## $ p15pri_com <chr> "5832568", "23590", "14409", "58883", "241", "176", "37173"…
## $ p15pri_cof <chr> "6732842", "15548", "10649", "69924", "230", "134", "45228"…
## $ p15sec_in <chr> "4082402", "10634", "7820", "39284", "120", "101", "25592",…
## $ p15sec_inm <chr> "2234373", "7163", "5413", "22034", "72", "70", "14311", "1…
## $ p15sec_inf <chr> "1848029", "3471", "2407", "17250", "48", "31", "11281", "1…
## $ p15sec_co <chr> "17181221", "29863", "20208", "203516", "420", "480", "1334…
## $ p15sec_com <chr> "8491006", "18526", "12552", "97269", "210", "316", "64820"…
## $ p15sec_cof <chr> "8690215", "11337", "7656", "106247", "210", "164", "68613"…
## $ p18ym_pb <chr> "26057800", "22016", "13846", "283254", "368", "345", "2265…
## $ p18ym_pb_m <chr> "12797492", "13719", "8403", "136375", "203", "217", "10923…
## $ p18ym_pb_f <chr> "13260308", "8297", "5443", "146879", "165", "128", "117266…
## $ graproes <chr> "8.63", "*", "*", "9.23", "*", "*", "9.81", "10.01", "*", "…
## $ graproes_m <chr> "8.79", "*", "*", "9.30", "*", "*", "9.95", "10.18", "*", "…
## $ graproes_f <chr> "8.48", "*", "*", "9.17", "*", "*", "9.69", "9.86", "*", "5…
## $ pea <chr> "44701044", "114327", "67165", "475207", "1273", "1101", "3…
## $ pea_m <chr> "30045138", "102367", "59141", "307381", "1040", "935", "20…
## $ pea_f <chr> "14655906", "11960", "8024", "167826", "233", "166", "12736…
## $ pe_inac <chr> "39657833", "90326", "59919", "401248", "1232", "945", "263…
## $ pe_inac_m <chr> "10551884", "21737", "12748", "111981", "296", "286", "7676…
## $ pe_inac_f <chr> "29105949", "68589", "47171", "289267", "936", "659", "1870…
## $ pocupada <chr> "42669675", "112669", "65758", "443826", "1233", "1060", "3…
## $ pocupada_m <chr> "28447257", "100913", "57896", "282532", "1007", "901", "19…
## $ pocupada_f <chr> "14222418", "11756", "7862", "161294", "226", "159", "12211…
## $ pdesocup <chr> "2031369", "1658", "1407", "31381", "40", "41", "21020", "1…
## $ pdesocup_m <chr> "1597881", "1454", "1245", "24849", "33", "34", "15770", "1…
## $ pdesocup_f <chr> "433488", "204", "162", "6532", "7", "7", "5250", "4969", "…
## $ psinder <chr> "38020372", "120820", "79539", "249596", "1031", "982", "17…
## $ pder_ss <chr> "72514513", "136035", "86192", "930149", "2347", "1775", "6…
## $ pder_imss <chr> "35380021", "42422", "23108", "530445", "877", "711", "4159…
## $ pder_iste <chr> "6303630", "3397", "2000", "85564", "112", "46", "62219", "…
## $ pder_istee <chr> "900884", "489", "314", "3470", "12", "5", "2056", "1949", …
## $ pder_segp <chr> "26229071", "75338", "55607", "303287", "1318", "1011", "12…
## $ p12ym_solt <chr> "29853117", "69720", "44845", "323815", "951", "706", "2237…
## $ p12ym_casa <chr> "46651603", "118495", "77984", "482578", "1408", "1158", "3…
## $ p12ym_sepa <chr> "8162339", "17302", "10477", "71817", "157", "186", "54101"…
## $ pcatolica <chr> "92924489", "208751", "141704", "1101785", "3235", "2525", …
## $ pncatolica <chr> "10924103", "24117", "15620", "51766", "68", "123", "40707"…
## $ potras_rel <chr> "172891", "1847", "1333", "835", "3", "0", "709", "682", "*…
## $ psin_relig <chr> "5262546", "19260", "11032", "21235", "38", "69", "17073", …
## $ tothog <chr> "28159373", "63531", "39674", "289575", "799", "557", "2010…
## $ hogjef_m <chr> "21243167", "57943", "34821", "224643", "716", "478", "1527…
## $ hogjef_f <chr> "6916206", "5588", "4853", "64932", "83", "79", "48317", "4…
## $ pobhog <chr> "110610075", "231430", "153907", "1178123", "3349", "2366",…
## $ phogjef_m <chr> "87382237", "210660", "137176", "959212", "3022", "2027", "…
## $ phogjef_f <chr> "23227838", "20770", "16731", "218911", "327", "339", "1588…
## $ vivtot <dbl> 35625147, 104004, 63685, 361676, 1300, 771, 247792, 225328,…
## $ tvivhab <dbl> 28614991, 64433, 40054, 290877, 803, 566, 202141, 185120, 2…
## $ tvivpar <chr> "35169529", "103102", "63305", "360374", "1296", "762", "24…
## $ vivpar_hab <chr> "28159373", "63531", "39674", "289575", "799", "557", "2010…
## $ tvivparhab <chr> "28607568", "64241", "39979", "290777", "802", "561", "2020…
## $ vivpar_des <chr> "4997806", "17696", "11781", "56875", "299", "149", "36893"…
## $ vivpar_ut <chr> "2012350", "21875", "11850", "13924", "198", "56", "8758", …
## $ ocupvivpar <chr> "110610075", "231430", "153907", "1178123", "3349", "2366",…
## $ prom_ocup <chr> "3.93", "*", "*", "4.07", "*", "*", "3.94", "3.90", "*", "3…
## $ pro_ocup_c <chr> "1.06", "*", "*", "0.96", "*", "*", "0.89", "0.87", "*", "0…
## $ vph_pisodt <chr> "26224791", "49413", "28677", "284121", "747", "522", "1980…
## $ vph_pisoti <chr> "1731414", "13552", "10604", "4802", "51", "30", "2596", "1…
## $ vph_1dor <chr> "9929668", "32183", "20167", "71256", "300", "238", "44360"…
## $ vph_2ymasd <chr> "18079707", "30850", "19111", "217742", "498", "313", "1563…
## $ vph_1cuart <chr> "2036147", "7332", "4755", "7006", "43", "40", "3495", "264…
## $ vph_2cuart <chr> "4768838", "17504", "11457", "25342", "150", "134", "13433"…
## $ vph_3ymasc <chr> "21172227", "38137", "23030", "256273", "603", "375", "1834…
## $ vph_c_elec <chr> "27515030", "40662", "25785", "287266", "659", "477", "2001…
## $ vph_s_elec <chr> "513482", "22243", "13460", "1923", "139", "76", "668", "29…
## $ vph_aguadv <chr> "24808420", "20538", "13432", "283042", "514", "356", "1975…
## $ vph_aguafv <chr> "3174979", "42258", "25732", "5840", "283", "194", "3097", …
## $ vph_excsa <chr> "26848166", "47803", "27893", "284565", "664", "458", "1993…
## $ vph_drenaj <chr> "25410351", "36996", "21226", "283977", "614", "429", "1986…
## $ vph_nodren <chr> "2523821", "25263", "17581", "4795", "181", "121", "1922", …
## $ vph_c_serv <chr> "23207764", "14359", "8980", "278631", "414", "279", "19588…
## $ vph_snbien <chr> "782716", "8196", "6127", "1300", "26", "25", "500", "367",…
## $ vph_radio <chr> "22373499", "43368", "26213", "256790", "658", "445", "1824…
## $ vph_tv <chr> "26048531", "38574", "23519", "282484", "676", "475", "1974…
## $ vph_refri <chr> "23091296", "29064", "17793", "264623", "537", "382", "1882…
## $ vph_lavad <chr> "18692852", "19361", "12413", "238954", "449", "325", "1706…
## $ vph_autom <chr> "12429083", "27168", "15497", "171795", "477", "293", "1244…
## $ vph_pc <chr> "8279619", "3435", "2193", "99579", "97", "59", "81576", "7…
## $ vph_telef <chr> "12161965", "3973", "2530", "137911", "48", "44", "109090",…
## $ vph_cel <chr> "18318374", "30417", "16841", "208209", "511", "357", "1576…
## $ vph_inter <chr> "6004315", "1418", "940", "66075", "36", "19", "56788", "55…
## $ tam_loc <dbl> NA, NA, NA, NA, NA, NA, NA, 13, 1, 1, 1, 1, 1, 4, 1, 3, 3, …
glimpse(iter_2020)
## Rows: 195,662
## Columns: 286
## $ ENTIDAD <chr> "00", "00", "00", "01", "01", "01", "01", "01", "01", "01"…
## $ NOM_ENT <chr> "Total nacional", "Total nacional", "Total nacional", "Agu…
## $ MUN <chr> "000", "000", "000", "000", "000", "000", "001", "001", "0…
## $ NOM_MUN <chr> "Total nacional", "Total nacional", "Total nacional", "Tot…
## $ LOC <chr> "0000", "9998", "9999", "0000", "9998", "9999", "0000", "0…
## $ NOM_LOC <chr> "Total nacional", "Localidades de una vivienda", "Localida…
## $ LONGITUD <chr> NA, NA, NA, NA, NA, NA, NA, "102°17'45.768\" W", "102°22'2…
## $ LATITUD <chr> NA, NA, NA, NA, NA, NA, NA, "21°52'47.362\" N", "21°52'18.…
## $ ALTITUD <chr> NA, NA, NA, NA, NA, NA, NA, "1878", "1902", "1861", "1861"…
## $ POBTOT <dbl> 126014024, 250354, 147125, 1425607, 3697, 3021, 948990, 86…
## $ POBFEM <chr> "64540634", "96869", "61324", "728924", "1510", "1013", "4…
## $ POBMAS <chr> "61473390", "153485", "85801", "696683", "2187", "2008", "…
## $ P_0A2 <chr> "5764054", "10493", "6798", "71864", "165", "119", "44372"…
## $ P_0A2_F <chr> "2848875", "5193", "3407", "35604", "81", "54", "21893", "…
## $ P_0A2_M <chr> "2915179", "5300", "3391", "36260", "84", "65", "22479", "…
## $ P_3YMAS <chr> "119976584", "239441", "139757", "1352235", "3532", "2902"…
## $ P_3YMAS_F <chr> "61554567", "91463", "57628", "692561", "1429", "959", "46…
## $ P_3YMAS_M <chr> "58422017", "147978", "82129", "659674", "2103", "1943", "…
## $ P_5YMAS <chr> "115693273", "232086", "135028", "1299669", "3420", "2829"…
## $ P_5YMAS_F <chr> "59433559", "87931", "55256", "666713", "1377", "925", "44…
## $ P_5YMAS_M <chr> "56259714", "144155", "79772", "632956", "2043", "1904", "…
## $ P_12YMAS <chr> "100528155", "207748", "119223", "1116719", "3018", "2553"…
## $ P_12YMAS_F <chr> "51962264", "76111", "47543", "576593", "1179", "798", "39…
## $ P_12YMAS_M <chr> "48565891", "131637", "71680", "540126", "1839", "1755", "…
## $ P_15YMAS <chr> "93985354", "197411", "111530", "1038904", "2836", "2444",…
## $ P_15YMAS_F <chr> "48732991", "71344", "44275", "538387", "1086", "740", "36…
## $ P_15YMAS_M <chr> "45252363", "126067", "67255", "500517", "1750", "1704", "…
## $ P_18YMAS <chr> "87492680", "186968", "104612", "960764", "2609", "2341", …
## $ P_18YMAS_F <chr> "45530857", "66514", "41184", "500089", "987", "699", "343…
## $ P_18YMAS_M <chr> "41961823", "120454", "63428", "460675", "1622", "1642", "…
## $ P_3A5 <chr> "6462212", "10900", "7028", "78833", "169", "113", "48767"…
## $ P_3A5_F <chr> "3193548", "5270", "3511", "38679", "80", "47", "23951", "…
## $ P_3A5_M <chr> "3268664", "5630", "3517", "40154", "89", "66", "24816", "…
## $ P_6A11 <chr> "12986217", "20793", "13506", "156683", "345", "236", "979…
## $ P_6A11_F <chr> "6398755", "10082", "6574", "77289", "170", "114", "48353"…
## $ P_6A11_M <chr> "6587462", "10711", "6932", "79394", "175", "122", "49594"…
## $ P_8A14 <chr> "15287375", "24342", "16724", "181905", "427", "262", "114…
## $ P_8A14_F <chr> "7531118", "11538", "7679", "89383", "211", "133", "56248"…
## $ P_8A14_M <chr> "7756257", "12804", "9045", "92522", "216", "129", "58303"…
## $ P_12A14 <chr> "6542801", "10337", "7693", "77815", "182", "109", "49497"…
## $ P_12A14_F <chr> "3229273", "4767", "3268", "38206", "93", "58", "24224", "…
## $ P_12A14_M <chr> "3313528", "5570", "4425", "39609", "89", "51", "25273", "…
## $ P_15A17 <chr> "6492674", "10443", "6918", "78140", "227", "103", "49934"…
## $ P_15A17_F <chr> "3202134", "4830", "3091", "38298", "99", "41", "24477", "…
## $ P_15A17_M <chr> "3290540", "5613", "3827", "39842", "128", "62", "25457", …
## $ P_18A24 <chr> "14736111", "27841", "16336", "180847", "438", "439", "120…
## $ P_18A24_F <chr> "7398617", "11140", "6760", "90632", "180", "123", "60159"…
## $ P_18A24_M <chr> "7337494", "16701", "9576", "90215", "258", "316", "60293"…
## $ P_15A49_F <chr> "33885546", "47693", "29297", "388917", "750", "531", "260…
## $ P_60YMAS <chr> "15142976", "37383", "21277", "145376", "448", "281", "102…
## $ P_60YMAS_F <chr> "8139094", "13442", "8916", "78703", "190", "116", "56724"…
## $ P_60YMAS_M <chr> "7003882", "23941", "12361", "66673", "258", "165", "46263…
## $ REL_H_M <chr> "95.25", "158.45", "139.91", "95.58", "144.83", "198.22", …
## $ POB0_14 <chr> "31755284", "52523", "35025", "385195", "861", "577", "240…
## $ POB15_64 <chr> "83663440", "171209", "96250", "941834", "2524", "2241", "…
## $ POB65_MAS <chr> "10321914", "26202", "15280", "97070", "312", "203", "6794…
## $ P_0A4 <chr> "10047365", "17848", "11527", "124430", "277", "192", "768…
## $ P_0A4_F <chr> "4969883", "8725", "5779", "61452", "133", "88", "37897", …
## $ P_0A4_M <chr> "5077482", "9123", "5748", "62978", "144", "104", "38966",…
## $ P_5A9 <chr> "10764379", "17380", "11274", "131048", "281", "199", "817…
## $ P_5A9_F <chr> "5311288", "8526", "5558", "64689", "142", "88", "40366", …
## $ P_5A9_M <chr> "5453091", "8854", "5716", "66359", "139", "111", "41347",…
## $ P_10A14 <chr> "10943540", "17295", "12224", "129717", "303", "186", "820…
## $ P_10A14_F <chr> "5389280", "8061", "5423", "63637", "149", "97", "40158", …
## $ P_10A14_M <chr> "5554260", "9234", "6801", "66080", "154", "89", "41849", …
## $ P_15A19 <chr> "10806690", "18303", "11484", "131967", "348", "201", "851…
## $ P_15A19_F <chr> "5344540", "8138", "5140", "65064", "148", "75", "41939", …
## $ P_15A19_M <chr> "5462150", "10165", "6344", "66903", "200", "126", "43222"…
## $ P_20A24 <chr> "10422095", "19981", "11770", "127020", "317", "341", "852…
## $ P_20A24_F <chr> "5256211", "7832", "4711", "63866", "131", "89", "42697", …
## $ P_20A24_M <chr> "5165884", "12149", "7059", "63154", "186", "252", "42528"…
## $ P_25A29 <chr> "9993001", "20584", "12238", "118426", "300", "367", "8007…
## $ P_25A29_F <chr> "5131597", "7125", "4427", "60285", "109", "87", "40446", …
## $ P_25A29_M <chr> "4861404", "13459", "7811", "58141", "191", "280", "39631"…
## $ P_30A34 <chr> "9420827", "19601", "11315", "106825", "280", "346", "7185…
## $ P_30A34_F <chr> "4893101", "6309", "4074", "55174", "89", "87", "36831", "…
## $ P_30A34_M <chr> "4527726", "13292", "7241", "51651", "191", "259", "35019"…
## $ P_35A39 <chr> "9020276", "18645", "10357", "99257", "272", "275", "66892…
## $ P_35A39_F <chr> "4688746", "6289", "3825", "51483", "85", "80", "34639", "…
## $ P_35A39_M <chr> "4331530", "12356", "6532", "47774", "187", "195", "32253"…
## $ P_40A44 <chr> "8503586", "17934", "9705", "92378", "259", "223", "62159"…
## $ P_40A44_F <chr> "4441282", "6060", "3743", "48539", "103", "64", "32704", …
## $ P_40A44_M <chr> "4062304", "11874", "5962", "43839", "156", "159", "29455"…
## $ P_45A49 <chr> "7942413", "16840", "8668", "84669", "238", "170", "58264"…
## $ P_45A49_F <chr> "4130069", "5940", "3377", "44506", "85", "49", "31021", "…
## $ P_45A49_M <chr> "3812344", "10900", "5291", "40163", "153", "121", "27243"…
## $ P_50A54 <chr> "7037532", "15070", "7878", "74121", "177", "137", "52400"…
## $ P_50A54_F <chr> "3705369", "5481", "3239", "39510", "72", "52", "28200", "…
## $ P_50A54_M <chr> "3332163", "9589", "4639", "34611", "105", "85", "24200", …
## $ P_55A59 <chr> "5695958", "13070", "6838", "58865", "197", "103", "42458"…
## $ P_55A59_F <chr> "3002982", "4728", "2823", "31257", "74", "41", "22827", "…
## $ P_55A59_M <chr> "2692976", "8342", "4015", "27608", "123", "62", "19631", …
## $ P_60A64 <chr> "4821062", "11181", "5997", "48306", "136", "78", "35046",…
## $ P_60A64_F <chr> "2563200", "4050", "2511", "25871", "54", "34", "18957", "…
## $ P_60A64_M <chr> "2257862", "7131", "3486", "22435", "82", "44", "16089", "…
## $ P_65A69 <chr> "3645077", "9160", "5052", "35823", "106", "87", "25677", …
## $ P_65A69_F <chr> "1938227", "3343", "2130", "19125", "44", "33", "13907", "…
## $ P_65A69_M <chr> "1706850", "5817", "2922", "16698", "62", "54", "11770", "…
## $ P_70A74 <chr> "2647340", "6903", "3852", "25586", "78", "49", "18157", "…
## $ P_70A74_F <chr> "1413848", "2421", "1575", "13804", "35", "21", "9980", "9…
## $ P_70A74_M <chr> "1233492", "4482", "2277", "11782", "43", "28", "8177", "7…
## $ P_75A79 <chr> "1814582", "4765", "2920", "16581", "58", "38", "11458", "…
## $ P_75A79_F <chr> "966684", "1639", "1182", "8842", "26", "14", "6228", "584…
## $ P_75A79_M <chr> "847898", "3126", "1738", "7739", "32", "24", "5230", "477…
## $ P_80A84 <chr> "1175364", "3017", "1868", "10186", "38", "18", "6872", "6…
## $ P_80A84_F <chr> "651552", "1081", "793", "5789", "19", "7", "4055", "3819"…
## $ P_80A84_M <chr> "523812", "1936", "1075", "4397", "19", "11", "2817", "256…
## $ P_85YMAS <chr> "1039551", "2357", "1588", "8894", "32", "11", "5777", "53…
## $ P_85YMAS_F <chr> "605583", "908", "725", "5272", "12", "7", "3597", "3373",…
## $ P_85YMAS_M <chr> "433968", "1449", "863", "3622", "20", "4", "2180", "1973"…
## $ PROM_HNV <chr> "2.09", "*", "*", "2.11", "*", "*", "1.98", "1.95", "*", "…
## $ PNACENT <chr> "102724322", "177757", "117805", "1133247", "2908", "2370"…
## $ PNACENT_F <chr> "52519974", "75977", "52686", "576781", "1216", "811", "36…
## $ PNACENT_M <chr> "50204348", "101780", "65119", "556466", "1692", "1559", "…
## $ PNACOE <chr> "21611963", "54046", "20274", "276430", "749", "616", "214…
## $ PNACOE_F <chr> "11222300", "18910", "7205", "144420", "275", "198", "1128…
## $ PNACOE_M <chr> "10389663", "35136", "13069", "132010", "474", "418", "102…
## $ PRES2015 <chr> "111075594", "184423", "114178", "1232234", "2721", "1638"…
## $ PRES2015_F <chr> "57288776", "79893", "52604", "635320", "1298", "779", "42…
## $ PRES2015_M <chr> "53786818", "104530", "61574", "596914", "1423", "859", "3…
## $ PRESOE15 <chr> "3807844", "16172", "6214", "56422", "152", "77", "42481",…
## $ PRESOE15_F <chr> "1889986", "6089", "1664", "27956", "69", "36", "21032", "…
## $ PRESOE15_M <chr> "1917858", "10083", "4550", "28466", "83", "41", "21449", …
## $ P3YM_HLI <chr> "7364645", "26486", "18640", "2539", "20", "14", "1839", "…
## $ P3YM_HLI_F <chr> "3783447", "10908", "8181", "1043", "3", "3", "754", "704"…
## $ P3YM_HLI_M <chr> "3581198", "15578", "10459", "1496", "17", "11", "1085", "…
## $ P3HLINHE <chr> "865972", "2712", "3098", "25", "0", "0", "8", "6", "*", "…
## $ P3HLINHE_F <chr> "547528", "1652", "1901", "13", "0", "0", "4", "4", "*", "…
## $ P3HLINHE_M <chr> "318444", "1060", "1197", "12", "0", "0", "4", "2", "*", "…
## $ P3HLI_HE <chr> "6423548", "22906", "14758", "2461", "15", "6", "1792", "1…
## $ P3HLI_HE_F <chr> "3198595", "9203", "6205", "1012", "3", "3", "737", "688",…
## $ P3HLI_HE_M <chr> "3224953", "13703", "8553", "1449", "12", "3", "1055", "99…
## $ P5_HLI <chr> "7177185", "25743", "17992", "2508", "20", "14", "1822", "…
## $ P5_HLI_NHE <chr> "785361", "2412", "2742", "22", "0", "0", "8", "6", "*", "…
## $ P5_HLI_HE <chr> "6317027", "22464", "14467", "2437", "15", "6", "1776", "1…
## $ PHOG_IND <chr> "11800247", "27252", "21531", "5552", "5", "7", "4050", "3…
## $ POB_AFRO <chr> "2576213", "4122", "2816", "22425", "52", "32", "15170", "…
## $ POB_AFRO_F <chr> "1297617", "1614", "1056", "11211", "20", "11", "7560", "7…
## $ POB_AFRO_M <chr> "1278596", "2508", "1760", "11214", "32", "21", "7610", "7…
## $ PCON_DISC <chr> "6179890", "12126", "8058", "71294", "212", "123", "47525"…
## $ PCDISC_MOT <chr> "2939986", "5875", "4079", "34507", "110", "67", "23117", …
## $ PCDISC_VIS <chr> "2691338", "5008", "3590", "29888", "69", "35", "20047", "…
## $ PCDISC_LENG <chr> "945162", "1940", "1664", "9297", "18", "7", "5894", "5317…
## $ PCDISC_AUD <chr> "1350802", "2895", "2295", "12989", "39", "27", "8636", "7…
## $ PCDISC_MOT2 <chr> "1168098", "2123", "1808", "12726", "38", "13", "8226", "7…
## $ PCDISC_MEN <chr> "1149257", "2179", "1825", "12967", "27", "12", "8618", "7…
## $ PCON_LIMI <chr> "13934448", "28067", "16685", "165482", "418", "290", "116…
## $ PCLIM_CSB <chr> "4365234", "10653", "6309", "49636", "161", "109", "34873"…
## $ PCLIM_VIS <chr> "8974853", "17059", "10523", "103289", "226", "159", "7366…
## $ PCLIM_HACO <chr> "864662", "2092", "1279", "8940", "30", "16", "5980", "539…
## $ PCLIM_OAUD <chr> "2900108", "6916", "3982", "30298", "75", "53", "21547", "…
## $ PCLIM_MOT2 <chr> "673540", "1625", "1085", "6368", "24", "13", "4413", "399…
## $ PCLIM_RE_CO <chr> "2698640", "5763", "3479", "34556", "95", "62", "24523", "…
## $ PCLIM_PMEN <chr> "1590583", "2823", "1579", "20169", "56", "31", "13945", "…
## $ PSIND_LIM <chr> "104815785", "207052", "120888", "1177938", "3044", "2590"…
## $ P3A5_NOA <chr> "2359716", "5620", "3783", "31495", "84", "57", "18639", "…
## $ P3A5_NOA_F <chr> "1155636", "2689", "1873", "15371", "36", "26", "9130", "8…
## $ P3A5_NOA_M <chr> "1204080", "2931", "1910", "16124", "48", "31", "9509", "8…
## $ P6A11_NOA <chr> "577029", "2920", "1782", "4941", "25", "6", "2877", "2525…
## $ P6A11_NOAF <chr> "275189", "1403", "874", "2292", "17", "3", "1360", "1183"…
## $ P6A11_NOAM <chr> "301840", "1517", "908", "2649", "8", "3", "1517", "1342",…
## $ P12A14NOA <chr> "618233", "2699", "1674", "6812", "34", "13", "3907", "341…
## $ P12A14NOAF <chr> "283195", "1190", "766", "2901", "16", "7", "1671", "1467"…
## $ P12A14NOAM <chr> "335038", "1509", "908", "3911", "18", "6", "2236", "1948"…
## $ P15A17A <chr> "4726359", "4952", "3557", "55493", "133", "56", "36490", …
## $ P15A17A_F <chr> "2390407", "2386", "1509", "28286", "53", "22", "18550", "…
## $ P15A17A_M <chr> "2335952", "2566", "2048", "27207", "80", "34", "17940", "…
## $ P18A24A <chr> "4894125", "4157", "2738", "59978", "93", "77", "44885", "…
## $ P18A24A_F <chr> "2482980", "1610", "1053", "31114", "33", "23", "23031", "…
## $ P18A24A_M <chr> "2411145", "2547", "1685", "28864", "60", "54", "21854", "…
## $ P8A14AN <chr> "412725", "2393", "1527", "3178", "19", "7", "1851", "1609…
## $ P8A14AN_F <chr> "178152", "1080", "712", "1318", "10", "4", "772", "683", …
## $ P8A14AN_M <chr> "234573", "1313", "815", "1860", "9", "3", "1079", "926", …
## $ P15YM_AN <chr> "4456431", "24331", "15092", "21908", "180", "113", "11618…
## $ P15YM_AN_F <chr> "2677192", "10532", "7074", "11762", "78", "41", "6599", "…
## $ P15YM_AN_M <chr> "1779239", "13799", "8018", "10146", "102", "72", "5019", …
## $ P15YM_SE <chr> "4841952", "28014", "17660", "25567", "209", "119", "14576…
## $ P15YM_SE_F <chr> "2791237", "11278", "7476", "13286", "79", "43", "7917", "…
## $ P15YM_SE_M <chr> "2050715", "16736", "10184", "12281", "130", "76", "6659",…
## $ P15PRI_IN <chr> "7731820", "38545", "21620", "65609", "378", "301", "33308…
## $ P15PRI_INF <chr> "4042527", "13056", "8064", "33542", "152", "86", "18056",…
## $ P15PRI_INM <chr> "3689293", "25489", "13556", "32067", "226", "215", "15252…
## $ P15PRI_CO <chr> "12325433", "38809", "22033", "122405", "470", "409", "762…
## $ P15PRI_COF <chr> "6515268", "14762", "9009", "64730", "207", "132", "41402"…
## $ P15PRI_COM <chr> "5810165", "24047", "13024", "57675", "263", "277", "34854…
## $ P15SEC_IN <chr> "2913915", "14833", "5040", "30347", "157", "145", "19144"…
## $ P15SEC_INF <chr> "1297269", "3143", "1561", "12806", "37", "27", "8184", "7…
## $ P15SEC_INM <chr> "1616646", "11690", "3479", "17541", "120", "118", "10960"…
## $ P15SEC_CO <chr> "22833912", "40180", "24056", "288036", "832", "807", "182…
## $ P15SEC_COF <chr> "11857736", "15578", "9485", "151759", "291", "220", "9543…
## $ P15SEC_COM <chr> "10976176", "24602", "14571", "136277", "541", "587", "871…
## $ P18YM_PB <chr> "39977750", "33907", "19102", "467249", "722", "617", "354…
## $ P18YM_PB_F <chr> "20408275", "11972", "7672", "240419", "289", "211", "1818…
## $ P18YM_PB_M <chr> "19569475", "21935", "11430", "226830", "433", "406", "172…
## $ GRAPROES <chr> "9.74", "6.5", "6.45", "10.35", "8.14", "8.37", "10.84", "…
## $ GRAPROES_F <chr> "9.64", "6.51", "6.48", "10.32", "8.2", "8.53", "10.75", "…
## $ GRAPROES_M <chr> "9.84", "6.5", "6.43", "10.38", "8.11", "8.3", "10.93", "1…
## $ PEA <chr> "62281634", "128289", "68904", "706930", "2077", "1748", "…
## $ PEA_F <chr> "25465693", "33067", "18475", "293533", "506", "363", "208…
## $ PEA_M <chr> "36815941", "95222", "50429", "413397", "1571", "1385", "2…
## $ PE_INAC <chr> "37891261", "68766", "46162", "407903", "939", "801", "269…
## $ PE_INAC_F <chr> "26379060", "42827", "28959", "282320", "673", "435", "182…
## $ PE_INAC_M <chr> "11512201", "25939", "17203", "125583", "266", "366", "862…
## $ POCUPADA <chr> "61121324", "127469", "68215", "692983", "2060", "1741", "…
## $ POCUPADA_F <chr> "25137019", "32906", "18365", "289268", "497", "361", "205…
## $ POCUPADA_M <chr> "35984305", "94563", "49850", "403715", "1563", "1380", "2…
## $ PDESOCUP <chr> "1160310", "820", "689", "13947", "17", "7", "10173", "949…
## $ PDESOCUP_F <chr> "328674", "161", "110", "4265", "9", "2", "3386", "3224", …
## $ PDESOCUP_M <chr> "831636", "659", "579", "9682", "8", "5", "6787", "6274", …
## $ PSINDER <chr> "32999713", "86676", "56232", "262088", "1067", "1289", "1…
## $ PDER_SS <chr> "92582812", "153663", "90057", "1161139", "2472", "1730", …
## $ PDER_IMSS <chr> "47245909", "53559", "23569", "780525", "1090", "828", "57…
## $ PDER_ISTE <chr> "7165164", "3795", "2312", "92771", "113", "87", "65237", …
## $ PDER_ISTEE <chr> "1041534", "552", "350", "3786", "4", "9", "2352", "2243",…
## $ PAFIL_PDOM <chr> "1192255", "649", "485", "3196", "0", "1", "2563", "2494",…
## $ PDER_SEGP <chr> "32842765", "84849", "59445", "271996", "1242", "775", "12…
## $ PDER_IMSSB <chr> "958787", "2883", "1956", "1680", "2", "1", "1064", "969",…
## $ PAFIL_IPRIV <chr> "2615213", "3288", "1300", "31789", "31", "20", "25703", "…
## $ PAFIL_OTRAI <chr> "1149542", "6284", "1504", "3179", "13", "25", "2346", "21…
## $ P12YM_SOLT <chr> "34370381", "63913", "38355", "402370", "1037", "787", "27…
## $ P12YM_CASA <chr> "54036478", "124916", "68874", "593273", "1695", "1454", "…
## $ P12YM_SEPA <chr> "12049313", "18433", "10660", "120740", "285", "312", "873…
## $ PCATOLICA <chr> "97864218", "187464", "112351", "1272419", "3250", "2732",…
## $ PRO_CRIEVA <chr> "14095307", "29725", "16630", "73359", "223", "95", "55328…
## $ POTRAS_REL <chr> "248169", "1117", "675", "1900", "11", "22", "1539", "1457…
## $ PSIN_RELIG <chr> "13314516", "29624", "16432", "74439", "195", "169", "5853…
## $ TOTHOG <chr> "35219141", "62516", "36568", "386445", "807", "516", "266…
## $ HOGJEF_F <chr> "11474983", "8292", "6620", "119453", "123", "100", "85732…
## $ HOGJEF_M <chr> "23744158", "54224", "29948", "266992", "684", "416", "181…
## $ POBHOG <chr> "125514839", "198544", "125099", "1421200", "3137", "1918"…
## $ PHOGJEF_F <chr> "37418569", "28805", "21860", "395735", "532", "385", "273…
## $ PHOGJEF_M <chr> "88096270", "169739", "103239", "1025465", "2605", "1533",…
## $ VIVTOT <dbl> 43903443, 101390, 61435, 463972, 1368, 869, 313256, 286646…
## $ TVIVHAB <dbl> 35233462, 62767, 36676, 386671, 813, 518, 266942, 246259, …
## $ TVIVPAR <chr> "42300700", "99591", "60317", "453099", "1354", "858", "30…
## $ VIVPAR_HAB <chr> "33630719", "60968", "35558", "375798", "799", "507", "257…
## $ VIVPARH_CV <chr> "35156897", "62091", "36359", "386011", "801", "516", "266…
## $ TVIVPARHAB <chr> "35219141", "62516", "36568", "386445", "807", "516", "266…
## $ VIVPAR_DES <chr> "6155682", "18117", "12225", "60327", "233", "164", "37113…
## $ VIVPAR_UT <chr> "2514299", "20506", "12534", "16974", "322", "187", "9201"…
## $ OCUPVIVPAR <chr> "125514839", "198544", "125099", "1421200", "3137", "1918"…
## $ PROM_OCUP <chr> "3.56", "3.18", "3.42", "3.68", "3.89", "3.72", "3.54", "3…
## $ PRO_OCUP_C <chr> "0.96", "1.03", "1.03", "0.89", "1.02", "1.03", "0.84", "0…
## $ VPH_PISODT <chr> "33833470", "53169", "29302", "382634", "771", "499", "264…
## $ VPH_PISOTI <chr> "1235550", "8797", "6891", "2899", "30", "17", "1530", "10…
## $ VPH_1DOR <chr> "11186214", "30115", "17038", "86423", "270", "175", "5543…
## $ VPH_2YMASD <chr> "23887498", "31851", "19157", "299141", "531", "341", "210…
## $ VPH_1CUART <chr> "2085925", "7333", "4351", "6390", "39", "27", "3185", "24…
## $ VPH_2CUART <chr> "5460133", "16206", "9491", "30686", "116", "85", "17449",…
## $ VPH_3YMASC <chr> "27527131", "38424", "22351", "348487", "646", "404", "245…
## $ VPH_C_ELEC <chr> "34805976", "48426", "28586", "384361", "723", "477", "265…
## $ VPH_S_ELEC <chr> "268863", "13538", "7607", "1210", "78", "39", "438", "300…
## $ VPH_AGUADV <chr> "33858339", "45470", "26499", "383430", "694", "463", "265…
## $ VPH_AEASP <chr> "29541708", "8198", "5054", "355192", "195", "136", "25415…
## $ VPH_AGUAFV <chr> "1215497", "16498", "9696", "2137", "107", "53", "989", "3…
## $ VPH_TINACO <chr> "22629812", "34143", "18089", "295903", "608", "361", "199…
## $ VPH_CISTER <chr> "9652823", "13743", "7029", "152521", "405", "241", "12280…
## $ VPH_EXCSA <chr> "33081729", "44688", "24348", "382597", "708", "455", "265…
## $ VPH_LETR <chr> "1396774", "9825", "6050", "1011", "27", "19", "520", "60"…
## $ VPH_DRENAJ <chr> "33564054", "47253", "26036", "383148", "719", "459", "265…
## $ VPH_NODREN <chr> "1498766", "14708", "10155", "2379", "82", "57", "798", "1…
## $ VPH_C_SERV <chr> "32671764", "35091", "19807", "380982", "610", "418", "264…
## $ VPH_NDEAED <chr> "79584", "4842", "2935", "184", "16", "10", "53", "19", "*…
## $ VPH_DSADMA <chr> "32979844", "43668", "23841", "382121", "704", "445", "264…
## $ VPH_NDACMM <chr> "16874580", "24373", "16122", "130744", "203", "119", "883…
## $ VPH_SNBIEN <chr> "581095", "5136", "4115", "876", "12", "8", "380", "313", …
## $ VPH_REFRI <chr> "30811260", "38199", "21775", "365189", "632", "436", "254…
## $ VPH_LAVAD <chr> "25610544", "26412", "15880", "335710", "561", "377", "234…
## $ VPH_HMICRO <chr> "16651199", "13608", "7902", "238571", "276", "218", "1760…
## $ VPH_AUTOM <chr> "16340788", "30940", "16699", "240381", "529", "343", "169…
## $ VPH_MOTO <chr> "4227460", "15001", "8076", "45642", "216", "143", "26624"…
## $ VPH_BICI <chr> "7469168", "13600", "6330", "105752", "407", "241", "54393…
## $ VPH_RADIO <chr> "23772973", "36738", "20009", "312002", "650", "405", "221…
## $ VPH_TV <chr> "32031555", "40001", "23198", "370411", "684", "466", "257…
## $ VPH_PC <chr> "13204680", "5797", "3588", "177149", "167", "114", "13692…
## $ VPH_TELEF <chr> "13184550", "3523", "2177", "147818", "43", "37", "116647"…
## $ VPH_CEL <chr> "30775898", "47005", "25581", "359895", "732", "470", "251…
## $ VPH_INTER <chr> "18307193", "8385", "5027", "236003", "205", "146", "17861…
## $ VPH_STVP <chr> "15211306", "18981", "11306", "174089", "212", "156", "130…
## $ VPH_SPMVPI <chr> "6616141", "1732", "971", "98724", "48", "35", "80951", "7…
## $ VPH_CVJ <chr> "4047100", "1113", "708", "70126", "41", "38", "56131", "5…
## $ VPH_SINRTV <chr> "1788552", "12775", "8247", "6021", "39", "25", "3299", "2…
## $ VPH_SINLTC <chr> "3170894", "14143", "10065", "15323", "62", "44", "7293", …
## $ VPH_SINCINT <chr> "15108204", "51293", "29741", "128996", "530", "330", "742…
## $ VPH_SINTIC <chr> "852871", "7154", "5283", "1711", "20", "11", "731", "595"…
## $ TAMLOC <chr> "*", "*", "*", "*", "*", "*", "*", "13", "1", "1", "1", "1…
Los censos no hablan siempre el mismo idioma.
Cada año, el INEGI cambió ligeramente la forma de nombrar las columnas y
los valores que representan los totales
municipales.
Por eso, Tochtli debe armonizar los datos, creando un
lenguaje común entre los tres censos.
"TOTAL MUNICIPAL"."Total del Municipio".loc con valor
0, pero su nombre y formato varían.Así, Tochtli crea tres filtros diferentes, uno para cada año, asegurando que cada tabla contenga únicamente los totales municipales.
Luego añade dos elementos esenciales:
cve_mun, combinación de la clave de
entidad (ENTIDAD) y municipio (MUN), para
formar un identificador único de cinco dígitos.anio, que indica el año del censo al que
pertenece cada observación.iter_2010 <- clean_names(iter_2010)
iter_2020 <- clean_names(iter_2020)
Antes de empezar a construir indicadores, Tochtli se
detiene a observar los datos recién cargados.
Cada fila representa una historia, un hogar, una coordenada en el mapa
de Geotitlán.
Para explorar este territorio de números y palabras, usará una tabla
interactiva con la librería DT,
una herramienta que le permite recorrer los censos como si
caminara por un valle de datos.
“Observar es el primer paso del análisis —dice Tochtli—.
Los datos no se dominan: se escuchan, se leen, se sienten.”
💻 Código:
library(DT)
# 🧭 Tabla interactiva del Censo 2020
DT::datatable(
head(iter_2020, 100), # muestra las primeras 100 filas del censo
options = list(
pageLength = 10, # número de filas visibles por página
scrollX = TRUE # permite desplazamiento horizontal
),
caption = "🌾 Visualización interactiva de los primeros registros del Censo 2020 en Geotitlán"
)
Entre los códices del INEGI, Tochtli descubre un
pequeño enigma:
los censos no hablan siempre el mismo idioma.
A lo largo de los años, los escribas cambiaron las palabras y el orden
de las columnas,
haciendo que una misma idea —el total municipal—
aparezca con distintos nombres.
🪶 Por ejemplo: - En el Censo 2000,
el campo nom_loc usa el texto “TOTAL
MUNICIPAL” (en mayúsculas).
- En los Censos 2010 y 2020, aparece como
“Total del Municipio” (con mayúsculas y
minúsculas).
- En algunas tablas, incluso surge una columna loc con el
valor 0, pero su presencia y nombre varían.
Así que, para evitar que los datos se confundan entre sí,
Tochtli diseña tres filtros distintos, uno para cada
censo,
garantizando que solo se conserven los registros que representan el
total por municipio.
# ------------------------------------------------------------
# TOTALES MUNICIPALES POR AÑO (filtros específicos por nom_loc)
# ------------------------------------------------------------
library(dplyr)
library(janitor)
library(stringr)
# Utilidad pequeña: limpiar nombres y corregir posible BOM en la 1ª columna
prep_names <- function(df){
df <- janitor::clean_names(df)
names(df)[1] <- sub("^\ufeff", "", names(df)[1]) # quita BOM si aparece
df
}
# --- 2010: nom_loc == "Total del Municipio"
mun_2010 <- iter_2010 %>%
prep_names() %>%
filter(nom_loc == "Total del Municipio") %>% # filtro exacto
mutate(
entidad = suppressWarnings(as.integer(entidad)),
mun = suppressWarnings(as.integer(mun)),
cve_mun = paste0(sprintf("%02d", entidad), sprintf("%03d", mun)),
anio = 2010
)
# --- 2020: nom_loc == "Total del Municipio"
mun_2020 <- iter_2020 %>%
prep_names() %>%
filter(nom_loc == "Total del Municipio") %>% # filtro exacto
mutate(
entidad = suppressWarnings(as.integer(entidad)),
mun = suppressWarnings(as.integer(mun)),
cve_mun = paste0(sprintf("%02d", entidad), sprintf("%03d", mun)),
anio = 2020
)
# Contamos cuántos municipios hay en cada año
tabla_municipios <- bind_rows(
dplyr::count(mun_2010, anio),
dplyr::count(mun_2020, anio)
) %>%
arrange(anio) %>%
mutate(
incremento = n - lag(n), # diferencia con respecto al censo anterior
variacion_pct = round((incremento / lag(n)) * 100, 2) # cambio porcentual
)
# Mostramos la tabla resultante
tabla_municipios
## # A tibble: 2 × 4
## anio n incremento variacion_pct
## <dbl> <int> <int> <dbl>
## 1 2010 2456 NA NA
## 2 2020 2469 13 0.53
# ------------------------------------------------------------
# NORMALIZAR CLAVES Y CREAR cve_mun = ENTIDAD(2) + MUN(3)
# - Soluciona el problema de ceros a la izquierda (01, 003, etc.)
# - Limpia espacios y caracteres no numéricos
# ------------------------------------------------------------
library(dplyr)
library(stringr)
# Función para pad con ceros (robusta a num/char/factor y basura no numérica)
pad_code <- function(x, width){
v <- as.character(x) |>
str_trim() |>
str_replace_all("[^0-9]", "") |> # deja solo dígitos
suppressWarnings(as.integer()) # a entero (pierde ceros, está bien)
ifelse(is.na(v), NA_character_, stringr::str_pad(as.character(v), width, pad = "0"))
}
# Función para estandarizar y crear cve_mun en un df municipal
with_cve_mun <- function(df){
df %>%
mutate(
entidad = pad_code(entidad, 2), # "1" -> "01"
mun = pad_code(mun, 3), # "7" -> "007"
cve_mun = ifelse(is.na(entidad) | is.na(mun), NA_character_, paste0(entidad, mun))
)
}
# Aplicar a cada año
mun_2010 <- with_cve_mun(mun_2010)
mun_2020 <- with_cve_mun(mun_2020)
# ------------------------------------------------------------
# 🔑 Generar la clave municipal (cve_mun)
# ------------------------------------------------------------
# Ya tenemos las columnas 'entidad' y 'mun' estandarizadas.
# Ahora combinamos ambas para formar la clave municipal de 5 dígitos:
# Ejemplo: Aguascalientes (entidad = 01) + Aguascalientes (mun = 001) -> 01001
mun_2010 <- mun_2010 %>%
mutate(cve_mun = paste0(entidad, mun))
mun_2020 <- mun_2020 %>%
mutate(cve_mun = paste0(entidad, mun))
# Verificamos que las claves se hayan creado correctamente
mun_2010 %>% select(entidad, mun, cve_mun) %>% head()
## # A tibble: 6 × 3
## entidad mun cve_mun
## <chr> <chr> <chr>
## 1 01 001 01001
## 2 01 002 01002
## 3 01 003 01003
## 4 01 004 01004
## 5 01 005 01005
## 6 01 006 01006
mun_2020 %>% select(entidad, mun, cve_mun) %>% head()
## # A tibble: 6 × 3
## entidad mun cve_mun
## <chr> <chr> <chr>
## 1 01 001 01001
## 2 01 002 01002
## 3 01 003 01003
## 4 01 004 01004
## 5 01 005 01005
## 6 01 006 01006
En los valles de Geotitlán, Tochtli observa que los
códices del INEGI guardan una enorme sabiduría,
pero sus signos no siempre son fáciles de leer.
Cada censo está escrito con un estilo diferente: nombres cambiantes,
columnas dispersas, estructuras que se transforman con el tiempo.
Antes de convertir esos datos en mapas, Tochtli debe ordenar,
estandarizar y seleccionar las variables esenciales.
Solo entonces los datos se transformarán en indicadores
territoriales, capaces de revelar cómo crecen, envejecen y se
mueven los habitantes del valle.
Con paciencia y precisión, Tochtli toma las tablas del
ITER y selecciona las variables necesarias para darles
voz.
El objetivo es que los datos censales se conviertan en
cartografías vivas, donde podamos leer las
transformaciones del territorio:
sus procesos de crecimiento, envejecimiento y migración.
“Un indicador no es solo un número —dice Tochtli—.
Es una historia del territorio contada en lenguaje de datos.”
Mide la velocidad con la que crece la población en un periodo determinado.
\[ TCMA = \left( \frac{P_2}{P_1} \right)^{\frac{1}{t}} - 1 \]
📖 Interpretación:
Este indicador permite comparar el crecimiento relativo entre
municipios, independientemente de su tamaño.
En Geotitlán, Tochtli lo ve como la pulsación vital del
territorio, el ritmo con que cada municipio late y se
expande.
Expresa cuántas personas viven, en promedio, por kilómetro cuadrado.
\[ Densidad = \frac{Población \ total}{Superficie \ territorial} \]
📖 Interpretación:
La densidad muestra cómo se concentra la vida en el
territorio.
Tochtli la compara con las chinampas del valle: algunas rebosan de
actividad, otras se extienden en silencio.
Mide la proporción de personas mayores respecto a la población joven.
\[ Índice = \frac{P_{65+}}{P_{0-64}} \times 100 \]
📖 Interpretación:
Cuando este índice es alto, Tochtli dice que el territorio
cuenta sus historias con voces sabias y pausadas.
Cuando es bajo, el territorio canta con energía y
juventud.
Mide la proporción de población joven frente a la adulta.
\[ Índice = \frac{P_{0-14}}{P_{15+}} \times 100 \]
📖 Interpretación:
Refleja la estructura por edades de la población.
Junto con el índice de envejecimiento, Tochtli lo usa para
prever las necesidades sociales y educativas de cada
municipio.
> “En la pirámide de edades —dice— se esconden las semillas del
futuro.”
Mide la llegada de población proveniente de otras entidades en los últimos años.
\[ AM_{reciente} = \frac{Población \ residente \ en \ otra \ entidad}{Población \ total} \times 100 \]
📖 Interpretación:
Este indicador revela los caminos del movimiento
humano.
Tochtli lo interpreta como el pulso de los viajeros que llegan a
Geotitlán buscando nuevas raíces.
Evalúa la proporción de población nacida en otra entidad federativa.
\[ AM_{acumulada} = \frac{Población \ nacida \ en \ otra \ entidad}{Población \ total} \times 100 \]
📖 Interpretación:
Muestra el atractivo histórico de un municipio como
destino migratorio.
Cada cifra representa una historia de desplazamiento, adaptación y
encuentro.
Mide el porcentaje de población mayor de 12 años que participa en actividades económicas.
\[ Tasa_{actividad} = \frac{Población \ económicamente \ activa}{Población_{12+}} \times 100 \]
📖 Interpretación:
Indica la energía productiva del territorio.
Tochtli dice que aquí se ve cómo las manos y los oficios dan
forma al valle.
Compara la población dependiente (niños y adultos mayores) con la población en edad laboral.
\[ IDE = \frac{P_{0-14} + P_{65+}}{P_{15-64}} \times 100 \]
📖 Interpretación:
Un valor alto implica más personas que dependen de cada 100 en
edad laboral.
Para Tochtli, este equilibrio habla de solidaridad y
sostenibilidad: territorios que cuidan de muchos, pero deben
planear con cuidado su futuro.
Mide la proporción de población que vive en localidades urbanas respecto al total municipal.
📖 Interpretación:
Este indicador refleja el proceso de concentración
urbana.
Desde lo alto, Tlacolotl —el aguililla guardián— observa las luces de la
ciudad crecer,
mientras Tochtli analiza sus causas con código y paciencia.
💡 Reflexión final:
ese es el viaje de Tochtli por Geotitlán.
Porque los datos solo cobran sentido cuando nos ayudan a cuidar el territorio que habitamos.”
# ============================================================
# 🧩 SELECCIÓN, HOMOLOGACIÓN Y UNIÓN DE VARIABLES CENSALES
# ============================================================
# Objetivo: dejar un solo dataframe con las variables de 2010 y 2020
# comparables por municipio (cve_mun), incluyendo el nombre del municipio.
# ============================================================
library(dplyr)
library(janitor)
library(stringr)
library(tidyr)
# ------------------------------------------------------------
# 1️⃣ LIMPIAR NOMBRES DE COLUMNAS
# ------------------------------------------------------------
mun_2010 <- mun_2010 %>% clean_names()
mun_2020 <- mun_2020 %>% clean_names()
# ------------------------------------------------------------
# 2️⃣ SELECCIONAR VARIABLES CLAVE PARA 2010
# ------------------------------------------------------------
mun_2010_vars <- mun_2010 %>%
select(
cve_mun,
anio,
pob_total = pobtot, # población total
pob_12_mas = p_12ymas, # población de 12 años y más
pob_0_14 = pob0_14, # población de 0 a 14 años
pob_15_64 = pob15_64, # población de 15 a 64 años
pob_65_mas = pob65_mas, # población de 65 años y más
pob_nac_ot = pnacoe, # nacidos en otra entidad
pob_econ_act = pea # población económicamente activa
)
# ------------------------------------------------------------
# 3️⃣ SELECCIONAR VARIABLES CLAVE PARA 2020
# ------------------------------------------------------------
mun_2020_vars <- mun_2020 %>%
select(
cve_mun,
anio,
nom_ent,
nom_mun,
pob_total = pobtot, # población total (POBTOT)
pob_12_mas = p_12ymas, # población de 12 años y más
pob_15_mas = p_15ymas, # población de 15 años y más
pob_0_14 = pob0_14, # población de 0 a 14 años
pob_15_64 = pob15_64, # población de 15 a 64 años
pob_65_mas = pob65_mas, # población de 65 años y más
pob_nac_ot = pnacoe, # nacidos en otra entidad
pob_econ_act = pea # población económicamente activa
)
# ------------------------------------------------------------
# 4️⃣ RENOMBRAR VARIABLES CON SUFIJO DE AÑO (_10 y _20)
# ------------------------------------------------------------
mun_2010_wide <- mun_2010_vars %>%
rename_with(~ paste0(., "_10"), .cols = -cve_mun)
mun_2020_wide <- mun_2020_vars %>%
rename_with(~ paste0(., "_20"), .cols = -cve_mun)
# ------------------------------------------------------------
# 5️⃣ UNIR POR CLAVE MUNICIPAL (cve_mun)
# ------------------------------------------------------------
mun_10_20 <- full_join(mun_2010_wide, mun_2020_wide, by = "cve_mun")
# ------------------------------------------------------------
# 6️⃣ CHEQUEOS RÁPIDOS
# ------------------------------------------------------------
glimpse(mun_10_20)
## Rows: 2,469
## Columns: 20
## $ cve_mun <chr> "01001", "01002", "01003", "01004", "01005", "01006", …
## $ anio_10 <dbl> 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, …
## $ pob_total_10 <dbl> 797010, 45492, 54136, 15042, 99590, 41862, 49156, 8443…
## $ pob_12_mas_10 <chr> "602719", "32320", "39898", "10801", "69970", "30172",…
## $ pob_0_14_10 <chr> "238193", "16209", "17800", "5255", "35746", "14373", …
## $ pob_15_64_10 <chr> "515262", "26623", "32248", "8930", "59840", "25250", …
## $ pob_65_mas_10 <chr> "40309", "2627", "4034", "844", "3640", "2169", "2520"…
## $ pob_nac_ot_10 <chr> "186972", "5194", "6379", "1378", "16300", "4636", "37…
## $ pob_econ_act_10 <chr> "336974", "14319", "19310", "4819", "39315", "14892", …
## $ anio_20 <dbl> 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, …
## $ nom_ent_20 <chr> "Aguascalientes", "Aguascalientes", "Aguascalientes", …
## $ nom_mun_20 <chr> "Aguascalientes", "Asientos", "Calvillo", "Cosío", "Je…
## $ pob_total_20 <dbl> 948990, 51536, 58250, 17000, 129929, 47646, 57369, 955…
## $ pob_12_mas_20 <chr> "756970", "38399", "44778", "12820", "99250", "36250",…
## $ pob_15_mas_20 <chr> "707473", "35250", "41495", "11817", "91487", "33468",…
## $ pob_0_14_20 <chr> "240583", "16266", "16720", "5183", "38303", "14140", …
## $ pob_15_64_20 <chr> "639532", "31919", "35854", "10699", "84949", "30491",…
## $ pob_65_mas_20 <chr> "67941", "3331", "5641", "1118", "6538", "2977", "3579…
## $ pob_nac_ot_20 <chr> "214908", "6025", "6566", "1385", "23898", "4416", "49…
## $ pob_econ_act_20 <chr> "486675", "21440", "25976", "7010", "65839", "22097", …
# Municipios presentes solo en un año
missing_2010 <- mun_10_20 %>% filter(is.na(pob_total_10)) %>% nrow()
missing_2020 <- mun_10_20 %>% filter(is.na(pob_total_20)) %>% nrow()
cat("🟡 Municipios que aparecen en 2020 pero no en 2010:", missing_2010, "\n")
## 🟡 Municipios que aparecen en 2020 pero no en 2010: 13
cat("🟡 Municipios que aparecen en 2010 pero no en 2020:", missing_2020, "\n")
## 🟡 Municipios que aparecen en 2010 pero no en 2020: 0
# Vista rápida de las columnas principales
mun_10_20 %>%
select(cve_mun, nom_ent_20, nom_mun_20,
starts_with("pob_total"), starts_with("pob_econ_act")) %>%
head()
## # A tibble: 6 × 7
## cve_mun nom_ent_20 nom_mun_20 pob_total_10 pob_total_20 pob_econ_act_10
## <chr> <chr> <chr> <dbl> <dbl> <chr>
## 1 01001 Aguascalientes Aguascalient… 797010 948990 336974
## 2 01002 Aguascalientes Asientos 45492 51536 14319
## 3 01003 Aguascalientes Calvillo 54136 58250 19310
## 4 01004 Aguascalientes Cosío 15042 17000 4819
## 5 01005 Aguascalientes Jesús María 99590 129929 39315
## 6 01006 Aguascalientes Pabellón de … 41862 47646 14892
## # ℹ 1 more variable: pob_econ_act_20 <chr>
# ------------------------------------------------------------
# 📊 Vista interactiva con DT de columnas clave (2010 vs 2020)
# ------------------------------------------------------------
library(DT)
tabla_vista <- mun_10_20 %>%
select(
cve_mun, nom_ent_20, nom_mun_20,
pob_total_10, pob_total_20,
pob_econ_act_10, pob_econ_act_20
)
DT::datatable(
tabla_vista,
options = list(
pageLength = 10,
scrollX = TRUE,
autoWidth = TRUE,
language = list(url = '//cdn.datatables.net/plug-ins/1.13.1/i18n/es-ES.json')
),
filter = "top",
caption = "Comparativo municipal 2010 vs 2020 (población total y PEA)"
)
Mientras explora las tablas del Censo 2010 y del
Censo 2020,
Tochtli nota algo fascinante: el territorio no es
estático, también cambia y se reconfigura.
A veces, los municipios se dividen, se renombran o nacen de otros, como
brotes nuevos en el mapa de Geotitlán.
Para descubrirlos, Tochtli compara los códices del 2010 y 2020,
buscando aquellos lugares que: - 🌱 Sí tienen datos en
2020 (pob_total_20 no es NA),
- 🌾 Pero no aparecen en 2010
(pob_total_10 sí es NA).
Con esta comparación, obtiene una lista de municipios
nuevos creados o reconocidos oficialmente durante el periodo
2010–2020,
junto con su población y entidad correspondiente.
# ------------------------------------------------------------
# 🆕 DETECTAR NUEVOS MUNICIPIOS (presentes en 2020, ausentes en 2010)
# ------------------------------------------------------------
library(dplyr)
# Filtramos los municipios que existen en 2020 pero no en 2010
nuevos_municipios <- mun_10_20 %>%
filter(is.na(pob_total_10) & !is.na(pob_total_20)) %>%
select(cve_mun, nom_ent_20, nom_mun_20, pob_total_20)
# Mostramos los resultados
cat("Número de nuevos municipios en 2020:", nrow(nuevos_municipios), "\n")
## Número de nuevos municipios en 2020: 13
# Vista rápida
nuevos_municipios %>%
arrange(nom_ent_20, nom_mun_20) %>%
head(20)
## # A tibble: 13 × 4
## cve_mun nom_ent_20 nom_mun_20 pob_total_20
## <chr> <chr> <chr> <dbl>
## 1 02006 Baja California San Quintín 117568
## 2 04012 Campeche Seybaplaya 15297
## 3 07120 Chiapas Capitán Luis Ángel Vidal 4315
## 4 07122 Chiapas El Parral 15587
## 5 07123 Chiapas Emiliano Zapata 10783
## 6 07125 Chiapas Honduras de la Sierra 11650
## 7 07124 Chiapas Mezcalapa 23847
## 8 07121 Chiapas Rincón Chamula San Pedro 8718
## 9 17034 Morelos Coatetelco 11347
## 10 17036 Morelos Hueyapan 7855
## 11 17035 Morelos Xoxocotla 27805
## 12 23010 Quintana Roo Bacalar 41754
## 13 23011 Quintana Roo Puerto Morelos 26921
En los caminos de Geotitlán, Tochtli descubre que
los censos del INEGI son como códices antiguos:
repletos de información valiosa, pero escritos en lenguajes
cambiantes.
Cada edición guarda sus secretos —nombres distintos, estructuras
modificadas, nuevas variables—
y solo quien aprende a leerlos puede revelar las historias que el
territorio esconde.
Antes de mapear, Tochtli debe ordenar los datos, depurarlos y elegir
los campos que servirán para construir indicadores
territoriales,
aquellos que narran cómo crecen, envejecen y se mueven los pueblos del
valle.
Con paciencia de artesana, Tochtli toma los datos del
ITER
y selecciona las variables que darán vida a los mapas de
Geotitlán.
Cada tabla se transforma en una representación del espacio y del
tiempo,
un tejido de cifras que refleja la diversidad y el ritmo de cada
municipio.
“Un indicador —dice Tochtli— no es solo una fórmula.
Es una historia del territorio escrita con números.”
Mide la velocidad con que la población crece en un periodo determinado:
\[ TCMA = \left( \frac{P_2}{P_1} \right)^{\frac{1}{t}} - 1 \]
📖 Lectura en Geotitlán:
Cada municipio tiene su propio pulso.
La TCMA revela su latido demográfico: los que crecen rápido son fuegos
nuevos;
los que decrecen, ecos de antiguos asentamientos.
Expresa cuántas personas habitan, en promedio, por kilómetro cuadrado:
\[ Densidad = \frac{Población \ total}{Superficie \ territorial} \]
📖 Lectura en Geotitlán:
En los mapas de Tochtli, las zonas densas se iluminan como mercados
bulliciosos,
mientras las zonas dispersas respiran el silencio del campo.
Ambas son parte del equilibrio vital del territorio.
Mide la proporción de personas mayores respecto a la población joven:
\[ Índice = \frac{P_{65+}}{P_{0-64}} \times 100 \]
📖 Lectura:
Cuando el valor es alto, el territorio habla con voces sabias y
pausadas.
Cuando es bajo, predomina la energía del futuro.
Evalúa la proporción de población joven frente a la adulta:
\[ Índice = \frac{P_{0-14}}{P_{15+}} \times 100 \]
📖 Lectura:
Los municipios jóvenes son como campos recién sembrados:
prometen cosechas, pero necesitan cuidado y planificación.
Mide la llegada de población de otras entidades en los últimos años:
\[ A.M. \ Reciente = \frac{Población \ residente \ en \ otra \ entidad}{Población \ total} \times 100 \]
📖 Lectura:
Revela los caminos del movimiento humano.
Tochtli lo llama el pulso del viento, que trae nuevas raíces a
las tierras de Geotitlán.
Evalúa la proporción de personas nacidas en otra entidad:
\[ A.M. \ Acumulada = \frac{Población \ nacida \ en \ otra \ entidad}{Población \ total} \times 100 \]
📖 Lectura:
Cada cifra es una historia de desplazamiento.
Geotitlán crece con la memoria de quienes llegaron de lejos a
quedarse.
Mide el porcentaje de población mayor de 12 años que participa en actividades económicas:
\[ Tasa \ de \ actividad = \frac{Población \ económicamente \ activa}{Población_{12+}} \times 100 \]
📖 Lectura:
Aquí late la fuerza productiva del territorio:
manos, oficios y saberes que sostienen la vida cotidiana.
Compara la población dependiente (niños y mayores) con la población en edad laboral:
\[ Índice = \frac{P_{0-14} + P_{65+}}{P_{15-64}} \times 100 \]
📖 Lectura:
Un valor alto revela municipios solidarios pero presionados;
un valor bajo, territorios con estructura más estable.
Ambos enseñan lecciones sobre cómo se distribuye el esfuerzo
colectivo.
Mide la proporción de población que vive en localidades urbanas:
📖 Lectura:
El territorio urbano brilla con intensidad,
pero Tochtli recuerda que la ciudad también debe escuchar al campo que
la rodea.
El equilibrio entre ambos mundos es clave para la armonía de
Geotitlán.
Tochtli descubre que los censos del 2000, 2010 y 2020 usan palabras
distintas para nombrar las mismas cosas.
Por eso, antes de combinarlos, debe homologar los
nombres para que las fórmulas entiendan el mismo idioma.
| Concepto | 2010 | 2020 | Descripción |
|---|---|---|---|
| Población total | pobtot |
POBTOT |
Habitantes del municipio |
| Población de 0 a 14 años | pob0_14 |
POB0_14 |
Infancia |
| Población de 15 a 64 años | pob15_64 |
POB15_64 |
Edad laboral |
| Población 65 y más | pob65_mas |
POB65_MAS |
Personas mayores |
| Población nacida en otra entidad | pnacoe |
PNACOE |
Migración interna |
| Población económicamente activa | pea |
PEA |
Fuerza laboral |
“Cuando los datos hablan el mismo idioma —dice Tochtli—
el territorio puede contarse a sí mismo con claridad.”
Para unir los años 2010 y 2020, Tochtli usa la clave
municipal (cve_mun) como hilo conductor.
Primero renombra las columnas con sufijos _10 y
_20, luego las enlaza con full_join().
Así obtiene una gran tabla donde cada municipio muestra su evolución
a través del tiempo:
su población, su estructura por edades, su actividad económica y sus
flujos migratorios.
“En cada unión de tablas —dice Tochtli mientras observa el código correr—
los datos tejen la memoria del territorio.”
💡 Reflexión final:
> En Geotitlán, programar es también una forma de cuidar.
> Los indicadores no son solo estadísticas:
> son espejos del territorio, semillas de planeación y caminos de
conocimiento.
# ============================================================
# 🧩 SELECCIÓN, HOMOLOGACIÓN Y UNIÓN DE VARIABLES CENSALES
# ============================================================
# Objetivo: dejar un solo dataframe con las variables de 2010 y 2020
# comparables por municipio (cve_mun), incluyendo el nombre del municipio.
# ============================================================
library(dplyr)
library(janitor)
library(stringr)
library(tidyr)
# ------------------------------------------------------------
# 1️⃣ LIMPIAR NOMBRES DE COLUMNAS
# ------------------------------------------------------------
mun_2010 <- mun_2010 %>% clean_names()
mun_2020 <- mun_2020 %>% clean_names()
# ------------------------------------------------------------
# 2️⃣ SELECCIONAR VARIABLES CLAVE PARA 2010
# ------------------------------------------------------------
mun_2010_vars <- mun_2010 %>%
select(
cve_mun,
anio,
pob_total = pobtot, # población total
pob_12_mas = p_12ymas, # población de 12 años y más
pob_0_14 = pob0_14, # población de 0 a 14 años
pob_15_64 = pob15_64, # población de 15 a 64 años
pob_65_mas = pob65_mas, # población de 65 años y más
pob_nac_ot = pnacoe, # nacidos en otra entidad
pob_econ_act = pea # población económicamente activa
)
# ------------------------------------------------------------
# 3️⃣ SELECCIONAR VARIABLES CLAVE PARA 2020
# ------------------------------------------------------------
mun_2020_vars <- mun_2020 %>%
select(
cve_mun,
anio,
nom_ent,
nom_mun,
pob_total = pobtot, # población total (POBTOT)
pob_12_mas = p_12ymas, # población de 12 años y más
pob_15_mas = p_15ymas, # población de 15 años y más
pob_0_14 = pob0_14, # población de 0 a 14 años
pob_15_64 = pob15_64, # población de 15 a 64 años
pob_65_mas = pob65_mas, # población de 65 años y más
pob_nac_ot = pnacoe, # nacidos en otra entidad
pob_econ_act = pea # población económicamente activa
)
# ------------------------------------------------------------
# 4️⃣ RENOMBRAR VARIABLES CON SUFIJO DE AÑO (_10 y _20)
# ------------------------------------------------------------
mun_2010_wide <- mun_2010_vars %>%
rename_with(~ paste0(., "_10"), .cols = -cve_mun)
mun_2020_wide <- mun_2020_vars %>%
rename_with(~ paste0(., "_20"), .cols = -cve_mun)
# ------------------------------------------------------------
# 5️⃣ UNIR POR CLAVE MUNICIPAL (cve_mun)
# ------------------------------------------------------------
mun_10_20 <- full_join(mun_2010_wide, mun_2020_wide, by = "cve_mun")
# ------------------------------------------------------------
# 6️⃣ CHEQUEOS RÁPIDOS
# ------------------------------------------------------------
glimpse(mun_10_20)
## Rows: 2,469
## Columns: 20
## $ cve_mun <chr> "01001", "01002", "01003", "01004", "01005", "01006", …
## $ anio_10 <dbl> 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, …
## $ pob_total_10 <dbl> 797010, 45492, 54136, 15042, 99590, 41862, 49156, 8443…
## $ pob_12_mas_10 <chr> "602719", "32320", "39898", "10801", "69970", "30172",…
## $ pob_0_14_10 <chr> "238193", "16209", "17800", "5255", "35746", "14373", …
## $ pob_15_64_10 <chr> "515262", "26623", "32248", "8930", "59840", "25250", …
## $ pob_65_mas_10 <chr> "40309", "2627", "4034", "844", "3640", "2169", "2520"…
## $ pob_nac_ot_10 <chr> "186972", "5194", "6379", "1378", "16300", "4636", "37…
## $ pob_econ_act_10 <chr> "336974", "14319", "19310", "4819", "39315", "14892", …
## $ anio_20 <dbl> 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, …
## $ nom_ent_20 <chr> "Aguascalientes", "Aguascalientes", "Aguascalientes", …
## $ nom_mun_20 <chr> "Aguascalientes", "Asientos", "Calvillo", "Cosío", "Je…
## $ pob_total_20 <dbl> 948990, 51536, 58250, 17000, 129929, 47646, 57369, 955…
## $ pob_12_mas_20 <chr> "756970", "38399", "44778", "12820", "99250", "36250",…
## $ pob_15_mas_20 <chr> "707473", "35250", "41495", "11817", "91487", "33468",…
## $ pob_0_14_20 <chr> "240583", "16266", "16720", "5183", "38303", "14140", …
## $ pob_15_64_20 <chr> "639532", "31919", "35854", "10699", "84949", "30491",…
## $ pob_65_mas_20 <chr> "67941", "3331", "5641", "1118", "6538", "2977", "3579…
## $ pob_nac_ot_20 <chr> "214908", "6025", "6566", "1385", "23898", "4416", "49…
## $ pob_econ_act_20 <chr> "486675", "21440", "25976", "7010", "65839", "22097", …
# Municipios presentes solo en un año
missing_2010 <- mun_10_20 %>% filter(is.na(pob_total_10)) %>% nrow()
missing_2020 <- mun_10_20 %>% filter(is.na(pob_total_20)) %>% nrow()
cat("🟡 Municipios que aparecen en 2020 pero no en 2010:", missing_2010, "\n")
## 🟡 Municipios que aparecen en 2020 pero no en 2010: 13
cat("🟡 Municipios que aparecen en 2010 pero no en 2020:", missing_2020, "\n")
## 🟡 Municipios que aparecen en 2010 pero no en 2020: 0
# Vista rápida de las columnas principales
mun_10_20 %>%
select(cve_mun, nom_ent_20, nom_mun_20,
starts_with("pob_total"), starts_with("pob_econ_act")) %>%
head()
## # A tibble: 6 × 7
## cve_mun nom_ent_20 nom_mun_20 pob_total_10 pob_total_20 pob_econ_act_10
## <chr> <chr> <chr> <dbl> <dbl> <chr>
## 1 01001 Aguascalientes Aguascalient… 797010 948990 336974
## 2 01002 Aguascalientes Asientos 45492 51536 14319
## 3 01003 Aguascalientes Calvillo 54136 58250 19310
## 4 01004 Aguascalientes Cosío 15042 17000 4819
## 5 01005 Aguascalientes Jesús María 99590 129929 39315
## 6 01006 Aguascalientes Pabellón de … 41862 47646 14892
## # ℹ 1 more variable: pob_econ_act_20 <chr>
# ------------------------------------------------------------
# 📜 Los códices comparados: leyendo el cambio en el territorio
# ------------------------------------------------------------
# Tochtli prepara una vista paralela entre los censos de 2010 y 2020.
# Con esta tabla, puede observar cómo creció cada municipio,
# tanto en población total como en fuerza laboral (PEA).
# Es como mirar dos mapas temporales superpuestos, donde los números
# cuentan la historia de diez años de transformaciones en Geotitlán.
library(DT)
tabla_vista <- mun_10_20 %>%
select(
cve_mun, # clave única del municipio: el hilo del tejido territorial
nom_ent_20, # nombre de la entidad (2020)
nom_mun_20, # nombre del municipio (2020)
pob_total_10, # población total en 2010
pob_total_20, # población total en 2020
pob_econ_act_10,# población económicamente activa en 2010
pob_econ_act_20 # población económicamente activa en 2020
)
# 🌾 Tochtli invoca la magia de las tablas interactivas
# Cada fila es una historia municipal, cada columna un eco del tiempo.
DT::datatable(
tabla_vista,
options = list(
pageLength = 10, # diez historias por página
scrollX = TRUE, # permite navegar el códice horizontalmente
autoWidth = TRUE,
language = list(url = '//cdn.datatables.net/plug-ins/1.13.1/i18n/es-ES.json')
),
filter = "top", # filtros que actúan como lupas para explorar patrones
caption = "🧭 Comparativo municipal 2010–2020: la evolución de la población y la actividad económica en Geotitlán"
)
En esta etapa del viaje, Tochtli transforma los
números crudos del censo en sabiduría
territorial.
Los datos dejan de ser simples tablas y se convierten en instrumentos
para leer el pulso de los municipios.
Aquí el código se vuelve alquimia: del texto, surge el número; del
número, el indicador; y del indicador, la historia del territorio.
Los códices del INEGI suelen llegar con cifras enmascaradas,
como si los números fueran símbolos antiguos escritos con comas y
espacios —“12,345” en vez de 12345—.
R no puede calcular con ellos directamente, así que Tochtli utiliza su
primera herramienta mágica:
parse_number() del paquete readr.
Esta función: - 🌿 Elimina comas, signos o espacios. - 🔢 Convierte los textos en números reales. - ⚙️ Prepara el terreno para los cálculos posteriores.
💻 Código:
# 🧮 CONVERSIÓN A NUMÉRICO Y CÁLCULO DE INDICADORES
# ------------------------------------------------------------
library(dplyr)
library(readr)
# 1️⃣ Convertir columnas de población a numéricas
# (quita comas, espacios y convierte a numeric)
mun_10_20_num <- mun_10_20 %>%
mutate(across(
matches("^pob_|pobtot|p_"),
~ parse_number(as.character(.))
))
# 2️⃣ Calcular indicadores
indicadores_mun <- mun_10_20_num %>%
mutate(
# --- Tasa de Crecimiento Medio Anual (TCMA)
tcma = ((pob_total_20 / pob_total_10)^(1/10) - 1) * 100,
# --- Índice de Envejecimiento
ind_envejec_10 = (pob_65_mas_10 / pob_0_14_10) * 100,
ind_envejec_20 = (pob_65_mas_20 / pob_0_14_20) * 100,
# --- Índice de Juventud
ind_juventud_10 = (pob_0_14_10 / (pob_15_64_10 + pob_65_mas_10)) * 100,
ind_juventud_20 = (pob_0_14_20 / (pob_15_64_20 + pob_65_mas_20)) * 100,
# --- Índice de Dependencia Económica
ind_depend_10 = ((pob_0_14_10 + pob_65_mas_10) / pob_15_64_10) * 100,
ind_depend_20 = ((pob_0_14_20 + pob_65_mas_20) / pob_15_64_20) * 100,
# --- Atracción migratoria acumulada
atr_migr_10 = (pob_nac_ot_10 / pob_total_10) * 100,
atr_migr_20 = (pob_nac_ot_20 / pob_total_20) * 100,
# --- Tasa de actividad económica
tasa_act_10 = (pob_econ_act_10 / pob_12_mas_10) * 100,
tasa_act_20 = (pob_econ_act_20 / pob_12_mas_20) * 100
)
# 3️⃣ Revisar resultados
indicadores_mun %>%
select(nom_ent_20, nom_mun_20, tcma, ind_envejec_20, ind_depend_20, atr_migr_20, tasa_act_20) %>%
head()
## # A tibble: 6 × 7
## nom_ent_20 nom_mun_20 tcma ind_envejec_20 ind_depend_20 atr_migr_20
## <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Aguascalientes Aguascalientes 1.76 28.2 48.2 22.6
## 2 Aguascalientes Asientos 1.26 20.5 61.4 11.7
## 3 Aguascalientes Calvillo 0.735 33.7 62.4 11.3
## 4 Aguascalientes Cosío 1.23 21.6 58.9 8.15
## 5 Aguascalientes Jesús María 2.69 17.1 52.8 18.4
## 6 Aguascalientes Pabellón de Art… 1.30 21.1 56.1 9.27
## # ℹ 1 more variable: tasa_act_20 <dbl>
En Geotitlán, R es más que un lenguaje de
programación:
es una mochila llena de instrumentos para recorrer y representar el
territorio.
Cada librería es una herramienta ancestral reimaginada en código,
capaz de leer, transformar y pintar el espacio geográfico.
🗺️ sf (simple features)
Es el pincel cartográfico de R.
Permite leer y escribir datos espaciales —Shapefile,
GeoJSON, GeoPackage—
y trabajar con geometrías (puntos, líneas y polígonos).
También comprende los sistemas de proyección (CRS),
para que los mapas conserven su forma y sentido en el mundo.
🎨 tmap
La paleta visual de Geotitlán.
Crea mapas temáticos, estáticos o interactivos,
con una sintaxis clara y expresiva.
Con tmap, los datos cobran color y las variables encuentran
su voz.
🔗 dplyr
El telar de datos.
Une, filtra y transforma tablas;
permite fusionar las estadísticas del censo con la geometría del
territorio.
Sin él, los datos quedarían dispersos, sin historia ni forma.
🧹 janitor (opcional)
El limpiador del códice.
Establece nombres claros y uniformes en las columnas,
evitando errores por mayúsculas, tildes o espacios.
Tochtli lo usa antes de cualquier ritual analítico.
📝 Tip geotitlense:
En Windows, recuerda escribir las rutas con “/” o doble “\”.
Así evitas que los caminos del código se confundan y el mapa se pierda.
📖 Reflexión:
> “Cada librería es una extensión de nuestra mirada.
> Con ellas, el territorio se revela línea a línea,
> capa a capa, como un códice que respira.” — Tochtli
# 🗺️ Lectura de la capa municipal: el mapa base de Geotitlán
# ------------------------------------------------------------
# Tochtli abre el códice espacial donde descansan los contornos
# de los municipios de México. Cada polígono es una historia,
# una frontera, una memoria grabada en coordenadas.
library(sf)
## Linking to GEOS 3.13.1, GDAL 3.11.0, PROJ 9.6.0; sf_use_s2() is TRUE
library(dplyr)
library(stringr)
library(janitor)
library(tmap)
# 🌎 1) Ruta hacia los archivos espaciales de Geotitlán
# (Ajustada a tu nueva estructura de carpetas)
ruta_shp <- "C:/geodatos/Datos espaciales/00mun.shp"
# 🧭 2) Lectura y limpieza del shapefile
mun_sf <- sf::read_sf(ruta_shp) %>%
janitor::clean_names()
Con solo unas pocas líneas de código, R puede leer y visualizar información geográfica.
sf::read_sf() lee un archivo espacial
(como un .shp), conservando su geometría.tmap nos permite crear mapas de forma
rápida y reproducible.tmap_mode("plot") obtenemos un
mapa estático; cambiando a "view" generamos un mapa
interactivo con zoom y desplazamiento.Este primer mapa muestra todos los municipios de México con su delimitación básica, demostrando que R puede comportarse como una plataforma geoespacial completa sin necesidad de interfaces gráficas.
# 3️⃣ Mapa estilo Mondrian con tmap
library(tmap)
tmap_mode("plot") # 'plot' = mapa estático; usa 'view' para interactivo
## ℹ tmap modes "plot" - "view"
## ℹ toggle with `tmap::ttm()`
tm_shape(mun_sf) +
tm_polygons(
col = "#FFD100", # 🟨 Amarillo dominante
border.col = "#000000", # Bordes negros gruesos
lwd = 0.6,
title = "Municipios"
) +
tm_layout(
title = "🟥🟨🟦 Mapa Mondrian de municipios de México",
title.size = 1.4,
frame = TRUE, # Marco visible
frame.lwd = 3, # Borde grueso tipo Mondrian
bg.color = "#FFFFFF", # Fondo blanco
outer.bg.color = "#0033A0", # Fondo externo azul profundo
legend.bg.color = "#C8102E", # Fondo de la leyenda rojo
legend.text.color = "white", # Texto de leyenda en blanco
legend.title.color = "white",
legend.outside = TRUE,
legend.outside.position = "right",
main.title.position = "center",
main.title.color = "#0033A0",
main.title.fontface = "bold"
) +
tm_compass(
type = "4star",
position = c("left", "bottom"),
color.light = "#FFD100",
color.dark = "#C8102E"
) +
tm_scale_bar(
position = c("left", "bottom"),
text.color = "#0033A0",
color.dark = "#000000",
color.light = "#FFD100"
)
##
## ── tmap v3 code detected ───────────────────────────────────────────────────────
## [v3->v4] `tm_polygons()`: use 'fill' for the fill color of polygons/symbols
## (instead of 'col'), and 'col' for the outlines (instead of 'border.col').[v3->v4] `tm_polygons()`: migrate the argument(s) related to the legend of the
## visual variable `fill` namely 'title' to 'fill.legend = tm_legend(<HERE>)'[v3->v4] `tm_layout()`: use `tm_title()` instead of `tm_layout(title = )`! `tm_scale_bar()` is deprecated. Please use `tm_scalebar()` instead.
# Integrando datos espaciales y estadísticos
Hasta este punto del taller, hemos trabajado con dos tipos de información complementaria:
🗺️ El shapefile municipal (mun_sf): Contiene la geometría (los polígonos de los municipios), sus límites y nombres oficiales.
📊 La tabla de indicadores (indicadores_mun): Contiene los datos estadísticos calculados a partir de los censos (población, índices, tasas, etc.).
El objetivo de este bloque es unir ambos conjuntos de información para obtener una sola capa espacial con toda la información lista para mapear y analizar: geometría + indicadores.
# 🔗 UNIÓN mun_sf (cvegeo) + indicadores_mun (cve_mun)
# ------------------------------------------------------------
library(sf)
library(dplyr)
library(stringr)
library(janitor)
# 1️⃣ Aseguramos nombres limpios
mun_sf <- mun_sf %>% janitor::clean_names()
# 2️⃣ Función para normalizar a 5 dígitos (caracter)
pad5 <- function(x){
x <- as.character(x)
x <- stringr::str_replace_all(x, "[^0-9]", "")
dplyr::if_else(nchar(x) == 0, NA_character_, stringr::str_pad(x, 5, pad = "0"))
}
# 3️⃣ Crear llave común 'cve_mun' en ambos objetos
mun_sf_key <- mun_sf %>%
mutate(
cve_mun = pad5(cvegeo)
) %>%
select(cvegeo, cve_mun, nomgeo, everything()) # 👈 forzamos a mantener nomgeo
indicadores_key <- indicadores_mun %>%
mutate(cve_mun = pad5(cve_mun))
# 4️⃣ Diagnóstico rápido de empates
faltan_en_ind <- mun_sf_key %>%
st_drop_geometry() %>%
anti_join(indicadores_key %>% select(cve_mun), by = "cve_mun")
sobran_en_ind <- indicadores_key %>%
anti_join(mun_sf_key %>% st_drop_geometry() %>% select(cve_mun), by = "cve_mun")
cat("Claves en SHP sin match en indicadores:", nrow(faltan_en_ind), "\n")
## Claves en SHP sin match en indicadores: 0
cat("Claves en indicadores sin match en SHP:", nrow(sobran_en_ind), "\n")
## Claves en indicadores sin match en SHP: 0
# 5️⃣ Unión (manteniendo geometría y nombre del municipio)
mun_indicadores_sf <- mun_sf_key %>%
left_join(indicadores_key, by = "cve_mun")
# 6️⃣ Comprobación de columnas clave tras el join
mun_indicadores_sf %>%
select(cvegeo, cve_mun, nomgeo,
any_of(c("nom_ent_20", "nom_mun_20")),
starts_with("pob_total"), starts_with("tcma"), starts_with("ind_")) %>%
head()
## Simple feature collection with 6 features and 14 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 2410092 ymin: 1067540 xmax: 2514978 ymax: 1159778
## Projected CRS: MEXICO_ITRF_2008_LCC
## # A tibble: 6 × 15
## cvegeo cve_mun nomgeo nom_ent_20 nom_mun_20 pob_total_10 pob_total_20 tcma
## <chr> <chr> <chr> <chr> <chr> <dbl> <dbl> <dbl>
## 1 01001 01001 Aguascal… Aguascali… Aguascali… 797010 948990 1.76
## 2 01002 01002 Asientos Aguascali… Asientos 45492 51536 1.26
## 3 01003 01003 Calvillo Aguascali… Calvillo 54136 58250 0.735
## 4 01004 01004 Cosío Aguascali… Cosío 15042 17000 1.23
## 5 01005 01005 Jesús Ma… Aguascali… Jesús Mar… 99590 129929 2.69
## 6 01006 01006 Pabellón… Aguascali… Pabellón … 41862 47646 1.30
## # ℹ 7 more variables: ind_envejec_10 <dbl>, ind_envejec_20 <dbl>,
## # ind_juventud_10 <dbl>, ind_juventud_20 <dbl>, ind_depend_10 <dbl>,
## # ind_depend_20 <dbl>, geometry <MULTIPOLYGON [m]>
Con este código, exportamos el objeto espacial
mun_indicadores_sf, que ya contiene geometría y variables censales, como un shapefile estándar.🔹
st_write()es la función del paquete sf para escribir archivos espaciales.
🔹 El parámetrodriver = "ESRI Shapefile"indica el formato de salida.
🔹delete_layer = TRUEpermite sobrescribir el archivo si ya existe, evitando errores.El resultado quedará en la ruta de trabajo o donde tu le des la dirección
# ------------------------------------------------------------
# 💾 EXPORTAR LA CAPA UNIDA COMO SHAPEFILE
# ------------------------------------------------------------
# Objetivo:
# Guardar la capa final 'mun_indicadores_sf' (municipios + indicadores)
# como shapefile para abrirla después en QGIS o ArcGIS.
library(sf)
# 1️⃣ Definir la ruta de salida
ruta_salida_shp <- "C:/SIG_RO/Taller_R/Salidas/indicadores_municipales.shp"
# 2️⃣ Exportar usando st_write()
st_write(
obj = mun_indicadores_sf,
dsn = ruta_salida_shp,
driver = "ESRI Shapefile",
delete_layer = TRUE # sobrescribe si ya existe
)
## Warning in abbreviate_shapefile_names(obj): Field names abbreviated for ESRI
## Shapefile driver
## Deleting layer `indicadores_municipales' using driver `ESRI Shapefile'
## Writing layer `indicadores_municipales' to data source
## `C:/SIG_RO/Taller_R/Salidas/indicadores_municipales.shp' using driver `ESRI Shapefile'
## Writing 2469 features with 34 fields and geometry type Multi Polygon.
# 3️⃣ Confirmación visual
cat("✅ Shapefile exportado correctamente en:", ruta_salida_shp)
## ✅ Shapefile exportado correctamente en: C:/SIG_RO/Taller_R/Salidas/indicadores_municipales.shp
# 🗺️ FILTRO: MUNICIPIOS DEL ESTADO DE QUERÉTARO
# ------------------------------------------------------------
library(dplyr)
library(sf)
# 1️⃣ Verificar que el campo 'cve_ent' exista
names(mun_indicadores_sf)
## [1] "cvegeo" "cve_mun" "nomgeo" "cve_ent"
## [5] "geometry" "anio_10" "pob_total_10" "pob_12_mas_10"
## [9] "pob_0_14_10" "pob_15_64_10" "pob_65_mas_10" "pob_nac_ot_10"
## [13] "pob_econ_act_10" "anio_20" "nom_ent_20" "nom_mun_20"
## [17] "pob_total_20" "pob_12_mas_20" "pob_15_mas_20" "pob_0_14_20"
## [21] "pob_15_64_20" "pob_65_mas_20" "pob_nac_ot_20" "pob_econ_act_20"
## [25] "tcma" "ind_envejec_10" "ind_envejec_20" "ind_juventud_10"
## [29] "ind_juventud_20" "ind_depend_10" "ind_depend_20" "atr_migr_10"
## [33] "atr_migr_20" "tasa_act_10" "tasa_act_20"
# 2️⃣ Filtrar solo Querétaro (clave 22)
mun_queretaro <- mun_indicadores_sf %>%
filter(cve_ent == "22")
# 3️⃣ Verificar cuántos municipios tiene
mun_queretaro %>%
st_drop_geometry() %>%
count(cve_ent, sort = TRUE)
## # A tibble: 1 × 2
## cve_ent n
## <chr> <int>
## 1 22 18
# 4️⃣ Vista rápida de nombres de municipios
mun_queretaro %>%
st_drop_geometry() %>%
select(cve_ent, nomgeo) %>%
head()
## # A tibble: 6 × 2
## cve_ent nomgeo
## <chr> <chr>
## 1 22 Amealco de Bonfil
## 2 22 Pinal de Amoles
## 3 22 Arroyo Seco
## 4 22 Cadereyta de Montes
## 5 22 Colón
## 6 22 Corregidora
# 5️⃣ (Opcional) mapa rápido de verificación
library(leaflet)
leaflet(st_transform(mun_queretaro, 4326)) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addPolygons(
color = "#444444", weight = 0.6,
fillColor = "#0072B2", fillOpacity = 0.4,
label = ~nomgeo,
highlightOptions = highlightOptions(color = "black", weight = 1.2, bringToFront = TRUE)
) %>%
addLegend(
position = "bottomright",
colors = "#0072B2",
labels = "Municipios de Querétaro",
title = "Estado de Querétaro"
)
# ------------------------------------------------------------
# 🌐 Leaflet: mapa interactivo con mun_queretaro (usa nomgeo)
# ------------------------------------------------------------
library(dplyr)
library(sf)
library(leaflet)
library(scales)
##
## Adjuntando el paquete: 'scales'
## The following object is masked from 'package:readr':
##
## col_factor
library(htmltools)
# 1) Asegurar CRS WGS84 y definir nombre del municipio
mun_map <- mun_queretaro %>%
st_transform(4326) %>%
mutate(
nombre_mun = nomgeo, # 👈 usa nomgeo como nombre del municipio
nombre_ent = "Querétaro" # puedes cambiarlo si tienes una columna de entidad
)
# 2) Paletas de color por indicador (pares 2010–2020)
rng_pair <- function(df, v10, v20) range(c(df[[v10]], df[[v20]]), na.rm = TRUE)
pal_bin <- function(palette, dom) colorBin(palette, domain = dom, bins = 7, na.color = "#cccccc")
pal_tcma <- pal_bin("YlOrRd", range(mun_map$tcma, na.rm = TRUE))
pal_envej <- pal_bin("PuRd", rng_pair(mun_map, "ind_envejec_10", "ind_envejec_20"))
pal_juventud <- pal_bin("Greens", rng_pair(mun_map, "ind_juventud_10", "ind_juventud_20"))
pal_depend <- pal_bin("YlGnBu", rng_pair(mun_map, "ind_depend_10", "ind_depend_20"))
pal_migr <- pal_bin("BuPu", rng_pair(mun_map, "atr_migr_10", "atr_migr_20"))
pal_act <- pal_bin("Oranges",rng_pair(mun_map, "tasa_act_10", "tasa_act_20"))
lbl_base <- function(nmun, nent) {
sprintf("<b>%s, %s</b>", nmun %||% "", nent %||% "") %>% lapply(HTML)
}
# 3) Construcción del mapa interactivo
leaflet(mun_map, options = leafletOptions(zoomControl = TRUE)) %>%
addProviderTiles(providers$CartoDB.Positron, group = "Fondo claro") %>%
addProviderTiles(providers$CartoDB.DarkMatter, group = "Fondo oscuro") %>%
# --- TCMA ---
addPolygons(
fillColor = ~pal_tcma(tcma),
color = "#4d4d4d", weight = 0.4, opacity = 1, fillOpacity = 0.85,
group = "TCMA (2000–2020)",
popup = ~sprintf("<b>%s</b><br/>TCMA: %s",
nombre_mun,
ifelse(is.finite(tcma), percent(tcma, 0.1), "s/d"))
) %>%
addLegend(pal = pal_tcma, values = ~tcma, group = "TCMA (2000–2020)",
title = "TCMA (2000–2020)", opacity = 0.85) %>%
# --- Envejecimiento ---
addPolygons(
fillColor = ~pal_envej(ind_envejec_10), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Envejecimiento 2010",
popup = ~sprintf("<b>%s</b><br/>Índice 2010: %s",
nombre_mun,
ifelse(is.finite(ind_envejec_10), paste0(round(ind_envejec_10,1),"%"), "s/d"))
) %>%
addPolygons(
fillColor = ~pal_envej(ind_envejec_20), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Envejecimiento 2020",
popup = ~sprintf("<b>%s</b><br/>Índice 2020: %s",
nombre_mun,
ifelse(is.finite(ind_envejec_20), paste0(round(ind_envejec_20,1),"%"), "s/d"))
) %>%
addLegend(pal = pal_envej, values = ~c(ind_envejec_10, ind_envejec_20),
group = "Envejecimiento 2010", title = "Índice de envejecimiento (%)",
opacity = 0.85) %>%
# --- Juventud ---
addPolygons(
fillColor = ~pal_juventud(ind_juventud_10), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Juventud 2010",
popup = ~sprintf("<b>%s</b><br/>Índice 2010: %s",
nombre_mun,
ifelse(is.finite(ind_juventud_10), paste0(round(ind_juventud_10,1),"%"), "s/d"))
) %>%
addPolygons(
fillColor = ~pal_juventud(ind_juventud_20), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Juventud 2020",
popup = ~sprintf("<b>%s</b><br/>Índice 2020: %s",
nombre_mun,
ifelse(is.finite(ind_juventud_20), paste0(round(ind_juventud_20,1),"%"), "s/d"))
) %>%
addLegend(pal = pal_juventud, values = ~c(ind_juventud_10, ind_juventud_20),
group = "Juventud 2010", title = "Índice de juventud (%)",
opacity = 0.85) %>%
# --- Dependencia ---
addPolygons(
fillColor = ~pal_depend(ind_depend_10), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Dependencia 2010",
popup = ~sprintf("<b>%s</b><br/>Dependencia 2010: %s",
nombre_mun,
ifelse(is.finite(ind_depend_10), paste0(round(ind_depend_10,1),"%"), "s/d"))
) %>%
addPolygons(
fillColor = ~pal_depend(ind_depend_20), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Dependencia 2020",
popup = ~sprintf("<b>%s</b><br/>Dependencia 2020: %s",
nombre_mun,
ifelse(is.finite(ind_depend_20), paste0(round(ind_depend_20,1),"%"), "s/d"))
) %>%
addLegend(pal = pal_depend, values = ~c(ind_depend_10, ind_depend_20),
group = "Dependencia 2010", title = "Dependencia económica (%)",
opacity = 0.85) %>%
# --- Migración ---
addPolygons(
fillColor = ~pal_migr(atr_migr_10), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Migración 2010",
popup = ~sprintf("<b>%s</b><br/>Migración 2010: %s",
nombre_mun,
ifelse(is.finite(atr_migr_10), paste0(round(atr_migr_10,1),"%"), "s/d"))
) %>%
addPolygons(
fillColor = ~pal_migr(atr_migr_20), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Migración 2020",
popup = ~sprintf("<b>%s</b><br/>Migración 2020: %s",
nombre_mun,
ifelse(is.finite(atr_migr_20), paste0(round(atr_migr_20,1),"%"), "s/d"))
) %>%
addLegend(pal = pal_migr, values = ~c(atr_migr_10, atr_migr_20),
group = "Migración 2010", title = "Atracción migratoria (%)",
opacity = 0.85) %>%
# --- Actividad económica ---
addPolygons(
fillColor = ~pal_act(tasa_act_10), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Actividad 2010",
popup = ~sprintf("<b>%s</b><br/>Actividad 2010: %s",
nombre_mun,
ifelse(is.finite(tasa_act_10), paste0(round(tasa_act_10,1),"%"), "s/d"))
) %>%
addPolygons(
fillColor = ~pal_act(tasa_act_20), color = "#4d4d4d", weight = 0.4,
fillOpacity = 0.85, group = "Actividad 2020",
popup = ~sprintf("<b>%s</b><br/>Actividad 2020: %s",
nombre_mun,
ifelse(is.finite(tasa_act_20), paste0(round(tasa_act_20,1),"%"), "s/d"))
) %>%
addLegend(pal = pal_act, values = ~c(tasa_act_10, tasa_act_20),
group = "Actividad 2010", title = "Tasa de actividad (%)",
opacity = 0.85) %>%
# --- Control de capas ---
addLayersControl(
baseGroups = c("Fondo claro", "Fondo oscuro"),
overlayGroups = c("TCMA (2000–2020)",
"Envejecimiento 2010", "Envejecimiento 2020",
"Juventud 2010", "Juventud 2020",
"Dependencia 2010", "Dependencia 2020",
"Migración 2010", "Migración 2020",
"Actividad 2010", "Actividad 2020"),
options = layersControlOptions(collapsed = FALSE)
) %>%
hideGroup(c("Envejecimiento 2010","Envejecimiento 2020",
"Juventud 2010","Juventud 2020",
"Dependencia 2010","Dependencia 2020",
"Migración 2010","Migración 2020",
"Actividad 2010","Actividad 2020"))