Capítulo 3 El Tidyverso y tidyr
3.1 Paquetes necesarios para este capítulo
Para este capítulo necesitas tener instalado el paquete tidyverse y el paquete dismo para uno de los ejercicios.
En este capítulo se explicará qué es el paquete tidyverse (Wickham 2017) y cuales son sus componentes. Además veremos las funciones del paqute tidyr (Wickham and Henry 2018) con sus dos funciones gather
y spread
.
Dado que este libro es un apoyo para el curso BIO4022, esta clase puede también ser seguida en este link. El video de la clase se encontrará disponible en este link.
3.2 El tidyverso
El tidiverso se refiere al paquete tidiverse, el cual es una colección de paquetes coehrentes, que tienen una gramática, filosofía y estructura similar. Todos se basan en la idea de tidy data propuesta por Hadley Wickham (Wickham and others 2014).
Los paquetes que forman parte del tidyverso son:
- readr (ya la estamos usando)
- dplyr (Clase anterior)
- tidyr (Hoy)
- ggplot2 (Próxima clase)
- purrr (En clase sobre loops)
- forcats (Para variables categóricas)
- stringr (Para carácteres, Palabras)
3.2.1 readr
El paquete readr (Wickham, Hester, and Francois 2017) tiene como función el importar (leer) y exportar archivos. Dado que en general nosotros usaremos archivos del tipo csv, para este tipo de archivos, readr tiene la función read_csv
. Para exportar un archivo ocupamos la función write_csv
. Ambas funciones son 10 veces más rápidas que las versiones de r base. Para más información sobre este revisar su página oficial.
3.2.2 dplyr
Este paquete sirve para modificar variables y sus detalles los vimos en el capítulo 1. Los cinco verbos principales que tiene son mutate
para generar nuevas variables y que vienen de variables ya existentes, select
para seleccionar variables basadas en su nombre, filter
para seleccionar filas de acuerdo a si cumplen o no con condiciones en una o mas variables, summarize
para resumir las variables, y arrange
para reordenar las filas de acuerdo a alguna variable. Para más información sobre este paquete revisar su página oficial.
3.2.3 tidyr
Con sólo dos funciones: gather
y spread
. El paquete tidyr (Wickham and Henry 2018) tiene como finalidad el tomar bases de datos no tidy y transformalas en tidy (datos limpios y ordenados). Para esto, gather
transforma tablas anchas en largas y spread
transforma tablas anchas en larga. En este capítulo explicaremos en más detalle estos dos verbos. Para más información sobre este paquete revisar su página oficial.
3.2.4 ggplot2
Una vez que una base de datos está en formato tidy, podemos usar ggplot2 (Wickham 2016) para visualizar estos datos. Los datos pueden ser categóricos, continuos e incluso espaciales en conjunto con el paquete sf. Este paquete es el más antiguo del tidyverse y por ello posee una gramática un poco diferente. Hablaremos más de este paquete en el capítulo 4. Por ahora si se quiere aprender más sobre ggplot2 se puede revisar la página oficial
3.2.5 purrr
Purrr (Henry and Wickham 2018) permite formular loops de una forma más sencilla e intuitiva que los for loops. Utilizando sus funciones map
, map2
, walk
y reduce
podemos realizar loops dentro de la gramática del tidyverse. Trabajaremos en este paquete en el capítulo 6. Como siempre puedes encontras más información en su página oficial
3.2.6 forcats
Trabajar con factores es una de las labores más complejas en R, es por eso que se creó el paquete forcats (Wickham 2018a). Si bien no hay un capítulo en este libro en el cuál se trabajará exclusivamente con este paquete, se utilizará al menos una función en el capítulo 4
3.2.7 stringr
El modíficar variables de texto para hacer que las variables tengan sentido humano es algo muy importante, para este tipo de modificaciones se utiliza el paquete stringr (Wickham 2018b). En este capítulo, para algunos ejercicios, introduciremos algunas funcionalidades de este paquete. Para más información revisar su página oficial.
3.3 tidyr
Este paquete como ya fue explicado en la sección anterior, solo posee dos funciones: gather
y spread
. Estas funciones sirven para pasar de tablas anchas a largas y viceversa, pero ¿qué significa que la misma información sea presentada en una tabla larga o en una tabla ancha?
Tomemos por ejemplo dos tablas. En la tabla 3.1 vemos una tabla ancha y en la tabla 3.2 una tabla larga.
Sepal.Length | Sepal.Width | Petal.Length | Petal.Width | Species |
---|---|---|---|---|
5.1 | 3.5 | 1.4 | 0.2 | setosa |
7.0 | 3.2 | 4.7 | 1.4 | versicolor |
6.3 | 3.3 | 6.0 | 2.5 | virginica |
Species | Atributos_florales | Medidas |
---|---|---|
setosa | Sepal.Length | 5.1 |
versicolor | Sepal.Length | 7.0 |
virginica | Sepal.Length | 6.3 |
setosa | Sepal.Width | 3.5 |
versicolor | Sepal.Width | 3.2 |
virginica | Sepal.Width | 3.3 |
setosa | Petal.Length | 1.4 |
versicolor | Petal.Length | 4.7 |
virginica | Petal.Length | 6.0 |
setosa | Petal.Width | 0.2 |
versicolor | Petal.Width | 1.4 |
virginica | Petal.Width | 2.5 |
3.3.0.1 DATO
Usualmente las tablas anchas son mejores para ser mostradas ya que se distinguen más facilmente las variables trabajadas, mientras que las tablas largas son mejores para programar y hacer análisis.
3.3.1 gather
Esta función nos permite pasar de una tabla ancha a una larga. En muchos casos esto es necesario para generar una base de datos tidy, y en otras ocaciones es importante para generación de gráficos que necesitamos tal como veremos en el capítulo 4. En esta función partimos con un data frame y luego tenemos 3 argumentos: en el primero key
, ponemos el nombre de la variable que va a llevar como observaciones los nombres de las columnas; luego en el argumento value, ponemos el nombre de la columna que llevará los valores de cada columna al transformarse en una columna larga; Por último hay un argumento (sin nombre), en el cual ponemos las columas que queremos que sean “alargadas”, o con un signo negativo, las que no queremos que sean parte de esta transformación. Todo esto quedará más claro en el siguiente ejemplo.
3.3.1.1 Ejemplo de los censos
Supongamos que un estudiante de biología va a realizar un censo en un parque nacional por tres días y genera la siguiente tabla (el código a continuación es el que permite generar el data frame obervado en la tabla 3.3)
df_cuentas <- data.frame(dia = c("Lunes", "Martes", "Miercoles"),
Lobo = c(2, 1, 3), Liebre = c(20, 25, 30), Zorro = c(4, 4,
4))
dia | Lobo | Liebre | Zorro |
---|---|---|---|
Lunes | 2 | 20 | 4 |
Martes | 1 | 25 | 4 |
Miercoles | 3 | 30 | 4 |
Claramente esta base de datos no es tidy, ya que deberíamos tener una columna para la variable día, otra para especie y por último una para la abundancia de cada especie en cadad día. Antes de mostrar como realizaríamos esto con gather
, veamos sus efectos para entenderlo mejor. La forma más básica de usar esta función sería el solo darle un nombre a la columna key (que tendrá el nombre de las columnas) y otro a value, que tendría el valor de las celdas. Veamos que ocurre si hacermos eso en el siguiente código y tabla 3.4.
Columnas | Valores |
---|---|
dia | Lunes |
dia | Martes |
dia | Miercoles |
Lobo | 2 |
Lobo | 1 |
Lobo | 3 |
Liebre | 20 |
Liebre | 25 |
Liebre | 30 |
Zorro | 4 |
Zorro | 4 |
Zorro | 4 |
Como vemos en la tabla 3.4, en la columna llamada Columnas, tenemos sólo los nombres de las columnas de la tabla 3.3, y en la columna Valores, tenemos los valores encontrados en la tabla 3.3. Sin embargo, para tener las tres columnas que desearíamos tener (día, especie y abundancia), necesitamos que la variable día no participe de este “alargamiento”, para esto lo que haríamos sería los siguiente:
Al agregar -día
como tercer argumento quitamos esa variable del día en el “alargamiento”, en ese caso obtenemos la tabla 3.5. Ahora sólo falta arreglar los nombres.
dia | Columnas | Valores |
---|---|---|
Lunes | Lobo | 2 |
Martes | Lobo | 1 |
Miercoles | Lobo | 3 |
Lunes | Liebre | 20 |
Martes | Liebre | 25 |
Miercoles | Liebre | 30 |
Lunes | Zorro | 4 |
Martes | Zorro | 4 |
Miercoles | Zorro | 4 |
Para cambiar los nombres de las columnas que nos faltan, sólo cambiamos los valores de los argumentos key
y value
como se ve a continuación y en la tabla 3.6.
dia | Especie | Abundancia |
---|---|---|
Lunes | Lobo | 2 |
Martes | Lobo | 1 |
Miercoles | Lobo | 3 |
Lunes | Liebre | 20 |
Martes | Liebre | 25 |
Miercoles | Liebre | 30 |
Lunes | Zorro | 4 |
Martes | Zorro | 4 |
Miercoles | Zorro | 4 |
3.3.2 spread
spread
es la función inversa a gather
, esto es, toma una tabla de datos en formato ancho y la trnasforma en una base de datos de formato largo. Esta función tiene dos argumentos básicos. key que es el nombre de la variable que pasará a ser nombres de columna y value, que es el nombre de la columna con los valores que llenarán estas columnas.
3.3.2.1 Continuación ejemplo de censos
Volvamos al ejemplo de los censos donde quedamos, en nuestro último ejercicio creamos el data frame DF_largo que vemos en la tabla 3.6. Veremos algunos ejemplos de como podemos cambiar este data frame en una tabla ancha:
Con el código anterior generamos la 3.7, la cuál es distinta a la original en la tabla 3.3), en esta los días quedaron como nombres de columnas, y las especies pasaron a ser una variable.
Especie | Lunes | Martes | Miercoles |
---|---|---|---|
Liebre | 20 | 25 | 30 |
Lobo | 2 | 1 | 3 |
Zorro | 4 | 4 | 4 |
En la tabla 3.8 se ven todas las opciones de como generar una tabla ancha en base a el data frame DF_largo, pruebe opciones hasta entender la función, algunas de estas opciones darán errores.
Key | Value |
---|---|
Especie | dia |
Abundancia | dia |
dia | Especie |
Abundancia | Especie |
dia | Abundancia |
Especie | Abundancia |
3.4 Ejercicios
3.4.1 Ejercicio 1
Utilizando el siguiente código usando el paquete dismo bajaras la base de datos del GBIF (Global Biodiversity Information Facility) de presencias conocidas del huemul (Hippocamelus bisulcus):
Tomando la base de datos generada:
Quedarse con solo las observaciones que tienen coordenadas geograficas
Determinar cuantas observaciones son de observacion humana y cuantas de especimen de museo
3.4.2 Ejercicio 2
Entrar a INE ambiental y bajar la base de datos de Dimensión Aire.
- Generar una base de datos tidy con las siguientes 5 columnas
- El nombre de la localidad donde se encuntra la estación
- El año en que se tomo la medida
- El mes en que se tomo la medida
- La temperatura media de ese mes
- La media del mp25 de ese mes
- Humedad relativa media mensual
- De la base de datos anterior obterner un segundo data frame en la cual calculen para cada variable y estación la media y desviación estandar para cada mes
Referencias
Henry, Lionel, and Hadley Wickham. 2018. Purrr: Functional Programming Tools. https://CRAN.R-project.org/package=purrr.
Wickham, Hadley. 2016. Ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York. http://ggplot2.org.
Wickham, Hadley. 2017. Tidyverse: Easily Install and Load the ’Tidyverse’. https://CRAN.R-project.org/package=tidyverse.
Wickham, Hadley. 2018a. Forcats: Tools for Working with Categorical Variables (Factors). https://CRAN.R-project.org/package=forcats.
Wickham, Hadley. 2018b. Stringr: Simple, Consistent Wrappers for Common String Operations. https://CRAN.R-project.org/package=stringr.
Wickham, Hadley, and Lionel Henry. 2018. Tidyr: Easily Tidy Data with ’Spread()’ and ’Gather()’ Functions. https://CRAN.R-project.org/package=tidyr.
Wickham, Hadley, Jim Hester, and Romain Francois. 2017. Readr: Read Rectangular Text Data. https://CRAN.R-project.org/package=readr.
Wickham, Hadley, and others. 2014. “Tidy Data.” Journal of Statistical Software 59 (10). Foundation for Open Access Statistics: 1–23.