Mapas en R… los partidos que gobiernan los estados en México

Últimamente veo que se ha puesto de moda -al menos entre los politólogos- hacer mapas. Los mapas son muy útiles para presentar información espacial diversa. Sin embargo, uno de los problemas que veo es que el software para producir dichos mapas es demasiado caro (por ejemplo, ArcGIS, de la compañía ESRI, cuesta muchos muchos dólares)… Creo que exagero, hay opciones “open source” (es decir, gratis) que son muy buenas como Quantum GIS. Para mi desgracia no he tenido mucho tiempo de aprender a usar este software… ¿Qué hacer? Pues, como dicen en mi pueblo, uno se las arregla con lo que tiene. ¡Por suerte tengo R!

Veamos pues cómo hacer un mapa en R. Se necesitan varios ingredientes, los más importantes, tal vez, son los dichosos “shapefiles”: conjunto de archivos con terminación .shp, .shx, .dbf, etc., que contiene diversa información como latitud, longitud, y los datos vectoriales a desplegar en el mapa (pueden ser polígonos, líneas, puntos, etc. Estas figuras representan lagos, parques, municipios, carreteras, vías de tren, etc.). El shapefile que utilizaré en esta ocasión contiene los 31 estados mexicanos y la ciudad de México; lo obtuve de la base de datos de áreas administrativas globales “GADM” y también lo pueden encontrar aquí. El archivo que necesito para R se llama “MEX_adm1.shp” (los otros shapefiles, aquellos con terminación adm0 y amd2, contienen los vectores del país entero y de los dos mil cuatrocientos y tantos municipios mexicanos… en este caso nos enfocaremos en el adm1, es decir, el de las unidades estatales). Descargué todos los archivos de GADM en una carpeta localizada en mi “Desktop” llamada “Mexico” dentro de la subcarpeta llamada “MEX_adm”. Ya con ese “ingrediente” en nuestra computadora vayamos a R.

Necesitan instalar los siguientes paquetes: ggplot2, ggmap, maptools y car. Maptools sirve para cargar el shapefile en R, ggplot2 sirve para convertir este shapefile a un data.frame con información de latitud, longitud, etc., ggmap sirve para obtener mapas, y car sirve para recodificar una variable y convertirla en un factor. Los pasos del código abajo aclararán para qué sirve cada uno (de todas formas aquí tienen más información sobre ggmap):

#El working directory donde se encuentra el dichoso shapefile.
setwd("~/Desktop/Mexico/MEX_adm")

#Los paquetes a utilizar.
require(ggmap)
require(ggplot2)
require(maptools)
require(car)

#Descarguemos el shapefile en R. La función readShapeSpatial viene en el paquete maptools (busquen más información sobre este paquete en la documentación en línea al respecto).
estados.shape = readShapeSpatial("MEX_adm1.shp")

#Convirtamos este shapefile a un data.frame de R para poder utilizarlo con ggmap, ggplot2 o crear más variables.
#La función para convertir este shapefile en un data.frame se llama fortify y viene en el paquete ggplot2.
estados.poly = fortify(estados.shape)

#Veamos que información tiene el data.frame que acabamos de crear.
#Vemos que tiene dos variables numéricas para longitud y latitud (long y lat respectivamente), order (variable de enteros que une los puntos para crear los polígonos), etc.
str(estados.poly)

Antes de seguir, veamos cómo obtener un simple mapa… para ello utilizamos la función get_map que viene en el paquete ggmap. Esta función es muy muy útil pues sirve para obtener mapas de cualquier parte del mundo (países enteros, ciudades, etc.) Tiene bastantes argumentos: location (podemos escribir aquí la ciudad que queremos, o el país que queremos o las coordenadas en longitud y latitud), maptype (si queremos un mapa con una imagen satelital, o blanco y negro, etc.), zoom (que tan cerca o lejos queremos el mapa, 3 es todo el mundo y 21 es a nivel edificio… un super-zoom), etc. Aquí hay más información sobre la función get_map. Veamos ahora un ejemplo sencillo.

