Analizando datos descargado del INEGI “descarga masiva”

Numero de homicidios reportado al MP per capita por estado y año

Carga los paquetes y la funcion para limpiar vectores con characteres.

library(reshape)
## Loading required package: plyr
## Attaching package: 'reshape'
## The following object(s) are masked from 'package:plyr':
## 
## rename, round_any
library(ggplot2)

clean <- function(x) {
    x <- as.character(x)
    x <- gsub("[^0-9,/.]", "", x)
    as.numeric(x)
}

El primer paso es descargar todos los archivos tsv del sitio de INEGI.

http://www3.inegi.org.mx/sistemas/descarga/default.aspx?c=28088

Abrirlos en un solo directorio.

Bueno. Mueva a esta carpeta y para cargar todos de una vez usa lapply.

setwd("~/Downloads/INEGI/tsv/valor")
dir(pattern = "*Valor*")
##  [1] "00_Nacional_Valor.tsv"                  
##  [2] "01_Aguascalientes_Valor.tsv"            
##  [3] "02_BajaCalifornia_Valor.tsv"            
##  [4] "03_BajaCaliforniaSur_Valor.tsv"         
##  [5] "04_Campeche_Valor.tsv"                  
##  [6] "05_CoahuiladeZaragoza_Valor.tsv"        
##  [7] "06_Colima_Valor.tsv"                    
##  [8] "07_Chiapas_Valor.tsv"                   
##  [9] "08_Chihuahua_Valor.tsv"                 
## [10] "09_DistritoFederal_Valor.tsv"           
## [11] "10_Durango_Valor.tsv"                   
## [12] "11_Guanajuato_Valor.tsv"                
## [13] "12_Guerrero_Valor.tsv"                  
## [14] "13_Hidalgo_Valor.tsv"                   
## [15] "14_Jalisco_Valor.tsv"                   
## [16] "15_Mexico_Valor.tsv"                    
## [17] "16_MichoacandeOcampo_Valor.tsv"         
## [18] "17_Morelos_Valor.tsv"                   
## [19] "18_Nayarit_Valor.tsv"                   
## [20] "19_NuevoLeon_Valor.tsv"                 
## [21] "20_Oaxaca_Valor.tsv"                    
## [22] "21_Puebla_Valor.tsv"                    
## [23] "22_Queretaro_Valor.tsv"                 
## [24] "23_QuintanaRoo_Valor.tsv"               
## [25] "24_SanLuisPotosi_Valor.tsv"             
## [26] "25_Sinaloa_Valor.tsv"                   
## [27] "26_Sonora_Valor.tsv"                    
## [28] "27_Tabasco_Valor.tsv"                   
## [29] "28_Tamaulipas_Valor.tsv"                
## [30] "29_Tlaxcala_Valor.tsv"                  
## [31] "30_VeracruzdeIgnaciodelaLlave_Valor.tsv"
## [32] "31_Yucatan_Valor.tsv"                   
## [33] "32_Zacatecas_Valor.tsv"                 
a <- dir(pattern = "*Valor*")
d <- lapply(a, function(x) read.table(x, sep = "\t", fill = T, head = T))

Hay un problema. Algunos de los archivos tienen menos campos. El primero en la lista tiene lo menos. Resulta que los que faltan son años que no son importantes porque faltan datos por la mayoria de los estados y indicadores.

st  #Seleciona el primer miembro de la lista
dd <- d[[1]]
# Escribe un pequeño funcion para checar que los nombres corresponde
f <- function(x) x[, names(x) %in% names(dd)]
# Applicar la funcion.
d1 <- lapply(d, f)
# Juntar los resultados. CUIDADO. Este paso es largo y usa mucha memoria.
# Apenas lo logra
d2 <- do.call("rbind", d1)
# Guardarlos datos para que no hay que reptir el rollo.
write.csv(d2, file = "combined.csv", row.names = F)

Ahora tenemos un solo dataframe enorme. Contiene informacion desglosado al nivel municipal. Para extraer nada mas los estados.

d <- droplevels(d2[grep("Total", d2$Desc_Municipio), ])
d1 <- d[, c(1, 2, 5, 6, 7, 9, 35:47)]
write.csv(d1, "Estados.csv", row.names = F)
d1 <- read.csv("Estados.csv")

https://dl.dropbox.com/u/2703650/Analyses/INEGI/Estados.csv

Para extraer un variable hay que consultar los metadatos con cuidado. Una solución mejor seria meter los datos extraidos en una Base de datos. Pero por el momento vamos a ver los datos de homicidios.

hom <- d1[grep("Delitos por homicidio", d1$Indicador), ]
hom <- hom[, c(1, 2, 7:19)]
names(hom) <- gsub("X", "Hom", names(hom))

Para analizar la tasa de homicidios necesitamos la población de cada estado en cada año. Hay un problema. Los datos de poblacion tiene huecos entre cada censo. Un solución es ajustar un modelo sencillo linear para extrapolar entre puntos. Este es una aproximación aceptable para una serie de tiempo corto.

pop <- d1[d1$Indicador == "Población total", ]
dpop <- melt(pop, id = 1:2, m = 7:19)
dpop$year <- clean(dpop$variable)
# Una función para predicir los datos que faltan
f <- function(x) {
    x$pred = predict(lm(value ~ year, data = x), newdata = list(year = 1998:2010))
    x
}
# Aplicarlo a la lista y reconstruir el data frame en una linea
dp <- unsplit(lapply(split(dpop, dpop$Desc_Entidad), f), dpop$Desc_Entidad)
# Ahora, solamente reeplazar los datos que faltan
dp$value[is.na(dp$value)] <- dp$pred[is.na(dp$value)]
pop <- cast(dp, Cve_Entidad + Desc_Entidad ~ variable)
pop <- data.frame(pop)
names(pop) <- gsub("X", "Pob", names(pop))

Ahro ya tenemos dos dataframes. Uno tiene los datos de homocidios y el otro la población

h <- hom
h[, 3:15] <- 1e+05 * hom[, 3:15]/pop[, 3:15]
hh <- melt(h, id = 1:2, meas = 3:15)
hh$year <- clean(hh$variable)
qplot(year, value, data = hh, facets = ~Desc_Entidad, geom = c("line", "smooth"), 
    method = loess, ylim = c(0, 120))

plot of chunk unnamed-chunk-9

Para juntarlos con un shapefile hay que aprovechar el hecho de que los estados tienen un numero unico. Asi que se puede usar merge y luego abrir los resultados en Qgis o otro SIG.

https://dl.dropbox.com/u/2703650/Analyses/INEGI/shapefiles.zip

d <- readOGR("shapefiles", "estados")
h1 <- as.data.frame(cast(Cve_Entidad ~ year, data = hh))
names(h1)[1] <- "num_edo"
d@data <- merge(d@data, h1)
writeOGR(d, "shapefiles", "homicidios", drive = "ESRI Shapefile")

alt text

alt text