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:

dplyr

Sus principales verbos son:

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.

# Observo el dataset para ver que estoy tratando

glimpse(starwars)
## 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 ...
head(starwars)
## # 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>
tail(starwars)
## # 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"
print(starwars)
## # 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.

starwars %>% 
  arrange(desc(mass))
## # 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