#Quiero un mapa de Brasil que muestre gran parte del continente y no sólo este país (para ello utilizo zoom=4). También quiero un mapa de tipo "terrain", es decir, que muestre relieve de montañas, bosques, etc.
#Voy a pedir que obtenga el mapa de Google. Para el ejemplo de México pediré el mapa de otra fuente (OpenStreetMap).
ejemplo = get_map(location="Brazil", source="google", maptype="terrain", zoom=4)

#Vemos el mapa con la función ggmap.
ggmap(ejemplo)

Esta es la imagen que obtenemos:

mapaBrasil

Después de probar la función que sirve para obtener mapas, sigamos con el ejemplo de México. El propósito del gráfico será ver qué partidos gobiernan los gobiernos estatales mexicanos (a principios de julio hubo elecciones locales y el otrora partido autoritario del siglo XX, el PRI, ganó la mayoría de las candidaturas en disputa -y esto lo observaremos en el gráfico final). Así pues, lo primero que debemos buscar son las coordenadas geográficas de México para así obtener el mapa más adecuado posible (dichas coordenadas las obtuve de aquí). Verán, por ejemplo, que el punto más al oeste se encuentra en la longitud 118° 22′ 00″; así, para obtener el mapa pedí a mi función que diera un poco más de espacio y colocara el extremo izquierdo del mapa a obtener en  la longitud 121° (esto lo hice especificando en el argumento location el subargumento left en -121. Di, igualmente, más espacio hacia el norte, sur y este). También, pedí obtener el mapa de OpenStreetMap (y no de Google Maps como lo hice anteriormente para obtener el mapa de Brasil). El argumento que indica esto es source="osm". También pedí un fondo en blanco y negro.

# Cada argumento lo explico en el párrafo de aquí arriba.
imagen = get_map(location=c(right=-85, left=-121, bottom=13, top=33), source="osm", color="bw")

#Veamos el mapa con la función ggmap.
ggmap(imagen)

Si todo sale bien deben obtener lo siguiente:

mapaMexico1

En seguida, la variable “id” del data.frame estados.poly (que obtuve del shapefile y la función fortify ) empieza en 0 y termina en 31 (lo pueden comprobar con la función unique). Sin embargo, de acuerdo al INEGI, los códigos de los estados deben empezar en 1 (correspondiente a Aguascalientes) y terminar en 32 (correspondiente a Zacatecas). Aquí pueden ver las claves oficiales del INEGI para cada uno de los estados. El orden de los identificadores en cada uno de los estados de mi data.frame es exactamente igual al del INEGI con la excepción de empezar en 0 y no en 1 y terminar en 31 y no en 32; así que lo único que tengo que hacer es añadirle un 1 a la variable id (creo una nueva variable llamada id2). Posteriormente, ya con este identificador ajustado, busco qué partidos gobiernan cada estado y creo una nueva variable llamada id3 (un factor que identifica qué partido gobierna qué estados). Los datos para saber qué partido gobierna en qué estado los obtuve de aquí (considero que Oaxaca está gobernado por el PRD y no por Movimiento Ciudadano). No creo necesario hacer este paso pero bueno, lo hago para ser “consistentes”. Veamos:

#Añado un 1 para ajustar el identificador a las claves del INEGI.
estados.poly$id2 = as.numeric(estados.poly$id) + 1

#Creo un factor para identificar qué partido gobierna qué estado (vean que utilizo la función recode para indicar qué id's, es decir, qué estados, gobierna cada partido.
#Por ejemplo, el PAN gobierna los estados 2, 3, 11, 21, 25, 26; así para los otros partidos.
estados.poly$id3 = estados.poly$id2
estados.poly$id3 = recode(estados.poly$id3, "c(2,3,11,21,25,26)='PAN'; c(1,4,6,7,8,10,13,14,15,16,18,19,22,23,24,28,29,30,31,32)='PRI'; c(9,12,17,20,27)='PRD'; 5='PVEM'")
estados.poly$id3 = as.factor(estados.poly$id3)

