Vamos a ver algunas funciones interesantes que se encuentran en la librería tidyverse. En primer lugar, vamos a activar el paquete.
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.0.2
## -- Attaching packages ------------------------------------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.2 v purrr 0.3.4
## v tibble 3.0.1 v dplyr 0.8.5
## v tidyr 1.0.3 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.5.0
## Warning: package 'ggplot2' was built under R version 4.0.2
## -- Conflicts ---------------------------------------------------------------------- tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
Recuerden que el paquete tiene que estar instalado. Para instalarlo (se hace una única vez), pueden utilizar la función install.packages(“tidyverse”).
Vamos a utilizar una base de datos de Gobierno de la Ciudad de Buenos Aires sobre información por radio según CENSO 2010.
censo2010 <- read.csv("https://cdn.buenosaires.gob.ar/datosabiertos/datasets/informacion-censal-por-radio/informacion-censal-por-radio-2010.csv", sep = ";", encoding = "UTF-8") %>%
select(-(1:4))
Veamos rápidamente que contiene el dataset.
head(censo2010)
## COMUNA FRACCION RADIO TOTAL_POB T_VARON T_MUJER I_MASCULINIDAD T_VIVIENDA
## 1 COMUNA 1 1 1 336 212 124 170,97% 82
## 2 COMUNA 1 12 1 341 184 157 117,20% 365
## 3 COMUNA 1 12 10 296 162 134 120,90% 629
## 4 COMUNA 1 12 11 528 294 234 125,64% 375
## 5 COMUNA 1 12 2 229 101 128 78,91% 445
## 6 COMUNA 1 12 3 723 374 349 107,16% 744
## V_PARTICUL V_PARTICUL_POR V_COLECTIV V_COLECTIV_POR T_HOGAR H_CON_NBI
## 1 80 97,56% 2 2,50% 65 19
## 2 361 98,90% 4 1,11% 116 25
## 3 627 99,68% 2 0,32% 101 1
## 4 370 98,67% 5 1,35% 136 7
## 5 445 100,00% 0 0,00% 129 16
## 6 739 99,33% 5 0,68% 314 104
## H_CON_NBI_POR H_SIN_NBI H_SIN_NBI_POR
## 1 29,23% 46 70,77%
## 2 21,55% 91 78,45%
## 3 0,99% 100 99,01%
## 4 5,15% 129 94,85%
## 5 12,40% 113 87,60%
## 6 33,12% 210 66,88%
La función factor() permite transformar el contenido de un vector en factor (variable categórica). Dentro de esta función, se puede usar levels que permite configurar los niveles de mis categorías, es decir en que orden las quiero.
Hagamos un primer gráfico sobre la población por Comuna.
censo2010 %>%
ggplot() +
geom_bar(aes(x = COMUNA, weight = TOTAL_POB, fill = COMUNA)) +
labs(title = "Población según Censo 2010",
x = "Comuna",
y = "Población") +
coord_flip() +
theme_minimal() +
theme(legend.position = "none")
Hay algunas cosas para mejorar:
1. Nos gustaría que las Comunas estén ordenadas
2. Vamos a filtrar 13 porque no se condice con la forma que tiene la variable “Comuna”.
censo2010 %>%
filter(COMUNA != 13) %>%
mutate(comuna_ordenada = factor(COMUNA, levels = c("COMUNA 1", "COMUNA 2", "COMUNA 3", "COMUNA 4", "COMUNA 5", "COMUNA 6", "COMUNA 7", "COMUNA 8", "COMUNA 9", "COMUNA 10", "COMUNA 11", "COMUNA 12", "COMUNA 13", "COMUNA 14", "COMUNA 15"))) %>%
ggplot() +
geom_bar(aes(x = comuna_ordenada, weight = TOTAL_POB, fill = comuna_ordenada)) +
labs(title = "Población según Censo 2010",
x = "Comuna",
y = "Población") +
coord_flip() +
theme_minimal() +
theme(legend.position = "none")
Mucho mejor!
La función left_join() permite unir diferentes datasets. Se puede configurar para unir según alguna variable en particular.
Vamos a generar dos datasets:
- Cantidad de radios censales en una comuna
- Población total en la comuna
Se podría haber resuelto todo en el mismo código con summarise(), sin embargo el objetivo es utilizar left_join().
cant_radios <- censo2010 %>%
group_by(COMUNA) %>%
summarise(cant = n())
cant_radios
## # A tibble: 16 x 2
## COMUNA cant
## <chr> <int>
## 1 13 1
## 2 COMUNA 1 330
## 3 COMUNA 10 197
## 4 COMUNA 11 229
## 5 COMUNA 12 226
## 6 COMUNA 13 305
## 7 COMUNA 14 294
## 8 COMUNA 15 238
## 9 COMUNA 2 197
## 10 COMUNA 3 254
## 11 COMUNA 4 252
## 12 COMUNA 5 218
## 13 COMUNA 6 215
## 14 COMUNA 7 250
## 15 COMUNA 8 162
## 16 COMUNA 9 186
poblacion <- censo2010 %>%
group_by(COMUNA) %>%
summarise(pop = sum(TOTAL_POB))
poblacion
## # A tibble: 16 x 2
## COMUNA pop
## <chr> <int>
## 1 13 568
## 2 COMUNA 1 205991
## 3 COMUNA 10 166022
## 4 COMUNA 11 189832
## 5 COMUNA 12 200116
## 6 COMUNA 13 230763
## 7 COMUNA 14 225970
## 8 COMUNA 15 182574
## 9 COMUNA 2 157827
## 10 COMUNA 3 187537
## 11 COMUNA 4 218245
## 12 COMUNA 5 179005
## 13 COMUNA 6 176076
## 14 COMUNA 7 220591
## 15 COMUNA 8 187237
## 16 COMUNA 9 161797
Ahora vamos a unir los dos datasets
resumen_comuna <- left_join(cant_radios, poblacion, by = "COMUNA")
resumen_comuna
## # A tibble: 16 x 3
## COMUNA cant pop
## <chr> <int> <int>
## 1 13 1 568
## 2 COMUNA 1 330 205991
## 3 COMUNA 10 197 166022
## 4 COMUNA 11 229 189832
## 5 COMUNA 12 226 200116
## 6 COMUNA 13 305 230763
## 7 COMUNA 14 294 225970
## 8 COMUNA 15 238 182574
## 9 COMUNA 2 197 157827
## 10 COMUNA 3 254 187537
## 11 COMUNA 4 252 218245
## 12 COMUNA 5 218 179005
## 13 COMUNA 6 215 176076
## 14 COMUNA 7 250 220591
## 15 COMUNA 8 162 187237
## 16 COMUNA 9 186 161797
Supongamos ahora que las variables a unir se llaman distinto y vamos a filtrar la comuna que se llama solo 13.
cant_radios2 <- censo2010 %>%
filter(COMUNA != 13) %>%
rename(com =COMUNA) %>%
group_by(com) %>%
summarise(cant = n())
cant_radios2
## # A tibble: 15 x 2
## com cant
## <chr> <int>
## 1 COMUNA 1 330
## 2 COMUNA 10 197
## 3 COMUNA 11 229
## 4 COMUNA 12 226
## 5 COMUNA 13 305
## 6 COMUNA 14 294
## 7 COMUNA 15 238
## 8 COMUNA 2 197
## 9 COMUNA 3 254
## 10 COMUNA 4 252
## 11 COMUNA 5 218
## 12 COMUNA 6 215
## 13 COMUNA 7 250
## 14 COMUNA 8 162
## 15 COMUNA 9 186
Nuevamente vamos a unir los datasets
resumen_comuna2 <- left_join(cant_radios2, poblacion, by = c("com" = "COMUNA"))
resumen_comuna2
## # A tibble: 15 x 3
## com cant pop
## <chr> <int> <int>
## 1 COMUNA 1 330 205991
## 2 COMUNA 10 197 166022
## 3 COMUNA 11 229 189832
## 4 COMUNA 12 226 200116
## 5 COMUNA 13 305 230763
## 6 COMUNA 14 294 225970
## 7 COMUNA 15 238 182574
## 8 COMUNA 2 197 157827
## 9 COMUNA 3 254 187537
## 10 COMUNA 4 252 218245
## 11 COMUNA 5 218 179005
## 12 COMUNA 6 215 176076
## 13 COMUNA 7 250 220591
## 14 COMUNA 8 162 187237
## 15 COMUNA 9 186 161797
¿Que observamos?
En primer lugar es necesario concatenar los valores por los cuales queremos unir con c(). El primer nombre “com” corresponde a la variable comuna de nuestro dataset cant_radios2 y “COMUNA” corresponde al nombre de la variable en nuestro dataset poblacion.
Tampoco vemos la comuna que se llama solo 13. ¿Por qué? Porque left_join() toma como base el dataset cant_radios2 (el dataset de la izquierda).
Probemos con right_join().
resumen_comuna3 <- right_join(cant_radios2, poblacion, by = c("com" = "COMUNA"))
resumen_comuna3
## # A tibble: 16 x 3
## com cant pop
## <chr> <int> <int>
## 1 13 NA 568
## 2 COMUNA 1 330 205991
## 3 COMUNA 10 197 166022
## 4 COMUNA 11 229 189832
## 5 COMUNA 12 226 200116
## 6 COMUNA 13 305 230763
## 7 COMUNA 14 294 225970
## 8 COMUNA 15 238 182574
## 9 COMUNA 2 197 157827
## 10 COMUNA 3 254 187537
## 11 COMUNA 4 252 218245
## 12 COMUNA 5 218 179005
## 13 COMUNA 6 215 176076
## 14 COMUNA 7 250 220591
## 15 COMUNA 8 162 187237
## 16 COMUNA 9 186 161797
Ahora no hay valores para en cant para la Comuna que se llama solo 13.
Existen otras funciones como inner_join(), full_join(), anti_join(), etc.
Esta función permite extraer partes de un vector de tipo caracter.
class(censo2010$COMUNA)
## [1] "character"
Perfecto! Esta variable sirve. Veamos de que se trata.
table(censo2010$COMUNA)
##
## 13 COMUNA 1 COMUNA 10 COMUNA 11 COMUNA 12 COMUNA 13 COMUNA 14 COMUNA 15
## 1 330 197 229 226 305 294 238
## COMUNA 2 COMUNA 3 COMUNA 4 COMUNA 5 COMUNA 6 COMUNA 7 COMUNA 8 COMUNA 9
## 197 254 252 218 215 250 162 186
Vamos a trabajar con las comunas 10, 11 y 12 y su población.
comunas_seleccion <- poblacion %>%
filter(COMUNA %in% c("COMUNA 10", "COMUNA 11", "COMUNA 12"))
comunas_seleccion
## # A tibble: 3 x 2
## COMUNA pop
## <chr> <int>
## 1 COMUNA 10 166022
## 2 COMUNA 11 189832
## 3 COMUNA 12 200116
Queremos armar una nueva variable que tome solamente los números de las comunas. Para eso vamos a usar la función substr().
comunas_seleccion <- comunas_seleccion %>%
mutate(numero_com = substr(COMUNA,8,9))
comunas_seleccion
## # A tibble: 3 x 3
## COMUNA pop numero_com
## <chr> <int> <chr>
## 1 COMUNA 10 166022 10
## 2 COMUNA 11 189832 11
## 3 COMUNA 12 200116 12
¿Cómo funciona substr()? Sustrae de la variable COMUNA los caracteres que están desde la posición 8 hasta la posición 9.
Estas dos funciones permiten generar argumentos condicionales.
Empecemos con ifelse(). Vamos a utilizar esta función para corregir la comuna que se llama solo “13”. Queremos que si la variable COMUNA toma el valor 13, entonces nuestra nueva variable tome valor “COMUNA 13”, y si no que tome el valor que tenia la variable COMUNA.
censo2010_corregido <- mutate(censo2010,
comuna_ok = ifelse(COMUNA == "13", "COMUNA 13", COMUNA) )
table(censo2010_corregido$comuna_ok)
##
## COMUNA 1 COMUNA 10 COMUNA 11 COMUNA 12 COMUNA 13 COMUNA 14 COMUNA 15 COMUNA 2
## 330 197 229 226 306 294 238 197
## COMUNA 3 COMUNA 4 COMUNA 5 COMUNA 6 COMUNA 7 COMUNA 8 COMUNA 9
## 254 252 218 215 250 162 186
Ahora todas nuestras comunas están bien escritas. Notese que el 13 está puesto entre " " ya que la variable COMUNA es de tipo caracter.
Ahora vamos a utilizar case_when(). Al igual que ifelse() permite escribir argumentos condicionales. Si bien la sintaxis de case_when() es un poco más compleja, permite realizar más categorías.
Vamos a volver a extraer las comunas. Como tenemos comunas de 1 dígito y comunas de 2 dígitos necesitamos extraer posiciones distintas del vector. Para eso utilizaremos case_when(). Vamos a utilizar el dataset resumen_comuna que generamos antes.
resumen_comuna
## # A tibble: 16 x 3
## COMUNA cant pop
## <chr> <int> <int>
## 1 13 1 568
## 2 COMUNA 1 330 205991
## 3 COMUNA 10 197 166022
## 4 COMUNA 11 229 189832
## 5 COMUNA 12 226 200116
## 6 COMUNA 13 305 230763
## 7 COMUNA 14 294 225970
## 8 COMUNA 15 238 182574
## 9 COMUNA 2 197 157827
## 10 COMUNA 3 254 187537
## 11 COMUNA 4 252 218245
## 12 COMUNA 5 218 179005
## 13 COMUNA 6 215 176076
## 14 COMUNA 7 250 220591
## 15 COMUNA 8 162 187237
## 16 COMUNA 9 186 161797
resumen_comuna <- resumen_comuna %>%
mutate(nro_comuna = case_when(
COMUNA == "13"
~ "13",
COMUNA %in% c("COMUNA 1", "COMUNA 2", "COMUNA 3", "COMUNA 4", "COMUNA 5", "COMUNA 6", "COMUNA 7", "COMUNA 8", "COMUNA 9")
~ substr(COMUNA, 8,8),
COMUNA %in% c( "COMUNA 10", "COMUNA 11", "COMUNA 12", "COMUNA 13", "COMUNA 14", "COMUNA 15")
~ substr(COMUNA, 8,9)
))
resumen_comuna
## # A tibble: 16 x 4
## COMUNA cant pop nro_comuna
## <chr> <int> <int> <chr>
## 1 13 1 568 13
## 2 COMUNA 1 330 205991 1
## 3 COMUNA 10 197 166022 10
## 4 COMUNA 11 229 189832 11
## 5 COMUNA 12 226 200116 12
## 6 COMUNA 13 305 230763 13
## 7 COMUNA 14 294 225970 14
## 8 COMUNA 15 238 182574 15
## 9 COMUNA 2 197 157827 2
## 10 COMUNA 3 254 187537 3
## 11 COMUNA 4 252 218245 4
## 12 COMUNA 5 218 179005 5
## 13 COMUNA 6 215 176076 6
## 14 COMUNA 7 250 220591 7
## 15 COMUNA 8 162 187237 8
## 16 COMUNA 9 186 161797 9
También podríamos usar esta función para clasificar alguna variable.
summary(censo2010$TOTAL_POB)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.0 646.2 786.0 813.2 928.0 3945.0
censo2010 <- censo2010 %>%
mutate(categoria_pob = case_when(
TOTAL_POB < 646.2 ~ "Dentro del 1er cuartil",
TOTAL_POB > 928.0 ~ "Dentro del 3er cuartil",
TRUE ~ "Otros valores"
))
Se utiliza TRUE para los argumentos que son siempre válidos (es decir que no se encuadraron en las categorías anteriores).
Una aclaración: la función primero revisa la primer condición, si no la cumple, pasa a la segunda y así sucesivamente. Es decir que si cumple con el 1er y el 3er argumento, tomará el valor valor del 1er argumento.
censo2010 %>%
group_by(categoria_pob) %>%
summarise(cantidad= n())
## # A tibble: 3 x 2
## categoria_pob cantidad
## <chr> <int>
## 1 Dentro del 1er cuartil 889
## 2 Dentro del 3er cuartil 888
## 3 Otros valores 1777
Estas funciones permiten manipular los datasets y obtener nueva información. Los invito a probar utilizarlas.