Hermano, esta guía va a ser cortita y al pie, como pase de Maradona en el mundial del 86’. La idea es introducirte un paquete que es intuitivo en R para realizar Limpieza y Análisis Explorativo. Como todo en esta vida hay un trde-off: es un gran paquete para hacer las cosas rápida, iniciar a usar R y eficientizar tu análisis pero quitando la parte de “programar” el potencial se pierde.
Que es el Tidyverse?
Hay un tipo llamado [Hadley Wickham] (http://hadley.nz/) que es el creador de Rstudio también, el con el IDE y R-Pubs fortaleció la comunidad R, luego su paquete ggplot2 le dió al lenguaje lo que le faltaba: gráficos sexy. Ahora R era un lenguaje dedicado para estadísticas y análisis de datos completo, directo y encima estúpidamente sensual para comunicar.
Pero no se quedó sólo ahí, creó infinidad de paquetes al punto que formaron un “Universo”, ya que dentro del lenguaje R todos sus paquetes comparten syntaxis. El Tidyverse en pocas palabras tiene lo mejor de R y Excel, por un lado utilizas el poder de R para manejar distintos objetos y con Rstudio tenes una paltaforma para ello mejor que solo spreadsheets; por el otro lado cada verbo del tidyverse hace una cosa puntual (similar al “you get what you see”), entonces en lugar de tener que saber manejar columnas en matrices o observaciones de dataframes, el tidyverse tiene una function que su nombre te dice intuitivamente que hace.
Se llama tidy porque como bien decíamos en la introducción sirve para ordenar - limpiar datos y verse porque es un paquete conteniendo varios paquetes donde cada uno trata un problema puntual. Los paquetes principales son:
ggplot2sistema grafico basado en el “grammar of Graphics”.
dplyrpaquete para manipulación de datos.
tidyrreorganizar y mover datos.
stringrpara trabajar con texto (strings, character inpunt).
dplyr
Sus principales verbos son:
mutate()agrega columnas que son cálculos de otras columnas dentro del datasetselect()selecciona columnas y subset el dataframe.filter()selecciona las filas.summarise()sirve para realizar calculos basados en columnas, por ejemplomeanviene aplicado a toda la columna “deaths”.arrange()reordena las filas.
Primero probamos con filter(), algo para lo que base R suele ser díficil , cuando se trabaja con dataframes que sabemos que ya estan ordenados con alguna lógica y son consistentes es infalible.
Usamos el dataset de starwars que viene incluído en el tidyverse.
## Observations: 87
## Variables: 13
## $ name <chr> "Luke Skywalker", "C-3PO", "R2-D2", "Darth Vader", "Leia...
## $ height <int> 172, 167, 96, 202, 150, 178, 165, 97, 183, 182, 188, 180...
## $ mass <dbl> 77.0, 75.0, 32.0, 136.0, 49.0, 120.0, 75.0, 32.0, 84.0, ...
## $ hair_color <chr> "blond", NA, NA, "none", "brown", "brown, grey", "brown"...
## $ skin_color <chr> "fair", "gold", "white, blue", "white", "light", "light"...
## $ eye_color <chr> "blue", "yellow", "red", "yellow", "brown", "blue", "blu...
## $ birth_year <dbl> 19.0, 112.0, 33.0, 41.9, 19.0, 52.0, 47.0, NA, 24.0, 57....
## $ gender <chr> "male", NA, NA, "male", "female", "male", "female", NA, ...
## $ homeworld <chr> "Tatooine", "Tatooine", "Naboo", "Tatooine", "Alderaan",...
## $ species <chr> "Human", "Droid", "Droid", "Human", "Human", "Human", "H...
## $ films <list> [<"Revenge of the Sith", "Return of the Jedi", "The Emp...
## $ vehicles <list> [<"Snowspeeder", "Imperial Speeder Bike">, <>, <>, <>, ...
## $ starships <list> [<"X-wing", "Imperial shuttle">, <>, <>, "TIE Advanced ...
## # A tibble: 6 x 13
## name height mass hair_color skin_color eye_color birth_year gender homeworld
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Luke~ 172 77 blond fair blue 19 male Tatooine
## 2 C-3PO 167 75 <NA> gold yellow 112 <NA> Tatooine
## 3 R2-D2 96 32 <NA> white, bl~ red 33 <NA> Naboo
## 4 Dart~ 202 136 none white yellow 41.9 male Tatooine
## 5 Leia~ 150 49 brown light brown 19 female Alderaan
## 6 Owen~ 178 120 brown, gr~ light blue 52 male Tatooine
## # ... with 4 more variables: species <chr>, films <list>, vehicles <list>,
## # starships <list>
## # A tibble: 6 x 13
## name height mass hair_color skin_color eye_color birth_year gender homeworld
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr> <chr>
## 1 Finn NA NA black dark dark NA male <NA>
## 2 Rey NA NA brown light hazel NA female <NA>
## 3 Poe ~ NA NA brown light brown NA male <NA>
## 4 BB8 NA NA none none black NA none <NA>
## 5 Capt~ NA NA unknown unknown unknown NA female <NA>
## 6 Padm~ 165 45 brown light brown 46 female Naboo
## # ... with 4 more variables: species <chr>, films <list>, vehicles <list>,
## # starships <list>
# Ahora selecciono de todas las observaciones solo a los Droides.
# El primer argumento de filter() es el data.frame en el cual vas a aplicar el verbo
# El segundo es el nombre de tu variable (columna) y con un logical (==, |, !=, <, >) pasas la condicion.
# lo almacenamos en un nuevo objeto
starwars_droids <- filter(starwars, species == "Droid")
class(starwars_droids)## [1] "tbl_df" "tbl" "data.frame"
## # A tibble: 87 x 13
## name height mass hair_color skin_color eye_color birth_year gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr>
## 1 Luke~ 172 77 blond fair blue 19 male
## 2 C-3PO 167 75 <NA> gold yellow 112 <NA>
## 3 R2-D2 96 32 <NA> white, bl~ red 33 <NA>
## 4 Dart~ 202 136 none white yellow 41.9 male
## 5 Leia~ 150 49 brown light brown 19 female
## 6 Owen~ 178 120 brown, gr~ light blue 52 male
## 7 Beru~ 165 75 brown light blue 47 female
## 8 R5-D4 97 32 <NA> white, red red NA <NA>
## 9 Bigg~ 183 84 black light brown 24 male
## 10 Obi-~ 182 77 auburn, w~ fair blue-gray 57 male
## # ... with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
En el encabezado dice tibble o tbl_df como habrás visto, no te asustes, es una forma de data.frame especial del tidyverse pero podés trabajar igual con cualquier otro tipo, es más, yo no lo recomiendo a nada del tidyverse en general, para hacer dos cositas sí, pero si querés trabajar de verdad no migramos del closed envirornment de STATA o MATLAB para entrar en otro. Otra cosa que podés haber observado es que la clase del objeto (class()) es heredada luego de aplicarle un verbo del tidyverse.
Ahora seleccionaremos, usaremos select(), sólo las columnas que nos interesan ya que hay muchas variables. En este caso lo almacenaremos en el mismo objeto ya que es este el data.frame con el que queremos trabajar, así evitamos llenarnos de objetos intermedios.
# se puede pasar el nombre de las columnas directo en el verbo o, como prefiero yo, los parametros siempre fuera.
vars <- c("name", "height", "mass", "homeworld", "species", "films")
starwars_droids <- select(starwars_droids, vars)
print(starwars_droids)## # A tibble: 5 x 6
## name height mass homeworld species films
## <chr> <int> <dbl> <chr> <chr> <list>
## 1 C-3PO 167 75 Tatooine Droid <chr [6]>
## 2 R2-D2 96 32 Naboo Droid <chr [7]>
## 3 R5-D4 97 32 Tatooine Droid <chr [1]>
## 4 IG-88 200 140 <NA> Droid <chr [1]>
## 5 BB8 NA NA <NA> Droid <chr [1]>
Bien, ahora que tenemos un data.frame compacto con la información que queremos trabajar, creamos una nueva variable que es función (calculos) de otras. Si bien esto en base R no es díficil, mantendremos las cosas dentro del tidyverse por ahora usando mutate().
# Creo la nueva variable "bmi" y con "=" le asigno a esa nueva columna que cosa incluir, el calculo lo realiza by.row.
# luego introduzco el "pipe operator %>%" para agregar otro verbo en la misma linea de codigo.
starwars_full <- mutate(starwars, bmi = mass / ((height / 100) ^ 2)) %>%
select(vars, bmi)
print(starwars_full)## # A tibble: 87 x 7
## name height mass homeworld species films bmi
## <chr> <int> <dbl> <chr> <chr> <list> <dbl>
## 1 Luke Skywalker 172 77 Tatooine Human <chr [5]> 26.0
## 2 C-3PO 167 75 Tatooine Droid <chr [6]> 26.9
## 3 R2-D2 96 32 Naboo Droid <chr [7]> 34.7
## 4 Darth Vader 202 136 Tatooine Human <chr [4]> 33.3
## 5 Leia Organa 150 49 Alderaan Human <chr [5]> 21.8
## 6 Owen Lars 178 120 Tatooine Human <chr [3]> 37.9
## 7 Beru Whitesun lars 165 75 Tatooine Human <chr [3]> 27.5
## 8 R5-D4 97 32 Tatooine Droid <chr [1]> 34.0
## 9 Biggs Darklighter 183 84 Tatooine Human <chr [1]> 25.1
## 10 Obi-Wan Kenobi 182 77 Stewjon Human <chr [6]> 23.2
## # ... with 77 more rows
El %>% es heredado de python como concepto, se lee de izquierda a derecha, mientras que R normalmente lee de adentro hacia afuera (que en práctica es de derecha a izquierda).
Nuestro penúltimo verbo, arrange() no es otra cosa que hacer sort, entre paréntesis se selecciona la columna que lidera la nueva disposición de las filas.
## # A tibble: 87 x 13
## name height mass hair_color skin_color eye_color birth_year gender
## <chr> <int> <dbl> <chr> <chr> <chr> <dbl> <chr>
## 1 Jabb~ 175 1358 <NA> green-tan~ orange 600 herma~
## 2 Grie~ 216 159 none brown, wh~ green, y~ NA male
## 3 IG-88 200 140 none metal red 15 none
## 4 Dart~ 202 136 none white yellow 41.9 male
## 5 Tarf~ 234 136 brown brown blue NA male
## 6 Owen~ 178 120 brown, gr~ light blue 52 male
## 7 Bossk 190 113 none green red 53 male
## 8 Chew~ 228 112 brown unknown blue 200 male
## 9 Jek ~ 180 110 brown fair blue NA male
## 10 Dext~ 198 102 none brown yellow NA male
## # ... with 77 more rows, and 5 more variables: homeworld <chr>, species <chr>,
## # films <list>, vehicles <list>, starships <list>
La última sección es group_by() y summarise(). Para más información sobre [group_by()] (https://dplyr.tidyverse.org/reference/group_by.html).
Una vez agrupadas nuestras filas (conceptualemente) con summarise() le decimos a R que agarre a cada species, le aplique el promedio a mass y lo almacene en la misma columna mass.
starwars %>%
group_by(species) %>%
summarise(
n = n(),
mass = mean(mass, na.rm = TRUE)
) %>%
filter(n > 1,
mass > 50)## # A tibble: 8 x 3
## species n mass
## <chr> <int> <dbl>
## 1 Droid 5 69.8
## 2 Gungan 3 74
## 3 Human 35 82.8
## 4 Kaminoan 2 88
## 5 Mirialan 2 53.1
## 6 Twi'lek 2 55
## 7 Wookiee 2 124
## 8 Zabrak 2 80
tidyr
COMING SOON