Para explicar todo el temario de la asignatura de AED sigo el manual: Introducción al Análisis Exploratorio de Datos. Aplicaciones con R y datos reales.
A lo largo del curso no hemos referido frecuentemente a Tidyverse. Hemos visto como Tidyverse hace referencia a una nueva forma de afrontar el análisis de datos en R. Se hace uso de un grupo de paquetes que trabajan en armonía porque comparten ciertos principios, como por ejemplo, la forma de estructurar los datos. La mayoría de estos paquetes han sido desarrollados por (o al menos con la colaboración de) Hadley Wickham. Esta es la página web del tidyverse.
En el tema 7 hemos visto algunas de las funciones más importantes de
dplyr
, en este tema 5 vamos a estudiar como aprender los
fundamentos para organizar los datos porque…..
“Programs must be written for people to read, and only incidentally for machines to execute –– Hal Abelson
Si vamos a manejar datos con R y a la manera del tydiverse, como Jenny Bryan señala en su excelente tutorial sobre tidy data:
An important aspect of “writing data for computers” is to make your data TIDY. —- Jenny Bryan
Por tanto, antes de comenzar a manipular datos conviene saber que se entiende por tidy data. Si los datos son tidy será más fácil trabajar con ellos con el tidyverse (tanto para transformarlos como para visualizarlos).
De forma sencilla, tidy data son simplemente datos organizados de una determinada manera. Además es justo de la manera a la estamos familiarizados. De forma más precisa se puede leer aquí, o de forma más elaborada [aquí] :
Tidy datasets provide a standardized way to link the structure of a dataset (its physical layout) with its semantics (its meaning). —– Hadley Wickham
La mayoría de datos en Ciencias Sociales se ajustan a la categoría de datos tabulares; es decir, están organizados en filas y columnas. En R este tipo de datos se almacenan en dataframes (o tibbles). En esencia, un dataframe será tidy si cada columna es una variable y cada fila es una unidad de análisis (persona, país, región etc…); es decir, cada celda contiene el valor de una variable para una unidad de análisis.
A dataset is a collection of values. Every value belongs to a variable and an observation. A variable contains all values that measure the same underlying attribute (like height, temperature, duration) across units. An observation contains all values measured on the same unit (like a person, or a day, or a race) across attributes
Tidy data from http://r4ds.had.co.nz/tidy-data.html
Veamos un ejemplo. Supongamos que la variable (o atributo) a medir es el salario y la unidad de análisis las personas. Hemos recogido datos para 3 personas. Veámoslos:
year | Nicolas | Carla | Angela |
---|---|---|---|
2016 | 100 | 400 | 200 |
2017 | 500 | 600 | 700 |
2018 | 200 | 250 | 900 |
Entendemos perfectamente estos datos, visualmente son cómodos, pero ¿son tidy data?
¿y este? También es un formato fácil de entender por nosotros, pero ¿son tidy?
names | Salario_2016 | Salario_2017 | Salario_2018 |
---|---|---|---|
Nicolas | 100 | 500 | 200 |
Carla | 400 | 600 | 250 |
Angela | 200 | 700 | 900 |
Este es quizá el formato al que estamos más acostumbrados (individuos o registros en filas y “variables” en columnas). ¿Realmente el salario de 2016 es una variable?
En jerga del tidyverse este formato de datos es “wide” (o ancho)
Podemos trabajar tranquilamente con el anterior formato, PERO, si queremos sacar todo el provecho al tidyverse es mejor tener los datos en long format.
names | year | salario |
---|---|---|
Nicolas | 2016 | 100 |
Carla | 2016 | 400 |
Angela | 2016 | 200 |
Nicolas | 2017 | 500 |
Carla | 2017 | 600 |
Angela | 2017 | 700 |
Nicolas | 2018 | 200 |
Carla | 2018 | 250 |
Angela | 2018 | 900 |
Este formato es más difícil de leer para nosotros, pero es más eficiente para los ordenadores. Y los datos los procesan los ordenadores!!
gather()
y spread()
Si tenemos un dataframe en formato wide tenemos que
pasarlo a formato long para trabajar más
eficientemente. Generalmente, para mostrar resultados se pasa de formato
long a formato wide, porque los
entendemos mejor. Estos procesos se realizan con las funciones
gather()
y spread()
.
tidyr: formato ancho y largo
La función gather()
convierte dataframes de formato
wide a long. Esta es su estructura:
gather(data, key, value, …, na.rm = FALSE, convert = FALSE)
Argumentos:
data
: dataframe
key
: nombre de la columna que representa la nueva
variable
value
: nombre de la columna que representa los
valores
...
: nombres de las columnas a juntar (o no juntar)
na.rm
: para eliminar observaciones con valores perdidos
(representados por NAs)
convert
: si TRUE automáticamente convertirá valores a
lógico, entero, numérico, complejo o factor según sea apropiado
data_wide <- data_2 #- data_2 está en formato ancho (wide)
#- la funcióm gather() transforma los datos de formato ancho(wide) a formato largo(long)
data_long <- data_wide %>% gather(periodo, salario, 2:4)
names | periodo | salario |
---|---|---|
Nicolas | Salario_2016 | 100 |
Carla | Salario_2016 | 400 |
Angela | Salario_2016 | 200 |
Nicolas | Salario_2017 | 500 |
Carla | Salario_2017 | 600 |
Angela | Salario_2017 | 700 |
Nicolas | Salario_2018 | 200 |
Carla | Salario_2018 | 250 |
Angela | Salario_2018 | 900 |
Si quisiéramos arreglar los valores de los periodos:
#(!!) stringr::str_replace encuentra el texto "." en la columna "periodo" y lo sustituye por " "
data_long <- data_long %>% mutate(periodo = str_replace(periodo, "_", " " ))
names | periodo | salario |
---|---|---|
Nicolas | Salario 2016 | 100 |
Carla | Salario 2016 | 400 |
Angela | Salario 2016 | 200 |
Nicolas | Salario 2017 | 500 |
Carla | Salario 2017 | 600 |
Angela | Salario 2017 | 700 |
Nicolas | Salario 2018 | 200 |
Carla | Salario 2018 | 250 |
Angela | Salario 2018 | 900 |
Pasar pasar de formato long a wide,
tidyr
tiene la función spread()
. El formato de
esta función, similar al de gather(), es:
spread(data, key, value, fill = NA, convert = FALSE)
Argumentos:
data
: dataframe key
: columna de valores que
queremos pasar a formato ancho (ocupará varias columnas)
value
: columna con los valores correspondientes a la
variable key
#- spread() convierte un df de long a wide
data_wide2 <- data_long %>% spread(periodo, salario)
names | Salario 2016 | Salario 2017 | Salario 2018 |
---|---|---|---|
Angela | 200 | 700 | 900 |
Carla | 400 | 600 | 250 |
Nicolas | 100 | 500 | 200 |
separate()
y unite()
Como puede deducirse por los nombres, estas funciones se utilizan para separar y unir columnas.
df <- data.frame( names = c("Pedro_Navaja", "Bob_Dylan", "Cid_Campeador"),
year = c(1978, 1941, 1048) )
df
## names year
## 1 Pedro_Navaja 1978
## 2 Bob_Dylan 1941
## 3 Cid_Campeador 1048
Separamos la primera columna:
df_separado <- df %>% separate(names, c("Nombre", "Apellido"), sep = "_")
df_separado
## Nombre Apellido year
## 1 Pedro Navaja 1978
## 2 Bob Dylan 1941
## 3 Cid Campeador 1048
Si queremos volver a unirlos, tendríamos que:
df_unido <- df_separado %>% unite(Nombre_y_Apellido, Nombre:Apellido, sep = "&")
df_unido
## Nombre_y_Apellido year
## 1 Pedro&Navaja 1978
## 2 Bob&Dylan 1941
## 3 Cid&Campeador 1048
Para practicar los formatos long y wide, vamos
a trabajar las funciones de tidyr
que hemos visto.
Descomprimid la carpeta Final
. En esta carpeta tenemos el
script de trabajo de esta última clase con los datos, etc.
A new data processing workflow for R: dplyr, magrittr, tidyr, ggplot2. Post de un nuevo convencido de las bondades del tidyverse. Un ejemplo sencillo pero ilustrativo.
Wide & Long Data Post que explica los beneficios de trabajar con datos en formato long (tidy).
La biblia del tidy data. Vignette de tidyr package escrita por Hadley Wickham que explica con MUCHO detalle que son los tidy data.