install.packages("tidyverse")Taller R UAH 2024 C2
Profesor: Alonso Quezada
Introducción al trabajo con datos
Tidyverse
Antes de importar datos, es necesario instalar la paquetería Tidyverse. Los paquetes del Tidyverse comparten una filosofía acerca de los datos y la programación en R, y están diseñados para trabajar juntos con naturalidad. Su nombre viene de la palabra en inglés “tidy”, que quiere decir “ordenado”.
Puedes instalar el tidyverse completo con una sola línea de código:
No podrás usar las funciones, objetos y archivos de ayuda de un paquete hasta que lo hayas cargado con library(). Una vez que has instalado un paquete, puedes cargarlo con la función library():
library(tidyverse)── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.2 ✔ readr 2.1.4
✔ forcats 1.0.0 ✔ stringr 1.5.0
✔ ggplot2 3.4.4 ✔ tibble 3.2.1
✔ lubridate 1.9.3 ✔ tidyr 1.3.0
✔ purrr 1.0.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
El tidyverse es un conjunto de paquetes en R diseñados para la ciencia de datos que comparten una filosofía común y están diseñados para trabajar juntos de manera cohesiva. Desarrollado por Hadley Wickham y otros, tidyverse incluye paquetes para la manipulación de datos (dplyr, tidyr), visualización de datos (ggplot2), importación de datos (readr, readxl), y muchos otros.
Los Pipes: %>%
El operador pipe %>% es uno de los componentes más emblemáticos y útiles de tidyverse. Este operador, tomado del paquete magrittr (y ahora parte de dplyr), permite encadenar múltiples operaciones sin necesidad de crear variables intermedias. Con %>%, el resultado de una expresión se “pasa” directamente a la siguiente, lo que hace que el código sea más legible y conciso.
Directorio
El directorio siempre se define con el comando setwd() y debe ir entre comillas, en mi caso se vería así: setwd("/Users/alonso/Desktop/Taller R UAH 2024/"). Para verificar cuál es mi directorio actual puedo ejecutar el comando getwd(). Cuando copias la ruta de un directorio (en Windows), es habitual que las carpetas del directorio se separen mediante una barra invertida (\) . Si pegas directamente esta ruta el directorio no se cambiará y la función anterior dará un error. Para solucionarlo, puede utilizar r"(mi directorio)" Lo que se vería así:
setwd(r"(Desktop\Taller R UAH 2024)")
Podemos observar que luego de definir nuestro directorio vamos a poder ver los archivos que hay dentro con el comando list.files()
Cargar bases de Excel a R
Vamos a trabajar con datos electorales de la elección de Alcaldes 2021. Los datos los obtuvimos desde: https://www.servel.cl/centro-de-datos/resultados-electorales-historicos-gw3/.
Para importar datos desde Excel debemos instalar el paquete readxl
install.packages("readxl")Utilizando el paquete readxl importamos el Excel desde la carpeta “datos originales” y nos saltamos las primeras cinco filas del archivo para poder capturar el nombre de las variables.
library(readxl)
X2021_05_Alcaldes <- read_excel("/Users/alonso/Desktop/Taller R UAH 2024/datos originales/2021_05_Alcaldes.xlsx", skip = 5)Guardar en formato Rda
El comando save nos permite guardar un objeto como una base de datos en formato de R en nuestro sistema, para eso especificamos primero el nombre del objeto y luego con file la ruta donde será almacenado.
save(X2021_05_Alcaldes, file = "/Users/alonso/Desktop/Taller R UAH 2024/datos originales/X2021_05_Alcaldes.Rda")Cargar base de datos en formato Rda
Para cargar una base de datos en formato de R debemos utilizar el comando load simplemente añadiendo la ruta del archivo entre comillas.
load("/Users/alonso/Desktop/Taller R UAH 2024/datos originales/X2021_05_Alcaldes.Rda")Primeros Pasos
Imaginemos que fuimos contratados para realizar un análisis de la elección de Alcaldes 2021 en Chile. Para poder abordar el desafío primero debemos explorar la base de datos para entender que información tenemos disponible.
Antes de proceder, existe una librería llamada janitor que contiene una serie de funcionalidades para limpiar datos. Una de sus principales funciones es clean_names() que limpia y estandariza los nombres de las variables de una base de datos de forma inmediata.
install.packages("janitor")Para utilizar clean_names() crearemos un objeto nuevo, para no cometer el error de reemplazar el original, con la misma información de Alcaldes, pero añadiendo la función clean_names().
library(janitor)
Attaching package: 'janitor'
The following objects are masked from 'package:stats':
chisq.test, fisher.test
Alcaldes2021 <- X2021_05_Alcaldes %>%
clean_names()Podrás observar que las variables se estandarizaron en minuscula y separadas por guión bajo.
Histograma
Una buena practica antes de comenzar con las transformaciones de datos es explorar la distribución de las variables. Un histograma es una descripción visual de los datos.
ggplot(Alcaldes2021, aes(x=votos)) +
geom_histogram(bins = 30) +
labs(title = "Histograma de votos", subtitle= "Eleccion de Alcaldes 2021")¿Qué podemos interpretar del histograma de votos? ¿Cuál es nuestra unidad de análisis?
Otra buena practica es obtener los estadisticos descriptivos de resumen de nuestras variables numericas. Si bien esto se podría manualmente con los comandos mean() y median().
mean(Alcaldes2021$votos)[1] 20.00683
median(Alcaldes2021$votos)[1] 11
Existe un paquete llamado summarytools que contiene la función descr() que nos entrega el resumen de toda la estadistica descriptiva facilmente.
install.packages("summarytools")library(summarytools)Warning in system2("/usr/bin/otool", c("-L", shQuote(DSO)),
stdout = TRUE): running command ''/usr/bin/otool' -L
'/Library/Frameworks/R.framework/Resources/library/tcltk/libs//tcltk.so'' had
status 1
Attaching package: 'summarytools'
The following object is masked from 'package:tibble':
view
¿Qué significa que el promedio sea 20 votos y la mediana 11 votos? ¿De que me sirven las unidades de referencias maxima y minimas de votos?
descr(Alcaldes2021 %>%
select(votos), round.digits = 1)Descriptive Statistics
Alcaldes2021$votos
N: 323335
votos
----------------- ----------
Mean 20.0
Std.Dev 24.3
Min 0.0
Q1 2.0
Median 11.0
Q3 29.0
Max 251.0
MAD 14.8
IQR 27.0
CV 1.2
Skewness 1.9
SE.Skewness 0.0
Kurtosis 4.6
N.Valid 323335.0
Pct.Valid 100.0
Manipulación de Datos con dplyr
dplyr es una parte del tidyverse que facilita la manipulación de datos, cuando cargamos tidyverse automaticamente estamos cargando dplyr. Principales funciones:
filter(): Filtrado de filas.select(): Selección de columnas.mutate(): Creación de nuevas columnas.summarize(): Resumen de valores.arrange(): reordenar filas
Filtrando filas con filter()
Filtra la base de datos por aquellas mesas que tengas más de 20 votos.
Alcaldes2021 %>%
filter(votos >= 20)# A tibble: 117,162 × 17
nro_region region circunscripcion_senatorial distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
2 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
3 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
4 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
5 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
6 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
7 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
8 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
9 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
10 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
# ℹ 117,152 more rows
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos <dbl>,
# nominado <chr>
Filtra la base de datos por aquellas mesas que tengas más de 100 votos y menos de 200.
Alcaldes2021 %>%
filter(votos >= 100 & votos<=200)# A tibble: 4,366 × 17
nro_region region circunscripcion_senatorial distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 COLCHANE
2 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 COLCHANE
3 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 COLCHANE
4 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 HUARA
5 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 HUARA
6 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 PICA
7 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 PICA
8 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 PICA
9 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 PICA
10 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 PICA
# ℹ 4,356 more rows
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos <dbl>,
# nominado <chr>
¿Como puede saber que esta bien escrito el codigo?
Alcaldes2021 %>%
filter(votos >= 100 & votos<=200) %>%
descr(votos)Descriptive Statistics
Alcaldes2021$votos
N: 4366
votos
----------------- ---------
Mean 117.14
Std.Dev 16.81
Min 100.00
Q1 105.00
Median 112.00
Q3 124.00
Max 200.00
MAD 13.34
IQR 19.00
CV 0.14
Skewness 1.77
SE.Skewness 0.04
Kurtosis 4.03
N.Valid 4366.00
Pct.Valid 100.00
Como se habrán dado cuenta el comando descr() es posibe utilizarlo dentro de un bloque de codigo utilizando los pipes %>%. Este codigo en particular, primero filtra la base original y luego calcula el resumen de estadisticos descriptivos.
Tambien podemos filtrar exactamente las mesas que obtuvieron 100 votos.
Alcaldes2021 %>%
filter(votos == 100)# A tibble: 228 × 17
nro_region region circunscripcion_senatorial distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 HUARA
2 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 POZO ALMON…
3 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 POZO ALMON…
4 2 DE ANTOFAGASTA CIRCUNSCRIPCION SENATORIAL 3 DISTRITO 3 MEJILLONES
5 3 DE ATACAMA CIRCUNSCRIPCION SENATORIAL 4 DISTRITO 4 CALDERA
6 3 DE ATACAMA CIRCUNSCRIPCION SENATORIAL 4 DISTRITO 4 CALDERA
7 4 DE COQUIMBO CIRCUNSCRIPCION SENATORIAL 5 DISTRITO 5 CANELA
8 4 DE COQUIMBO CIRCUNSCRIPCION SENATORIAL 5 DISTRITO 5 LA HIGUERA
9 4 DE COQUIMBO CIRCUNSCRIPCION SENATORIAL 5 DISTRITO 5 MONTE PATR…
10 5 DE VALPARAISO CIRCUNSCRIPCION SENATORIAL 6 DISTRITO 6 CABILDO
# ℹ 218 more rows
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos <dbl>,
# nominado <chr>
Incluso las mesas que obvieron 100 ó 200 exactamente.
Alcaldes2021 %>%
filter(votos == 100 | votos == 200)# A tibble: 232 × 17
nro_region region circunscripcion_senatorial distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 HUARA
2 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 POZO ALMON…
3 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 POZO ALMON…
4 2 DE ANTOFAGASTA CIRCUNSCRIPCION SENATORIAL 3 DISTRITO 3 MEJILLONES
5 3 DE ATACAMA CIRCUNSCRIPCION SENATORIAL 4 DISTRITO 4 CALDERA
6 3 DE ATACAMA CIRCUNSCRIPCION SENATORIAL 4 DISTRITO 4 CALDERA
7 4 DE COQUIMBO CIRCUNSCRIPCION SENATORIAL 5 DISTRITO 5 CANELA
8 4 DE COQUIMBO CIRCUNSCRIPCION SENATORIAL 5 DISTRITO 5 LA HIGUERA
9 4 DE COQUIMBO CIRCUNSCRIPCION SENATORIAL 5 DISTRITO 5 MONTE PATR…
10 5 DE VALPARAISO CIRCUNSCRIPCION SENATORIAL 6 DISTRITO 6 CABILDO
# ℹ 222 more rows
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos <dbl>,
# nominado <chr>
Lo que vendría siendo lo mismo que utilizar %in% para encontrar valores especificos de las filas dentro de una variable. Así, nos ahorramos de escribir “votos” tantas veces como valores queramos rescatar.
Alcaldes2021 %>%
filter(votos %in% c(100,200))# A tibble: 232 × 17
nro_region region circunscripcion_senatorial distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 HUARA
2 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 POZO ALMON…
3 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 POZO ALMON…
4 2 DE ANTOFAGASTA CIRCUNSCRIPCION SENATORIAL 3 DISTRITO 3 MEJILLONES
5 3 DE ATACAMA CIRCUNSCRIPCION SENATORIAL 4 DISTRITO 4 CALDERA
6 3 DE ATACAMA CIRCUNSCRIPCION SENATORIAL 4 DISTRITO 4 CALDERA
7 4 DE COQUIMBO CIRCUNSCRIPCION SENATORIAL 5 DISTRITO 5 CANELA
8 4 DE COQUIMBO CIRCUNSCRIPCION SENATORIAL 5 DISTRITO 5 LA HIGUERA
9 4 DE COQUIMBO CIRCUNSCRIPCION SENATORIAL 5 DISTRITO 5 MONTE PATR…
10 5 DE VALPARAISO CIRCUNSCRIPCION SENATORIAL 6 DISTRITO 6 CABILDO
# ℹ 222 more rows
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos <dbl>,
# nominado <chr>
Datos perdidos (valores faltantes)
filter() se puede combinar con la función is.na() para encontrar los valores perdidos (Na) en una variable, en este caso, filtramos los valores perdidos de la variable nro_voto. Que es el número de voto que se le asigna al candidato en la papeleta. El resultado señala que tenemos 92.167 observaciones con valores perdidos en la columna nro_voto.
Alcaldes2021 %>%
filter(is.na(nro_voto))# A tibble: 92,167 × 17
nro_region region circunscripcion_senatorial distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
2 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
3 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
4 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
5 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
6 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
7 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
8 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
9 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
10 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
# ℹ 92,157 more rows
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos <dbl>,
# nominado <chr>
Por el contrario, también es posible filtrar la base de datos para quedarnos con toda la información que no contenga valores perdidos, que es lo mismo que decir “toda la información distinta a valores perdidos”.
Alcaldes2021 %>%
filter(!is.na(nro_voto))# A tibble: 231,168 × 17
nro_region region circunscripcion_senatorial distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
2 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
3 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
4 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
5 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
6 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
7 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
8 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
9 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
10 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
# ℹ 231,158 more rows
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos <dbl>,
# nominado <chr>
Reordenar las filas con arrange()
arrange() funciona de manera similar a filter() excepto que en lugar de seleccionar filas, cambia su orden. La función toma un data frame y un conjunto de nombres de columnas (o expresiones más complicadas) para ordenar según ellas. Si proporcionas más de un nombre de columna, cada columna adicional se utilizará para romper empates en los valores de las columnas anteriores:
arrange(Alcaldes2021, votos)# A tibble: 323,335 × 17
nro_region region circunscripcion_senatorial distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
2 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
3 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
4 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
5 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
6 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
7 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
8 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
9 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
10 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
# ℹ 323,325 more rows
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos <dbl>,
# nominado <chr>
Nos referimos a romper empates cuando estas ordenando una columna de menor a mayor y tienes repetido un valor, por ejemplo 24, entonces la siguiente variable añadida en arrange() definira el orden de esas observaciones.
airquality %>% arrange(Solar.R, Wind) Ozone Solar.R Wind Temp Month Day
1 16 7 6.9 74 7 21
2 1 8 9.7 59 5 21
3 23 13 12.0 67 5 28
4 23 14 9.2 71 9 22
5 8 19 20.1 61 5 9
6 14 20 16.6 63 9 25
7 9 24 10.9 71 9 14
8 9 24 13.8 81 8 2
9 4 25 9.7 61 5 23
10 13 27 10.3 76 9 18
11 NA 31 14.9 77 6 29
12 9 36 14.3 72 8 22
13 20 37 9.2 65 6 18
14 11 44 9.7 62 5 20
15 NA 47 10.3 73 6 27
16 7 48 14.3 80 7 15
17 7 49 10.3 69 9 24
18 59 51 6.3 79 8 17
19 NA 59 1.7 76 6 22
20 NA 64 11.5 79 8 15
21 18 65 13.2 58 5 15
22 NA 66 16.6 57 5 25
23 22 71 10.3 77 8 16
24 16 77 7.4 82 8 3
25 6 78 18.4 57 5 18
26 20 81 8.6 82 7 26
27 52 82 12.0 86 7 27
28 39 83 6.9 81 8 1
29 NA 91 4.6 76 6 23
30 32 92 12.0 61 5 24
31 32 92 15.5 84 9 6
32 47 95 7.4 87 9 5
33 NA 98 11.5 80 6 28
34 19 99 13.8 59 5 8
35 NA 101 10.9 84 7 4
36 13 112 11.5 71 9 15
37 23 115 7.4 76 8 18
38 36 118 8.0 72 5 2
39 12 120 11.5 73 6 19
40 NA 127 8.0 78 6 26
41 29 127 9.7 82 6 7
42 18 131 8.0 76 9 29
43 NA 135 8.0 75 6 25
44 13 137 10.3 76 6 20
45 NA 137 11.5 86 8 11
46 NA 138 8.0 83 6 30
47 NA 139 8.6 82 7 11
48 36 139 10.3 81 9 23
49 NA 145 13.2 77 9 27
50 23 148 8.0 82 6 13
51 12 149 12.6 74 5 3
52 NA 150 6.3 77 6 21
53 NA 153 5.7 88 8 27
54 65 157 9.7 80 8 14
55 96 167 6.9 91 9 1
56 64 175 4.6 83 7 5
57 85 175 7.4 89 7 10
58 27 175 14.9 81 7 13
59 73 183 2.8 93 9 3
60 NA 186 9.2 84 6 4
61 79 187 5.1 87 7 19
62 85 188 6.3 94 8 31
63 91 189 4.6 93 9 4
64 41 190 7.4 67 5 1
65 44 190 10.3 78 8 20
66 14 191 14.3 75 9 28
67 21 191 14.9 77 6 16
68 44 192 11.5 86 8 12
69 30 193 6.9 70 9 26
70 NA 194 8.6 69 5 10
71 78 197 5.1 92 9 2
72 16 201 8.0 82 9 20
73 76 203 9.7 97 8 28
74 110 207 8.0 90 8 9
75 45 212 9.7 79 8 24
76 82 213 7.4 88 7 28
77 73 215 8.0 86 8 26
78 NA 220 8.6 85 6 5
79 23 220 10.3 78 9 8
80 63 220 11.5 85 7 20
81 NA 222 8.6 92 8 10
82 115 223 5.7 79 5 30
83 108 223 8.0 85 7 25
84 20 223 11.5 68 9 30
85 18 224 13.8 67 9 17
86 118 225 2.3 94 8 29
87 89 229 10.3 90 8 8
88 21 230 10.9 75 9 9
89 32 236 9.2 81 7 3
90 44 236 14.9 81 9 11
91 84 237 6.3 96 8 30
92 46 237 6.9 78 9 16
93 168 238 3.4 81 8 25
94 28 238 6.3 77 9 13
95 24 238 10.3 68 9 19
96 13 238 12.6 64 9 21
97 NA 242 16.1 67 6 3
98 31 244 10.9 78 8 19
99 49 248 9.2 85 7 2
100 NA 250 6.3 76 6 24
101 NA 250 9.2 92 6 12
102 20 252 10.9 80 9 7
103 45 252 14.9 81 5 29
104 64 253 7.4 83 7 30
105 59 254 9.2 81 7 31
106 122 255 4.0 89 8 7
107 NA 255 12.6 75 8 23
108 16 256 9.7 69 5 12
109 NA 258 9.7 81 7 22
110 24 259 9.7 73 9 10
111 NA 259 10.9 93 6 11
112 21 259 15.5 77 8 21
113 21 259 15.5 76 9 12
114 48 260 6.9 81 7 16
115 NA 264 14.3 79 6 6
116 10 264 14.3 73 7 12
117 NA 266 14.9 58 5 26
118 97 267 6.3 92 7 8
119 135 269 4.1 84 7 1
120 97 272 5.7 92 7 9
121 NA 273 6.9 87 6 8
122 28 273 11.5 82 8 13
123 35 274 10.3 82 7 17
124 14 274 10.9 68 5 14
125 50 275 7.4 86 7 29
126 77 276 5.1 88 7 7
127 37 279 7.4 76 5 31
128 37 284 20.7 72 6 17
129 61 285 6.3 84 7 18
130 NA 286 8.6 78 6 1
131 NA 287 9.7 74 6 2
132 11 290 9.2 66 5 13
133 71 291 13.8 90 6 9
134 NA 291 14.9 91 7 14
135 80 294 8.6 86 7 24
136 NA 295 11.5 82 7 23
137 23 299 8.6 65 5 7
138 34 307 12.0 66 5 17
139 18 313 11.5 62 5 4
140 40 314 10.9 83 7 6
141 11 320 16.6 73 5 22
142 30 322 11.5 68 5 19
143 NA 322 11.5 79 6 15
144 39 323 11.5 87 6 10
145 NA 332 13.8 80 6 14
146 14 334 11.5 64 5 16
147 66 NA 4.6 87 8 6
148 7 NA 6.9 74 5 11
149 78 NA 6.9 86 8 4
150 35 NA 7.4 85 8 5
151 NA NA 8.0 57 5 27
152 NA NA 14.3 56 5 5
153 28 NA 14.9 66 5 6
Para ordenar de manera descendente, es decir, de mayor a menor, basta con añadir el signo menos antes de la variable o tambien así: arrange(Alcaldes2021, desc(votos))
arrange(Alcaldes2021, -votos)# A tibble: 323,335 × 17
nro_region region circunscripcion_senato…¹ distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
2 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
3 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
4 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
5 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
6 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
7 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
8 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
9 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
10 13 METROPOLITANA DE SANTIAGO CIRCUNSCRIPCION SENATOR… DISTRIT… LO BA…
# ℹ 323,325 more rows
# ℹ abbreviated name: ¹circunscripcion_senatorial
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos <dbl>,
# nominado <chr>
Seleccionar columnas con select()
No es raro obtener conjuntos de datos con cientos o incluso miles de variables. En este caso, el primer desafío a menudo se reduce a las variables que realmente te interesan. select() te permite seleccionar rápidamente un subconjunto útil utilizando operaciones basadas en los nombres de las variables.
select(Alcaldes2021, region, pacto, partido, votos)# A tibble: 323,335 × 4
region pacto partido votos
<chr> <chr> <chr> <dbl>
1 DE TARAPACA UNIDOS POR LA DIGNIDAD PARTIDO DEMOCRATA CRISTIANO 50
2 DE TARAPACA CHILE VAMOS INDEPENDIENTES 21
3 DE TARAPACA INDEPENDIENTES INDEPENDIENTES 12
4 DE TARAPACA INDEPENDIENTES INDEPENDIENTES 12
5 DE TARAPACA INDEPENDIENTES INDEPENDIENTES 19
6 DE TARAPACA INDEPENDIENTES INDEPENDIENTES 14
7 DE TARAPACA <NA> <NA> 0
8 DE TARAPACA <NA> <NA> 0
9 DE TARAPACA UNIDOS POR LA DIGNIDAD PARTIDO DEMOCRATA CRISTIANO 57
10 DE TARAPACA CHILE VAMOS INDEPENDIENTES 18
# ℹ 323,325 more rows
# Seleccionar todas las columnas entre pacto y nominado (incluyente)
select(Alcaldes2021, pacto:nominado)# A tibble: 323,335 × 8
pacto partido nro_voto nombres primer_apellido segundo_apellido votos
<chr> <chr> <dbl> <chr> <chr> <chr> <dbl>
1 UNIDOS POR L… PARTID… 250 PATRIC… FERREIRA RIVERA 50
2 CHILE VAMOS INDEPE… 251 CAMILA… ARCE FAJARDO 21
3 INDEPENDIENT… INDEPE… 252 RENE D… CACERES ARAYA 12
4 INDEPENDIENT… INDEPE… 253 JORGE … ZAVALA VALENZUELA 12
5 INDEPENDIENT… INDEPE… 254 GERMAN… QUIROZ CANCINO 19
6 INDEPENDIENT… INDEPE… 255 PAULA … ASTUDILLO DIAZ 14
7 <NA> <NA> NA VOTOS … <NA> <NA> 0
8 <NA> <NA> NA VOTOS … <NA> <NA> 0
9 UNIDOS POR L… PARTID… 250 PATRIC… FERREIRA RIVERA 57
10 CHILE VAMOS INDEPE… 251 CAMILA… ARCE FAJARDO 18
# ℹ 323,325 more rows
# ℹ 1 more variable: nominado <chr>
# Seleccionar todas las columnas excepto aquellas entre nro_region y lista (incluyente)
select(Alcaldes2021, -(nro_region:lista))# A tibble: 323,335 × 8
pacto partido nro_voto nombres primer_apellido segundo_apellido votos
<chr> <chr> <dbl> <chr> <chr> <chr> <dbl>
1 UNIDOS POR L… PARTID… 250 PATRIC… FERREIRA RIVERA 50
2 CHILE VAMOS INDEPE… 251 CAMILA… ARCE FAJARDO 21
3 INDEPENDIENT… INDEPE… 252 RENE D… CACERES ARAYA 12
4 INDEPENDIENT… INDEPE… 253 JORGE … ZAVALA VALENZUELA 12
5 INDEPENDIENT… INDEPE… 254 GERMAN… QUIROZ CANCINO 19
6 INDEPENDIENT… INDEPE… 255 PAULA … ASTUDILLO DIAZ 14
7 <NA> <NA> NA VOTOS … <NA> <NA> 0
8 <NA> <NA> NA VOTOS … <NA> <NA> 0
9 UNIDOS POR L… PARTID… 250 PATRIC… FERREIRA RIVERA 57
10 CHILE VAMOS INDEPE… 251 CAMILA… ARCE FAJARDO 18
# ℹ 323,325 more rows
# ℹ 1 more variable: nominado <chr>
Para renombrar variables puedes utilizar rename() primero va el nombre nuevo.
rename(Alcaldes2021, votos1 = votos)# A tibble: 323,335 × 17
nro_region region circunscripcion_senatorial distrito comuna
<dbl> <chr> <chr> <chr> <chr>
1 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
2 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
3 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
4 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
5 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
6 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
7 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
8 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
9 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
10 1 DE TARAPACA CIRCUNSCRIPCION SENATORIAL 2 DISTRITO 2 ALTO HOSPICIO
# ℹ 323,325 more rows
# ℹ 12 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>, votos1 <dbl>,
# nominado <chr>
Si quisieras mover variables al comienzo del data frame podrías utilizar el auxiliar everything()
select(Alcaldes2021, votos, nominado, everything())# A tibble: 323,335 × 17
votos nominado nro_region region circunscripcion_senat…¹ distrito comuna
<dbl> <chr> <dbl> <chr> <chr> <chr> <chr>
1 50 ELECTO 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
2 21 <NA> 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
3 12 <NA> 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
4 12 <NA> 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
5 19 <NA> 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
6 14 <NA> 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
7 0 <NA> 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
8 0 <NA> 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
9 57 ELECTO 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
10 18 <NA> 1 DE TARAPACA CIRCUNSCRIPCION SENATO… DISTRIT… ALTO …
# ℹ 323,325 more rows
# ℹ abbreviated name: ¹circunscripcion_senatorial
# ℹ 10 more variables: circunscripcion_electoral <chr>, local <chr>,
# mesa <chr>, lista <chr>, pacto <chr>, partido <chr>, nro_voto <dbl>,
# nombres <chr>, primer_apellido <chr>, segundo_apellido <chr>
Hay una serie de funciones auxiliares que puedes usar dentro de select():
starts_with("abc"): coincide con los nombres que comienzan con “abc”.ends_with("xyz"): coincide con los nombres que terminan con “xyz”.contains("ijk"): coincide con los nombres que contienen “ijk”.matches("(.)\\1"): selecciona variables que coinciden con una expresión regular. Esta en particular coincide con cualquier variable que contenga caracteres repetidos. Aprenderás más sobre expresiones regulares en [Cadenas de caracteres].num_range("x", 1:3): coincide conx1,x2yx3.
select(Alcaldes2021, contains("apellido"))# A tibble: 323,335 × 2
primer_apellido segundo_apellido
<chr> <chr>
1 FERREIRA RIVERA
2 ARCE FAJARDO
3 CACERES ARAYA
4 ZAVALA VALENZUELA
5 QUIROZ CANCINO
6 ASTUDILLO DIAZ
7 <NA> <NA>
8 <NA> <NA>
9 FERREIRA RIVERA
10 ARCE FAJARDO
# ℹ 323,325 more rows
select(Alcaldes2021, starts_with("circunscripcion"))# A tibble: 323,335 × 2
circunscripcion_senatorial circunscripcion_electoral
<chr> <chr>
1 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
2 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
3 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
4 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
5 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
6 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
7 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
8 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
9 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
10 CIRCUNSCRIPCION SENATORIAL 2 ALTO HOSPICIO
# ℹ 323,325 more rows
Añadir nuevas variables con mutate()
Además de seleccionar conjuntos de columnas existentes, a menudo es útil crear nuevas columnas en función de columnas existentes. Ese es el trabajo de mutate() (del inglés mutar o transformar).
mutate() siempre agrega nuevas columnas al final de un conjunto de datos, así que comenzaremos creando un conjunto de datos más pequeño para que podamos ver las nuevas variables. Recuerda que cuando usas RStudio, la manera más fácil de ver todas las columnas es View().
RM <- select(Alcaldes2021,
nombres:nominado,
starts_with("circunscripcion"),
region,
comuna) %>%
filter(region == "METROPOLITANA DE SANTIAGO")Luego de seleccionar variables y filtrar la base solo por las observaciones que correspondan a la Región Metropolitana, vamos a crear una variable nueva que contenga la suma de votos totales de la columna votos.
RM <- mutate(RM,
votos_rm = sum(votos))El comando mutate() tambien nos sirve para multiplicar, dividir, etc. Por ejemplo, en la base de datos de autos llamada mtcars() las millas por galon si queremos transformalas en kilometros por litro devemos multiplicar por 0.425. Con mutate() es facil hacerlo.
mtcars <- mtcars %>%
mutate(kml = round(mpg * 0.425,1))Ordenamiento: hay una serie de funciones de ordenamiento (ranking), pero deberías comenzar con min_rank(). Esta función realiza el tipo más común de ordenamiento (por ejemplo, primero, segundo, tercero, etc.). El valor predeterminado otorga la menor posición a los valores más pequeños; usa desc(x) para dar la menor posición a los valores más grandes.
mtcars <- mtcars %>%
mutate(ranking_economico = min_rank(kml)) %>%
arrange(ranking_economico)Si min_rank() no hace lo que necesitas, consulta las variantes row_number(), dense_rank(), percent_rank(), cume_dist(),quantile(). Revisa sus páginas de ayuda para más detalles.
Resúmenes agrupados con summarise()
El último verbo clave es summarise() (resumir, en inglés). Se encarga de colapsar un data frame en una sola fila:
summarise(Alcaldes2021, pacto = sum(votos))# A tibble: 1 × 1
pacto
<dbl>
1 6468909
summarise() no es muy útil a menos que lo enlacemos con group_by(). Esto cambia la unidad de análisis del conjunto de datos completo a grupos individuales. Luego, cuando uses los verbos dplyr en un data frame agrupado, estos se aplicarán automáticamente “por grupo”. Por ejemplo, la suma de votos de cada pacto electoral por region!
pacto_region <- Alcaldes2021 %>% group_by(region, pacto) %>% summarise(votos = sum(votos))`summarise()` has grouped output by 'region'. You can override using the
`.groups` argument.
pacto_region %>%
filter(region == "DE LA ARAUCANIA" & !is.na(pacto)) %>%
ggplot(aes(x=reorder(pacto, votos), y=votos)) +
geom_col() +
coord_flip()Desagrupar
Si necesitas eliminar la agrupación y regresar a las operaciones en datos desagrupados, usa ungroup(). ¿Cuál es el alcalde más votado de Chile?
alcalde_votos <- Alcaldes2021 %>%
group_by(nombres, primer_apellido, segundo_apellido) %>%
summarise(votos = sum(votos)) %>%
ungroup() %>%
mutate(rank = min_rank(-votos)) %>%
arrange(rank)`summarise()` has grouped output by 'nombres', 'primer_apellido'. You can
override using the `.groups` argument.
El cuarto alcalde más votado es VOTOS NULOS! ¿Por qué?
alcalde_votos <- Alcaldes2021 %>%
filter(nombres!="VOTOS NULOS" & nombres!="VOTOS EN BLANCO") %>%
group_by(nombres, primer_apellido, segundo_apellido) %>%
summarise(votos = sum(votos)) %>%
ungroup() %>%
mutate(rank = min_rank(-votos)) %>%
arrange(rank)`summarise()` has grouped output by 'nombres', 'primer_apellido'. You can
override using the `.groups` argument.
Queremos ver el top 5 de alcaldes más votados de Chile.
alcalde_votos %>% filter(rank <= 5)# A tibble: 5 × 5
nombres primer_apellido segundo_apellido votos rank
<chr> <chr> <chr> <dbl> <int>
1 RODOLFO RAFAEL CARTER FERNANDEZ 90303 1
2 TOMAS VODANOVIC ESCUDERO 90186 2
3 GERMAN CODINA POWERS 87239 3
4 JORGE ESTEBAN SHARP FAJARDO 64832 4
5 DANIELA PEÑALOZA RAMOS 58603 5
Cosas útiles que hay que saber sobre las variables
Valores especiales
Lo primero que quiero mencionar son algunos de los valores “especiales” que R puede producir. Lo más probable es que los veas en situaciones en las que esperabas un número, pero hay bastantes otras formas en las que puedes encontrarlos. Estos valores son Inf, NaN, NA y NULL. Estos valores pueden aparecer en distintos lugares, por lo que es importante comprender su significado.
- Infinity (
Inf). El valor especial más fácil de explicar esInf, ya que corresponde a un valor infinitamente grande. También se puede tener-Inf. La forma más fácil de obtenerInfes dividir un número positivo por 0:
1/0[1] Inf
En la mayoría de las situaciones de análisis de datos del mundo real, si se obtienen números infinitos en los datos, algo va mal. Esperemos que nunca tengas que verlos.
- Not a Number (
NaN). El valor especial deNaNes la abreviatura de “not a number” (no es un número), y básicamente es una palabra clave que significa “no hay un número matemáticamente definido para esto”. Si recuerdas las matemáticas del colegio, recuerda que es convencional decir que 0/0 no tiene una respuesta adecuada: los matemáticos dirían que 0/0 no está definido. R dice que no es un número:
0/0[1] NaN
No obstante, se sigue tratando como un valor “numérico”. Para simplificar demasiado, NaN corresponde a los casos en que usted hizo una pregunta numérica adecuada que realmente no tiene una respuesta significativa.
Not available (
NA).NAindica que falta el valor que “supuestamente” debería almacenarse aquí. Para entender lo que esto significa, es útil reconocer que el valorNAes algo que es más probable ver cuando se analizan datos de experimentos del mundo real. A veces se producen fallos en el equipo, se pierden algunos datos o lo que sea. La cuestión es que falta parte de la información que esperabas obtener de tu estudio. Fíjese en la diferencia entreNAyNaN. ParaNaN, realmente sabemos lo que se supone que se almacena; es sólo que resulta que corresponde a algo como0/0que no tiene ningún sentido en absoluto. Por el contrario,NAindica que en realidad no sabemos lo que se supone que debe estar allí. Falta la información.No value (
NULL). El valorNULLlleva este concepto de “ausencia” aún más lejos. Básicamente afirma que la variable no tiene ningún valor. Esto es bastante diferente deNaNyNA. ParaNaNrealmente sabemos cuál es el valor, porque es algo loco como0/0. En el caso deNA, creemos que se supone que hay un valor, pero no sabemos cuál es. Pero paraNULLcreemos firmemente que no hay ningún valor.