¡Hola! En este cuarto encuentro trabajaremos con dos bases de datos; con la Encuesta Anual de Hogares de CABA y el CENSO 2010. Este último condensa información según radios censales, mínima expresión de un espacio territorial con limites geográficos y una determinada cantidad de unidades de viviendas a relevar. Cada unidad politico administrativa se desagrega en fracción y cada una de ellas en radios.
Para profundizar en sus definiciones: https://geoservicios.indec.gov.ar/codgeo/index.php?pagina=definiciones#:~:text=Fracci%C3%B3n%20y%20Radio%3A,unidades%20de%20viviendas%20a%20relevar.
Las funciones que utilizaremos vendrán de los paquetes tidyverse y data.table. Si bien este último tiene múltiples funciones para facilitar y agilizar la manipulación de datos, en este encuentro solo utilizaremos la función para levantar bases más rápido y sin tener que referenciarle qué tipo de archivo es.
# install.packages("data.table")
library(data.table)
library(tidyverse)
eah <- fread("https://cdn.buenosaires.gob.ar/datosabiertos/datasets/direccion-general-de-estadisticas-y-censos/encuesta-anual-hogares/encuesta-anual-hogares-2019.csv", header = TRUE, encoding = "Latin-1")
# Este data set ya está filtrado según el territorio de la CABA
censo <- fread("https://cdn.buenosaires.gob.ar/datosabiertos/datasets/direccion-general-de-estadisticas-y-censos/informacion-censal-por-radio/informacion-censal-por-radio-2010.csv") |>
select(-1)
# Como no vamos a trabajar con la geometria de los radios, los quitamos, ya que de manera contraria seria mucho mas pesado el data set y nos realentizaria el flujo de trabajo
# Portal del dato: https://data.buenosaires.gob.ar/dataset/informacion-censal-por-radio
Supongamos que queremos comparar los resultados de la Encuesta Permanente de Hogares (EAH) de CABA, con 14.319 casos sobre los datos del censo. Precisamente queremos observar y comparar las condiciones socioeconomicas de los hogares según la muestra y el censo en cada una de las comunas. Y a eso le sumamos que el producto final sea una única tabla. Para ello:
Una observación. Cada base posee un nivel de desagregación distinto. Mientras que la eah tiene los datos referidos a cada_hogar, el censo posee los datos relativos a cada radio censal. Con la eah no sabemos con detalle su ubicación geográfica dentro de las comunas, pero sí tenemos el detalle de cada hogar. Con la forma en que está presentada la base del censo, no tenemos el detalle de cada hogar pero sí la cantidad de hogares por radio censal.
¿A qué les hace pensar esto respecto a los datos que contienen ambas tablas? ¿Los condiciona para querer comparar ciertos datos?
str(censo)
head(censo)
summary(censo)
# ¿Cuál de estas funciones les parece mas útil para explorar la tabla?
# La base del censo contiene información que va desde al id del código de fracción, el radio, la comuna, y los datos agrupados de las viviendas y los hogares
# Estamos ante dos tablas con diferencias entre sus estructuras. Mientras que:
# eah tiene 14.319 casos con 31 variables (campos/columnas)
# censo tiene 3554 con 14 variables (campos/columnas)
# A ello se suma que:
# los datos de eah están desagregados por cada uno de los hogares, con información sobre condiciones sociodemograficas y económicas
# los datos de censo están agregados según radios, fracción y comuna
Partiremos de que nos interesa observar las columnas referentes a las Necesidades Básicas Insatisfechas (NBI)
Entre los indicadores que lo componen están: a) Acceso a una vivienda que asegure un estandar minimo de habitabilidad para el hogar
Acceso a servicios básicos que aseguren un nivel sanitario adecuado
Acceso a educación básica
Capacidad económica para alcanzar niveles mínimos de consumo
Para más información: https://repositorio.cepal.org/bitstream/handle/11362/4784/S0102117_es.pdf?sequence
Sin embargo, al querer comparar “las mismas variables” según el factor temporal en una misma población, tendremos que ser un poco creativxs con el data set de eah, ya que en censo las variables de NBI ya están agrupadas.
Como de la eah no hay información sobre las condiciones de la vivienda o del nivel sanitario, podemos tomar las referidas al niveleducativo y la capacidad económica 1) Ultimo nivel educativo aprobado 2) Condición de actividad
Exploremos sus categorias.
unique(eah$estado_ocupacional)
## [1] "Inactivo" "Ocupado" "Desocupado"
#esta parece facil para trabajar. Podemos separa en población activa e inactiva
unique(eah$nivel_max_educativo)
## [1] "Otras escuelas especiales" "Secundario/medio comun"
## [3] "EGB (1° a 9° año)" "Primario especial"
## [5] "" "Primario comun"
## [7] "Sala de 5" "No corresponde"
# Como hay varias categorías podríamos unificarla en algunas
# Y quitaremos aquellos valores "" como los valores "No corresponde" ya que nos nos interesa analizarlos en este caso.
¿Qué haremos con la primera base, eah?
Seleccionaremos las columnas con las que trabajaremos
Filtraremos aquellos casos que no nos interesan
Debemos unificar según algún criterios las categorías. Para ello utilizaremos el mutate() y el case_when() aplicados sobre la misma variable
Agruparemos los datos según las comunas
Pediremos un resumen estadístico que sume aquellos casos, por comuna, y que cumplan X condición
eah_agrupado <- eah |>
select(comuna,estado_ocupacional,nivel_max_educativo) |>
filter(!nivel_max_educativo %in% c("No corresponde", "","Otras escuelas especiales")) |>
mutate(nivel_max_educativo=case_when(nivel_max_educativo %in% c("Secundario/medio comun", "EGB (1° a 9° año)")~"Secundario",
nivel_max_educativo %in% c("Primario especial","Primario comun")~"Primario",
nivel_max_educativo=="Sala de 5"~"Salita")) |>
group_by(comuna) |>
summarise(pob_activa_2019=sum(estado_ocupacional %in% c("Ocupado","Desocupado")),
pob_inactiva_2019=sum(estado_ocupacional=="Inactivo"),
secundario_completo_2019=sum(nivel_max_educativo=="Secundario"),
secundario_incompleto_2019=sum(nivel_max_educativo %in% c("Primario", "Salita")))
¡Bien! Ya logramos limpiar y ordenar los datos de la eah.
Ahora pasemos al censo.
Seleccionaremos las columnas con las que trabajaremos
Agruparemos según comunas
Pediremos un informe estadístico
censo_agrupado <- censo |>
select(COMUNA, TOTAL_POB, T_HOGAR, H_CON_NBI, H_SIN_NBI) |>
group_by(COMUNA) |>
summarise(total_pob=sum(TOTAL_POB),
h_con_nbi=sum(H_CON_NBI),
h_s_nbi=sum(H_SIN_NBI))
¡Genial! Ya logramos limpiar y ordenar los datos del censo
¿Qué tienen en comuna el data set del censo y de la eah?
str(censo_agrupado)
## tibble [15 × 4] (S3: tbl_df/tbl/data.frame)
## $ COMUNA : int [1:15] 1 2 3 4 5 6 7 8 9 10 ...
## $ total_pob: int [1:15] 205991 157827 187537 218245 179005 176076 220591 187237 161797 166022 ...
## $ h_con_nbi: int [1:15] 13437 1489 9560 9678 4652 1656 7040 6582 2345 2149 ...
## $ h_s_nbi : int [1:15] 71052 71646 70929 66777 72194 73533 74443 51622 54150 59304 ...
str(eah_agrupado)
## tibble [15 × 5] (S3: tbl_df/tbl/data.frame)
## $ comuna : int [1:15] 1 2 3 4 5 6 7 8 9 10 ...
## $ pob_activa_2019 : int [1:15] 542 352 377 558 357 338 479 695 403 319 ...
## $ pob_inactiva_2019 : int [1:15] 383 184 276 453 244 213 355 634 337 236 ...
## $ secundario_completo_2019 : int [1:15] 500 403 358 481 367 352 398 574 353 307 ...
## $ secundario_incompleto_2019: int [1:15] 425 133 295 530 234 199 436 755 387 248 ...
La posibilidad de joinear/combinar tablas esta siempre y cuando ambas compartan contenido en común al menos en una variable; caracteres, valores numéricos, logicos, etc. ¡A ello se suma que la variable que las una debe estar escrita de la misma manera!
Existen distintos tipos de join, tales como: left_join() que pega los valores desde Y a X right_join() que pega los valores de X a Y inner_join() que retiene solo los valores con los coincidentes.
# Si queremos combinar el censo_agrupado y eah_agrupado, debería ser por la columna COMUNAS
# Pero vemos que ambas están escritas de manera distinta!
left_join(censo_agrupado,eah_agrupado,by="COMUNA")
## Error in `left_join()`:
## ! Join columns must be present in data.
## ✖ Problem with `COMUNA`.
head(censo_agrupado)
## # A tibble: 6 × 4
## COMUNA total_pob h_con_nbi h_s_nbi
## <int> <int> <int> <int>
## 1 1 205991 13437 71052
## 2 2 157827 1489 71646
## 3 3 187537 9560 70929
## 4 4 218245 9678 66777
## 5 5 179005 4652 72194
## 6 6 176076 1656 73533
head(eah_agrupado)
## # A tibble: 6 × 5
## comuna pob_activa_2019 pob_inactiva_2019 secundario_completo… secundario_inco…
## <int> <int> <int> <int> <int>
## 1 1 542 383 500 425
## 2 2 352 184 403 133
## 3 3 377 276 358 295
## 4 4 558 453 481 530
## 5 5 357 244 367 234
## 6 6 338 213 352 199
# Para ello debemos elegir segun algun criterio. Nos convendría pasar de la mayuscula a minuscula, ya que en ambos data set todas son minusculas
colnames(censo_agrupado)[1] <- "comuna"
# Otra forma, con tiydyverse, puede ser:
censo_agrupado <- censo_agrupado |>
rename(comuna=COMUNA)
## Error in `chr_as_locations()`:
## ! Can't rename columns that don't exist.
## ✖ Column `COMUNA` doesn't exist.
# Ahora estamos en condiciones de matchear!
left_join(censo_agrupado,eah_agrupado,by="comuna") |> view()
# Pero no creamos nada aun. Ahora es cuando estamos en condiciones de preguntarnos que queremos hacer. Si sobrescribir un objeto, o si creamos otro
agrupado_total <- censo_agrupado |>
left_join(eah_agrupado,by="comuna")
De acuerdo a la tabla generada podemos hacer varios tipos de gráficos:
ggplot(agrupado_total,aes(x=comuna,y=total_pob, size=h_con_nbi)) +
geom_point(alpha=0.5, shape=21, color="black", fill="red") +
scale_x_continuous(breaks = seq(0, 15, 3)) + # estamos asignando la secuencia en la que queremos que aparezcan las categorias. Queremos que empiece en 1 y termine en 15
scale_size(range = c(.1, 24)) + # Definimos la escala
labs(title="Hogares con NBI segmentado por comunas",
subtitle = "y posicionado según tamaño poblacional",
x="Comunas",
y="Total población",
size="Hogares con NBI",
caption = "Elaboración propia") +
theme_bw()+
theme(plot.title=element_text(face="bold",
size=16),
plot.subtitle = element_text(face = "bold.italic",
size=13),
plot.caption = element_text(face="bold",
size=10),
axis.text = element_text(face = "bold",
size = 10),
axis.title = element_text(face="bold",
size = 9,
hjust = 1),
legend.title = element_text(face = "bold",
size = 10),
legend.text = element_text(face = "bold",
size = 10,
vjust = 1))
ggplot(agrupado_total,aes(x=comuna,y=h_con_nbi)) +
geom_col(aes(fill=secundario_incompleto_2019), color="black") +
scale_x_continuous(breaks = seq(1, 15)) +
scale_y_continuous(breaks = seq(0, 15000, 2500))+
scale_fill_viridis_c(direction = 1 ,option = "magma") + # la funcion de scale_fill_viridis tiene muchisimas opciones de colores!
geom_text(aes(label=secundario_incompleto_2019, vjust=-1))+
labs(title = "Hogares con secundario incompleto segmentado por comunas",
subtitle = "Posicionado segun Hogares con NBI",
x="Comuna",
y="Hogares con NBI",
fill="Hogares con Secundario Incompleto",
caption = "Elaboración propia") +
theme_classic()+
theme(plot.title=element_text(face="bold",
size=16),
plot.subtitle = element_text(face = "bold.italic",
size=13),
plot.caption = element_text(face="bold",
size=10),
axis.text = element_text(face = "bold",
size = 10),
axis.title = element_text(face="bold",
size = 9,
hjust = 1),
legend.title = element_text(face = "bold",
size = 10),
legend.text = element_text(face = "bold",
size = 10,
vjust = 1))
En base a esto, ¿qué reflexiones podrían hacer respecto a cada uno de los gráficos? ¿ ¿Les parece que una forma de representación es más clara que otra? ¿Por qué?
Tengan en cuenta la siguiente página para elegir entre las escalas de colores de la paleta Viridis.
https://cran.r-project.org/web/packages/viridis/vignettes/intro-to-viridis.html
Supongamos que de repente se nos ocurre conocer el dato pero desagregado según las regiones geográficas de la ciudad; norte,sur,este,oeste y centro. Pero tenemos el inconveniente de que no lo tenemos creado de antemano, ¡no hay problemas!
Primero lo creeamos con mutate, siguiendo una condicion a partir de los datos de las comunas
Segundo lo graficamos!
# Incorporación de datos
agrupado_total <- agrupado_total |>
mutate(region=case_when(comuna %in% c(12,13,14,15,2)~"norte",
comuna %in% c(1,3) ~ "este",
comuna %in% c(5,6,7) ~ "centro",
comuna %in% c(4,8,9) ~ "sur",
comuna %in% c(10,11) ~ "oeste"))
#¿Qué hicimos?
# Le pedimos a R que nos cree una variable cuyos valores se generen a partir de una condicion;
# Todos aquellos valores dentro del campo comuna que sean 12,13,14,15 y 2 serán la región norte... y así
# Grafico facetado
ggplot(agrupado_total, aes(x=comuna,y=h_con_nbi)) +
geom_col(aes(fill=secundario_incompleto_2019), color="black") +scale_x_continuous(breaks = seq(1, 15)) +
scale_y_continuous(breaks = seq(0, 15000, 2500))+
scale_fill_viridis_c(direction = 1 ,option = "magma") + # la funcion de scale_fill_viridis tiene muchisimas opciones de colores!
geom_text(aes(label=secundario_incompleto_2019, vjust=-.3))+
facet_wrap(~region,nrow = 3, ncol = 2) +
labs(title = "Hogares con secundario incompleto segmentado por comunas",
subtitle = "Posicionado segun Hogares con NBI",
x="Comuna",
y="Hogares con NBI",
fill="Hgoares con Secundario Incompleto",
caption = "Elaboración propia") +
theme_classic()+
theme(plot.title=element_text(face="bold",
size=16),
plot.subtitle = element_text(face = "bold.italic",
size=13),
plot.caption = element_text(face="bold",
size=10),
axis.text = element_text(face = "bold",
size = 10),
axis.title = element_text(face="bold",
size = 9,
hjust = 1),
legend.title = element_text(face = "bold",
size = 10),
legend.text = element_text(face = "bold",
size = 10,
vjust = 1))
En base a la experiencia de descarga, manipulación, unión y representación de bases, les proponemos que se animen a incorporar otra variable. Pueden descargarla de otra base o crearla de acuerdo a X condición.
Luego pueden representarla mediante cualquiera de los gráficos que vimos en estos encuentros; de barras, puntos, histogramas, los que quieran
Sobre estos pueden asignarle los colores que deseen, así como el título y toda la información que crean pertinente para describir al gráfico
¡Exitos y un gusto que hayamos trabajado juntxs estos cuato encuentros!
Mauro Iuvaro.-