diff --git a/01_introduccion.Rmd b/01_introduccion.Rmd new file mode 100644 index 0000000..78a227f --- /dev/null +++ b/01_introduccion.Rmd @@ -0,0 +1,184 @@ + +--- +title: "INE con R: descargando datos del Instituto Nacional de Estadística desde R" +subtitle: "Primera parte: Introducción" +author: "Daniel Redondo-Sánchez - daniel.redondo.easp@juntadeandalucia.es" +date: "11-02-2019" +output: + html_document: + highlight: tango + theme: readable + toc: yes + toc_float: + collapsed: no + smooth_scroll: no + pdf_document: + toc: yes +editor_options: + chunk_output_type: console +--- + +**Con este documento vamos a aprender a descargar información del Instituto Nacional de Estadística (INE) usando R.** + +## 1. Obtención de URL + +El primer objetivo será el de obtener, o crear, una URL de la cual descargar los datos deseados. + +### 1.1. Generador de URL JSON + +Para descargar datos directamente del INE podemos hacer uso del [generador de URLs JSON](https://www.ine.es/dyngs/DataLab/manual.html?cid=66), que genera una dirección URL desde la que se puede acceder a estadísticas determinadas, en formato `JSON`. + +Dos enlaces nos serán muy útiles para comprender este generador, e incluso no tener que depender de él. + +* [Definición de URLs](https://www.ine.es/dyngs/DataLab/manual.html?cid=47). Nos permite comprender los distintos parámetros de la URL. + +* [Obtención de identificadores de objetos usando INEbase](https://www.ine.es/dyngs/DataLab/es/manual.html?cid=1259945947403). Permite reconocer el identificador de la operación estadística que se incluye en la URL. + +### 1.2. Generar URL sabiendo número de tabla + +Si queremos descargar información de una URL del tipo + +```{} +http://ine.es/jaxiT3/Tabla.htm?t=9687&L=0 +``` + +que corresponde a "Población residente por fecha, sexo y edad", podemos extraer de la URL el identificador de la tabla, que es `9687`, y podemos descargar la información en + +```{} +http://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/9687?nult=2&tip=AM +``` + +El parámetro `nult` indica que nos proporcione los n últimos datos, mientras que `tip` indica el tipo de descarga (A = amigable, M = metadatos, AM = amigable + metadatos). + +### 1.3. Generar URL sabiendo que es un fichero del tipo PcAxis + +Por ejemplo, si queremos descargar información de mortalidad, + +```{} +http://ine.es/jaxi/Tabla.htm?path=/t15/p417/a2017/l0/&file=01007.px&L=0 +``` + +es la URL de Muertes fetales tardías por causas (lista perinatal), sexo y semanas de gestación, dentro de defunciones según la Causa de Muerte 2017. + +En este caso, podemos ver un `.px` dentro de la URL, lo que indica que en última instancia estamos trabajando con un fichero PcAxis, el formato que usa el INE para editar y publicar sus datos. + +El identificador de la tabla se creará usando la parte de la URL `path=/t15/p417/a2017/l0/&file=01007.px` y extrayendo `path=` y `&file=`: + + +```{} +/t15/p417/a2017/l0/01007.px +``` + +La URL deseada será entonces: + +```{} +http://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/t15/p417/a2017/l0/01007.px?tip=AM +``` + +## 2. Petición a INE + +### 2.1. Primeros pasos + +Cargamos los paquetes necesarios: +```{r message=FALSE} +library(httr) +library(rlist) +library(dplyr) +``` + +```{r} +url <- "http://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/t15/p417/a2017/l0/01007.px?tip=AM" +``` + +Usamos la función `GET` del paquete `httr`, usando como único parámetro la URL obtenida en el paso anterior. + +```{r peticion} +muertes_json <- GET(url) +``` + +La variable `status_code` indica el éxito (o no) de la petición realizada. Un código que empieza por 2, o 3, suele indicar que la petición ha sido exitosa. Si el `status_code` comienza por 4, es que hay un problema en tu código (p.e. 404: la página no encuentra lo que solicitas), mientras que si comienza por 5, el problema está en la página web. + +```{r} +muertes_json$status_code +``` + +Podemos usar `http_type` para conocer el tipo de información que hemos obtenido. + +```{r} +http_type(muertes_json) +``` + +### 2.2. Pre-procesamiento + +La información debe ser pre-procesada antes de poder ser usada. Vemos la información cruda: + +```{r} +muertes_json +``` + +La función `content` extrae el contenido de lo solicitado. Vemos las primeras dos componentes del contenido: + +```{r} +muertes_contenido <- content(muertes_json) +head(muertes_contenido, 2) +``` + +Ya podríamos acceder a algunos datos, como por ejemplo: + +```{r} +muertes_contenido[[1]]$Nombre +muertes_contenido[[1]]$MetaData[[1]]$Codigo +muertes_contenido[[1]]$Data[[1]]$Valor +``` + +Pero esto no es lo ideal, así que seguimos procesando. Utilizaremos el paquete `rlist` de manera iterativa para extraer los datos y metadatos de la información descargada, y formar así un data.frame. + +```{r} +n <- length(muertes_contenido) + +for(i in 1:n){ + dato.i <- muertes_contenido[[i]] + muertes.i <- list.select(dato.i$Data, Valor) %>% list.stack %>% + cbind(codigo = dato.i$MetaData[[1]]$Nombre) %>% + cbind(sexo = dato.i$MetaData[[2]]$Nombre) %>% + cbind(s_gest = dato.i$MetaData[[3]]$Nombre) + ifelse(i == 1, muertes <- muertes.i, muertes <- rbind(muertes, muertes.i)) +} + +head(muertes) +``` + +También podríamos haber descargado los códigos de las variables, en lugar de las etiquetas: + +```{r} +n <- length(muertes_contenido) + +for(i in 1:n){ + dato.i <- muertes_contenido[[i]] + muertes.i <- list.select(dato.i$Data, Valor) %>% list.stack %>% + cbind(codigo = dato.i$MetaData[[1]]$Codigo) %>% + cbind(sexo = dato.i$MetaData[[2]]$Codigo) %>% + cbind(s_gest = dato.i$MetaData[[3]]$Codigo) + ifelse(i == 1, muertes <- muertes.i, muertes <- rbind(muertes, muertes.i)) +} + +head(muertes) +``` + +### 2.3. Ejemplo de uso + +Con el data.frame obtenido, podemos trabajar. Por ejemplo: + +```{r} +library(ggplot2) + +datos <- subset(muertes, muertes$codigo == "0193ixxiitodaslascausas" & + muertes$sexo != "ambossexos" & + ! muertes$s_gest %in% c("total", "noconsta")) + +ggplot(datos, aes(x = s_gest, y = Valor, fill = sexo)) + + geom_bar(stat = "identity", position = "dodge") + + ylab("Defunciones") + xlab("Semanas de gestación") + + ggtitle("Defunciones según semanas de gestación, por sexos") + + theme(legend.position="top") +``` \ No newline at end of file diff --git a/02_descarga_avanzada.Rmd b/02_descarga_avanzada.Rmd new file mode 100644 index 0000000..27a9dbb --- /dev/null +++ b/02_descarga_avanzada.Rmd @@ -0,0 +1,142 @@ + +--- +title: "INE con R: descargando datos del Instituto Nacional de Estadística desde R" +subtitle: "Segunda parte: Descarga avanzada. Población por provincias, por edad simple" +author: "Daniel Redondo-Sánchez" +date: "11-02-2019" +output: + html_document: + highlight: tango + theme: readable + toc: yes + toc_float: + collapsed: no + smooth_scroll: no + pdf_document: + toc: yes +editor_options: + chunk_output_type: console +--- + +# 1. Descarga de información + +```{r message=FALSE} +# Carga de paquetes +library(httr) +library(dplyr) +library(rlist) +``` + +```{r} +# Como la URL es: +# http://ine.es/jaxiT3/Tabla.htm?t=9687&L=0, +# ponemos el identificador 9678 +# Descargamos sin metadatos para que sea más rápido +url <- "http://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/9687?nult=6&tip=A" +poblacion_json <- GET(url) + +``` + +Parece que la descarga ha sido exitosa: + +```{r} +poblacion_json$status_code +``` + +pero + +```{r} +content(poblacion_json)$status +``` + +así que solicitamos la información hasta que es descargada con éxito: + +```{r descarga} +i <- 0 +while(is.null(content(poblacion_json)$status) == FALSE){ + i <- i + 1 + cat("Durmiendo...") + Sys.sleep(5) + cat(" Obteniendo información, puede tardar unos minutos... \n") + poblacion_json <- GET(url) + ifelse(is.null(content(poblacion_json)$status) == TRUE, + print(paste0("Intento nº", i, ": Archivo descargado.")), + print(paste0("Intento nº", i, ": ", content(poblacion_json)$status))) +} + +``` + +# 2. Procesamiento + +Extraemos la información necesaria (sexo, edad, provincia) que se encuentran dentro de un mismo campo. Usamos `strsplit` para dividir la información y seleccionar la componente necesaria. + +```{r ciclo procesamiento} +poblacion_contenido <- content(poblacion_json) +n <- length(poblacion_contenido) + +for(i in 1:n){ + dato.i <- poblacion_contenido[[i]]$Data + division <- strsplit(paste(poblacion_contenido[[i]]$Nombre), split = ". ", fixed = T)[[1]] + poblacion.i <- dato.i %>% list.select(T3_Periodo, Anyo, Valor) %>% list.stack %>% + cbind(edad = division[1]) %>% + cbind(sexo = division[3]) %>% + cbind(prov = division[2]) + ifelse(i == 1, poblacion <- poblacion.i, poblacion <- rbind(poblacion, poblacion.i)) +} +``` + +```{r} + +``` + +```{r} +# Tabla de frecuencias de los datos +table(poblacion$edad) +table(poblacion$sexo) +table(poblacion$prov) +table(poblacion$Anyo, poblacion$T3_Periodo) +``` + +Hemos observado que hay un error en los datos que hace que, a veces, cuando prov es "Total Nacional", aparece la edad en el campo prov y la provincia en el campo edad. Lo arreglamos. + +```{r ciclo arreglo} +poblacion$prov <- as.character(poblacion$prov) +poblacion$edad <- as.character(poblacion$edad) + +# m = n * número de periodos añadidos, se desdobla la lista +m <- nrow(poblacion) +m + +for(i in 1:m){ + if(poblacion$edad[[i]] == "Total Nacional"){ + poblacion$edad[[i]] = poblacion$prov[[i]] + poblacion$prov[[i]] = "Total Nacional" + } +} + +# Trabajamos con la edad (500 será nuestro código para el total) +for(i in 1:m){ + poblacion$edad[[i]] <- strsplit(poblacion$edad[[i]], " ")[[1]][1] + if(poblacion$edad[[i]] == "Todas") poblacion$edad[[i]] <- "500" +} + +poblacion$edad <- as.numeric(poblacion$edad) +``` + +```{r} +# Tabla de frecuencias de los datos +table(poblacion$edad) +table(poblacion$sexo) +table(poblacion$prov) +table(poblacion$Anyo, poblacion$T3_Periodo) +``` + +# 3. Ejemplo de uso + +```{r grafico final} +datos <- subset(poblacion, poblacion$edad != 500 & poblacion$prov == "Granada" & poblacion$sexo != "Total") + +library(ggplot2) +qplot(edad, Valor, col = sexo, data = datos, main = "Población por edad simple, por sexos. Varios periodos, Granada.", + facets = Anyo~T3_Periodo, ylim = c(0, max(datos$Valor))) +``` \ No newline at end of file diff --git a/02_descarga_avanzada.html b/02_descarga_avanzada.html new file mode 100644 index 0000000..482920c --- /dev/null +++ b/02_descarga_avanzada.html @@ -0,0 +1,1983 @@ + + + + +
+ + + + + + + + + + +## Warning: package 'dplyr' was built under R version 3.5.3
+
+# Como la URL es:
+# http://ine.es/jaxiT3/Tabla.htm?t=9687&L=0,
+# ponemos el identificador 9678
+# Descargamos sin metadatos para que sea más rápido
+url <- "http://servicios.ine.es/wstempus/js/ES/DATOS_TABLA/9687?nult=6&tip=A"
+poblacion_json <- GET(url)
Parece que la descarga ha sido exitosa:
+ +## [1] 200
+pero
+ +## [1] "Petición en proceso. Actualice página pasados unos minutos."
+así que solicitamos la información hasta que es descargada con éxito:
+i <- 0
+while(is.null(content(poblacion_json)$status) == FALSE){
+ i <- i + 1
+ cat("Durmiendo...")
+ Sys.sleep(5)
+ cat(" Obteniendo información, puede tardar unos minutos... \n")
+ poblacion_json <- GET(url)
+ ifelse(is.null(content(poblacion_json)$status) == TRUE,
+ print(paste0("Intento nº", i, ": Archivo descargado.")),
+ print(paste0("Intento nº", i, ": ", content(poblacion_json)$status)))
+}
## Durmiendo... Obteniendo información, puede tardar unos minutos...
+## [1] "Intento nº1: Petición en proceso. Actualice página pasados unos minutos."
+## Durmiendo... Obteniendo información, puede tardar unos minutos...
+## [1] "Intento nº2: Archivo descargado."
+Extraemos la información necesaria (sexo, edad, provincia) que se encuentran dentro de un mismo campo. Usamos strsplit
para dividir la información y seleccionar la componente necesaria.
poblacion_contenido <- content(poblacion_json)
+n <- length(poblacion_contenido)
+
+for(i in 1:n){
+ dato.i <- poblacion_contenido[[i]]$Data
+ division <- strsplit(paste(poblacion_contenido[[i]]$Nombre), split = ". ", fixed = T)[[1]]
+ poblacion.i <- dato.i %>% list.select(T3_Periodo, Anyo, Valor) %>% list.stack %>%
+ cbind(edad = division[1]) %>%
+ cbind(sexo = division[3]) %>%
+ cbind(prov = division[2])
+ ifelse(i == 1, poblacion <- poblacion.i, poblacion <- rbind(poblacion, poblacion.i))
+}
##
+## Total Nacional Todas las edades 0 años 1 año
+## 1818 936 936 936
+## 2 años 3 años 4 años 5 años
+## 936 936 936 936
+## 6 años 7 años 8 años 9 años
+## 936 936 936 936
+## 10 años 11 años 12 años 13 años
+## 936 936 936 936
+## 14 años 15 años 16 años 17 años
+## 936 936 936 936
+## 18 años 19 años 20 años 21 años
+## 936 936 936 936
+## 22 años 23 años 24 años 25 años
+## 936 936 936 936
+## 26 años 27 años 28 años 29 años
+## 936 936 936 936
+## 30 años 31 años 32 años 33 años
+## 936 936 936 936
+## 34 años 35 años 36 años 37 años
+## 936 936 936 936
+## 38 años 39 años 40 años 41 años
+## 936 936 936 936
+## 42 años 43 años 44 años 45 años
+## 936 936 936 936
+## 46 años 47 años 48 años 49 años
+## 936 936 936 936
+## 50 años 51 años 52 años 53 años
+## 936 936 936 936
+## 54 años 55 años 56 años 57 años
+## 936 936 936 936
+## 58 años 59 años 60 años 61 años
+## 936 936 936 936
+## 62 años 63 años 64 años 65 años
+## 936 936 936 936
+## 66 años 67 años 68 años 69 años
+## 936 936 936 936
+## 70 años 71 años 72 años 73 años
+## 936 936 936 936
+## 74 años 75 años 76 años 77 años
+## 936 936 936 936
+## 78 años 79 años 80 años 81 años
+## 936 936 936 936
+## 82 años 83 años 84 años 85 años
+## 936 936 936 936
+## 86 años 87 años 88 años 89 años
+## 936 936 936 936
+## 90 años 91 años 92 años 93 años
+## 936 936 936 936
+## 94 años 95 años 96 años 97 años
+## 936 936 936 936
+## 98 años 99 años 100 y más años
+## 936 936 954
+
+##
+## Total Hombres Mujeres
+## 32436 32436 32436
+
+##
+## Todas las edades Albacete Alicante/Alacant
+## 18 1836 1836
+## Almería Araba/Álava Asturias
+## 1836 1836 1836
+## Ávila Badajoz Balears, Illes
+## 1836 1836 1836
+## Barcelona Bizkaia Burgos
+## 1836 1836 1836
+## Cáceres Cádiz Cantabria
+## 1836 1836 1836
+## Castellón/Castelló Ciudad Real Córdoba
+## 1836 1836 1836
+## Coruña, A Cuenca Gipuzkoa
+## 1836 1836 1836
+## Girona Granada Guadalajara
+## 1836 1836 1836
+## Huelva Huesca Jaén
+## 1836 1836 1836
+## León Lleida Lugo
+## 1836 1836 1836
+## Madrid Málaga Murcia
+## 1836 1836 1836
+## Navarra Ourense Palencia
+## 1836 1836 1836
+## Palmas, Las Pontevedra Rioja, La
+## 1836 1836 1836
+## Salamanca Santa Cruz de Tenerife Segovia
+## 1836 1836 1836
+## Sevilla Soria Tarragona
+## 1836 1836 1836
+## Teruel Toledo Valencia/València
+## 1836 1836 1836
+## Valladolid Zamora Zaragoza
+## 1836 1836 1836
+## Ceuta Melilla 0 años
+## 1836 1836 18
+## 1 año 2 años 3 años
+## 18 18 18
+## 4 años 5 años 6 años
+## 18 18 18
+## 7 años 8 años 9 años
+## 18 18 18
+## 10 años 11 años 12 años
+## 18 18 18
+## 13 años 14 años 15 años
+## 18 18 18
+## 16 años 17 años 18 años
+## 18 18 18
+## 19 años 20 años 21 años
+## 18 18 18
+## 22 años 23 años 24 años
+## 18 18 18
+## 25 años 26 años 27 años
+## 18 18 18
+## 28 años 29 años 30 años
+## 18 18 18
+## 31 años 32 años 33 años
+## 18 18 18
+## 34 años 35 años 36 años
+## 18 18 18
+## 37 años 38 años 39 años
+## 18 18 18
+## 40 años 41 años 42 años
+## 18 18 18
+## 43 años 44 años 45 años
+## 18 18 18
+## 46 años 47 años 48 años
+## 18 18 18
+## 49 años 50 años 51 años
+## 18 18 18
+## 52 años 53 años 54 años
+## 18 18 18
+## 55 años 56 años 57 años
+## 18 18 18
+## 58 años 59 años 60 años
+## 18 18 18
+## 61 años 62 años 63 años
+## 18 18 18
+## 64 años 65 años 66 años
+## 18 18 18
+## 67 años 68 años 69 años
+## 18 18 18
+## 70 años 71 años 72 años
+## 18 18 18
+## 73 años 74 años 75 años
+## 18 18 18
+## 76 años 77 años 78 años
+## 18 18 18
+## 79 años 80 años 81 años
+## 18 18 18
+## 82 años 83 años 84 años
+## 18 18 18
+## 85 años 86 años 87 años
+## 18 18 18
+## 88 años 89 años 90 años
+## 18 18 18
+## 91 años 92 años 93 años
+## 18 18 18
+## 94 años 95 años 96 años
+## 18 18 18
+## 97 años 98 años 99 años
+## 18 18 18
+## Total Nacional
+## 18
+
+##
+## 1 de enero de 1 de julio de
+## 2016 0 16218
+## 2017 16218 16218
+## 2018 16218 16218
+## 2019 16218 0
+Hemos observado que hay un error en los datos que hace que, a veces, cuando prov es “Total Nacional”, aparece la edad en el campo prov y la provincia en el campo edad. Lo arreglamos.
+poblacion$prov <- as.character(poblacion$prov)
+poblacion$edad <- as.character(poblacion$edad)
+
+# m = n * número de periodos añadidos, se desdobla la lista
+m <- nrow(poblacion)
+m
## [1] 97308
+for(i in 1:m){
+ if(poblacion$edad[[i]] == "Total Nacional"){
+ poblacion$edad[[i]] = poblacion$prov[[i]]
+ poblacion$prov[[i]] = "Total Nacional"
+ }
+}
+
+# Trabajamos con la edad (500 será nuestro código para el total)
+for(i in 1:m){
+ poblacion$edad[[i]] <- strsplit(poblacion$edad[[i]], " ")[[1]][1]
+ if(poblacion$edad[[i]] == "Todas") poblacion$edad[[i]] <- "500"
+}
+
+poblacion$edad <- as.numeric(poblacion$edad)
##
+## 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
+## 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954
+## 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
+## 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954
+## 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
+## 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954
+## 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
+## 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954
+## 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
+## 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954 954
+## 90 91 92 93 94 95 96 97 98 99 100 500
+## 954 954 954 954 954 954 954 954 954 954 954 954
+
+##
+## Total Hombres Mujeres
+## 32436 32436 32436
+
+##
+## Albacete Alicante/Alacant Almería
+## 1836 1836 1836
+## Araba/Álava Asturias Ávila
+## 1836 1836 1836
+## Badajoz Balears, Illes Barcelona
+## 1836 1836 1836
+## Bizkaia Burgos Cáceres
+## 1836 1836 1836
+## Cádiz Cantabria Castellón/Castelló
+## 1836 1836 1836
+## Ceuta Ciudad Real Córdoba
+## 1836 1836 1836
+## Coruña, A Cuenca Gipuzkoa
+## 1836 1836 1836
+## Girona Granada Guadalajara
+## 1836 1836 1836
+## Huelva Huesca Jaén
+## 1836 1836 1836
+## León Lleida Lugo
+## 1836 1836 1836
+## Madrid Málaga Melilla
+## 1836 1836 1836
+## Murcia Navarra Ourense
+## 1836 1836 1836
+## Palencia Palmas, Las Pontevedra
+## 1836 1836 1836
+## Rioja, La Salamanca Santa Cruz de Tenerife
+## 1836 1836 1836
+## Segovia Sevilla Soria
+## 1836 1836 1836
+## Tarragona Teruel Toledo
+## 1836 1836 1836
+## Total Nacional Valencia/València Valladolid
+## 1836 1836 1836
+## Zamora Zaragoza
+## 1836 1836
+
+##
+## 1 de enero de 1 de julio de
+## 2016 0 16218
+## 2017 16218 16218
+## 2018 16218 16218
+## 2019 16218 0
+datos <- subset(poblacion, poblacion$edad != 500 & poblacion$prov == "Granada" & poblacion$sexo != "Total")
+
+library(ggplot2)
+qplot(edad, Valor, col = sexo, data = datos, main = "Población por edad simple, por sexos. Varios periodos, Granada.",
+ facets = Anyo~T3_Periodo, ylim = c(0, max(datos$Valor)))