Ya tenemos todos los ingredientes para crear el mapa: el mapa de México -i.e. el objeto llamado imagen- y un data.frame de polígonos que cuenta con una variable “id3” que identifica qué partidos gobiernan qué estados (el objeto llamado estados.poly). Hagamos, pues, el dichoso  mapa (indico de qué trata cada línea de código al final de la misma):

mapa = ggmap(imagen) + #Esto crea la imagen de México que ya vimos anteriormente.
geom_polygon(data=estados.poly, aes(x=long, y=lat, group=group), colour="grey", fill="white") + #Crea el relieve de los estados con un contorno gris y un fondo blanco.
geom_polygon(data=estados.poly, aes(x=long, y=lat, group=group, fill=id3), alpha=0.5) + #Creo un relleno de colores según mi factor id3 (que contiene el nombre de los partidos según el estado correspondiente).
scale_fill_manual(values=c("#003399","#FFCC33","#CC3300","#009966"), name="Partido") + #Indico que quiero colores de manera manual: azul, amarillo, rojo y verde.
labs(x="Longitud", y="Latitud") + #El nombre de los ejes.
ggtitle("Mexico: gobiernos estatales \n (Julio 2013) \n") #El título

#Vemos el mapa:
mapa

¡Listo! Aquí abajo verán el mapa final (por cierto, R tarda un poco en ajustar todas las líneas y polígonos así que no desesperen. En mi computadora tardó aproximadamente 5 minutos en desplegar la imagen final). Es interesante ver que el PRI tiene poder en casi todo el territorio nacional (el dinosaurio sigue más vivo que nunca), mientras tanto el PAN tiene mayor presencia en el noroeste del país y el PRD en el sur.

mapaMexico2

Si quieren saber más sobre la elaboración de mapas en R aquí hay otro buen post sobre el tema (en inglés).

Advertisements

3 comments

  1. Hola, tengo un problema para replicar la creación del mapa. Me aparece lo siguiente:
    est<-readShapeSpatial("MEX_adm2.shp")
    Error in getinfo.shape(fn) : Error opening SHP file

    Ya instalé los paquetes que mencionas.
    Te agradecería si me pudieras ayudar. Saludos

  2. Hola Diego, lo primero que te recomendaría es revisar qué archivos tienes en el directorio donde tienes el shape file -utilizando la función list.files().

    Tal vez el shapefile no se encuentra en ese directorio o, tal vez, faltan archivos adicionales que deben estar ahí para que el shapefile se pueda leer. Esto es mi culpa pues no aclaré algo importante: el shapefile, por sí solo, no lo puede leer maptools. Es necesario que en la misma carpeta donde esté el shapefile se encuentren otros archivos (en tu caso, es necesario que la carpeta donde tengas el shapefile contenga archivos como MEX_adm2.dbf, MEX_adm2.shx, MEX_adm2.prj, etc.). Así, para resolver tu problema, te recomendaría poner todos estos archivos en una carpeta llamada “Mexico” y extraer la información del shapefile desde esa carpeta (es decir, utilizar readShapeSpatial apuntando a esa carpeta). Por ejemplo readShapeSpatial("~/Desktop/Mexico/MEX_adm2.shp"); donde la carpeta “Mexico” tendría que tener los archivos adicionales que te menciono (terminaciones .dbf, .shx, etc.).

    Por último, en mi ejemplo yo estoy utilizando MEX_adm1.shp (el shapefile de los estados). Si utilizas MEX_adm2.shp (el shapefile de los municipios) la función fortify seguro tardará más en crear el data.frame

  3. Perfecto, muchas gracias!!
    Saludos

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: