Transformación de datos

Tomando las instrucciones de https://r4ds.had.co.nz/transform.html vamos a reforzar las nociones aprendidas de transformación de datos mediante el paquete dplyr

Para visualizar los resultados usaremos los paquetes nycflights13 y ggplot2

library(tidyverse)
library(nycflights13)

Datos

Tomamos del paquete nycflights13 los vuelos del año 2013 que contiene el dataframe.

vuelos <- nycflights13::flights
vuelos
## # A tibble: 336,776 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 336,766 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Repaso de funciones más usadas

Filter()

day_1of1 <- filter(vuelos, month==1, day==1)
day_1of1
## # A tibble: 842 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 832 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Ejericios:

1. Si queremos ver vuelos que no tengas retraso por mas de dos horas.

#filter(vuelos, !(arr_delay > 120 | dep_delay > 120))
(retraso <- filter(vuelos, arr_delay <= 120, dep_delay <= 120))
## # A tibble: 316,050 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 316,040 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

2. Si queremos ver si hay valores faltantes is.na()

#is.na(vuelos)

#filter(vuelos, is.na(vuelos))

3. Volaron hacia Houston (IAH or HOU)

# revisar y llegar al resultado de diferentes maneras.

vuelos %>% filter (dest == "HOU" | dest =="IAH")
## # A tibble: 9,313 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      623            627        -4      933            932
##  4  2013     1     1      728            732        -4     1041           1038
##  5  2013     1     1      739            739         0     1104           1038
##  6  2013     1     1      908            908         0     1228           1219
##  7  2013     1     1     1028           1026         2     1350           1339
##  8  2013     1     1     1044           1045        -1     1352           1351
##  9  2013     1     1     1114            900       134     1447           1222
## 10  2013     1     1     1205           1200         5     1503           1505
## # ℹ 9,303 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

4. Vuelos operados por United, American o Delta.

filter(vuelos, carrier %in% c("UA", "AA", "DL"))
## # A tibble: 139,504 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      554            600        -6      812            837
##  5  2013     1     1      554            558        -4      740            728
##  6  2013     1     1      558            600        -2      753            745
##  7  2013     1     1      558            600        -2      924            917
##  8  2013     1     1      558            600        -2      923            937
##  9  2013     1     1      559            600        -1      941            910
## 10  2013     1     1      559            600        -1      854            902
## # ℹ 139,494 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

5. Vuelos que salen en el verano(julio, agosto y septiembre)

(verano <- filter(vuelos, month %in% c(7,8,9)))
## # A tibble: 86,326 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     7     1        1           2029       212      236           2359
##  2  2013     7     1        2           2359         3      344            344
##  3  2013     7     1       29           2245       104      151              1
##  4  2013     7     1       43           2130       193      322             14
##  5  2013     7     1       44           2150       174      300            100
##  6  2013     7     1       46           2051       235      304           2358
##  7  2013     7     1       48           2001       287      308           2305
##  8  2013     7     1       58           2155       183      335             43
##  9  2013     7     1      100           2146       194      327             30
## 10  2013     7     1      100           2245       135      337            135
## # ℹ 86,316 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

6. Vuelos que se hayan demorado al menos una hora, pero que en el aire, en vuelo hayan estado más de 30 minutos.

(demo_masuno <- filter(vuelos, air_time >= 30, dep_delay >=60))
## # A tibble: 26,681 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      811            630       101     1047            830
##  2  2013     1     1      826            715        71     1136           1045
##  3  2013     1     1      848           1835       853     1001           1950
##  4  2013     1     1      957            733       144     1056            853
##  5  2013     1     1     1114            900       134     1447           1222
##  6  2013     1     1     1120            944        96     1331           1213
##  7  2013     1     1     1301           1150        71     1518           1345
##  8  2013     1     1     1337           1220        77     1649           1531
##  9  2013     1     1     1400           1250        70     1645           1502
## 10  2013     1     1     1505           1310       115     1638           1431
## # ℹ 26,671 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

7. Vuelos que salgan entre la medianoche y las 6 de la mañana (inclusive)

(vuelos_madrugada <- filter(vuelos, dep_time %in% c(0.00:6.00) ))
## # A tibble: 155 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     9        2           2359         3      432            444
##  2  2013     1    10        3           2359         4      426            437
##  3  2013     1    13        1           2249        72      108           2357
##  4  2013     1    13        2           2359         3      502            444
##  5  2013     1    13        3           2030       213      340           2350
##  6  2013     1    16        2           2125       157      119           2250
##  7  2013     1    16        3           1946       257      212           2154
##  8  2013     1    22        5           2359         6      452            444
##  9  2013     1    30        3           2159       124      100           2306
## 10  2013     1    31        1           2100       181      124           2225
## # ℹ 145 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>
# Otra forma con la función between()

(vuelos_madrugada <- filter(vuelos, between(dep_time, 0.00,6.00) ))
## # A tibble: 155 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     9        2           2359         3      432            444
##  2  2013     1    10        3           2359         4      426            437
##  3  2013     1    13        1           2249        72      108           2357
##  4  2013     1    13        2           2359         3      502            444
##  5  2013     1    13        3           2030       213      340           2350
##  6  2013     1    16        2           2125       157      119           2250
##  7  2013     1    16        3           1946       257      212           2154
##  8  2013     1    22        5           2359         6      452            444
##  9  2013     1    30        3           2159       124      100           2306
## 10  2013     1    31        1           2100       181      124           2225
## # ℹ 145 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

- Resolver:

  1. Cuantos vuelos no salieron a tiempo. Que otra variable estamos necesitando. Qué representa los campos.

dep_time y sched_dep_time son variables convenientes a ver pero debemos pasarlo a un formato de números continuos.

Arrange()

Recordar que acomoda el orden de las filas. orden by.

year <- arrange(flights, year, month, day)

# descendiente

arrange(flights, desc(dep_delay))
## # A tibble: 336,776 × 19
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     9      641            900      1301     1242           1530
##  2  2013     6    15     1432           1935      1137     1607           2120
##  3  2013     1    10     1121           1635      1126     1239           1810
##  4  2013     9    20     1139           1845      1014     1457           2210
##  5  2013     7    22      845           1600      1005     1044           1815
##  6  2013     4    10     1100           1900       960     1342           2211
##  7  2013     3    17     2321            810       911      135           1020
##  8  2013     6    27      959           1900       899     1236           2226
##  9  2013     7    22     2257            759       898      121           1026
## 10  2013    12     5      756           1700       896     1058           2020
## # ℹ 336,766 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>
vuelos <-vuelos %>%
  mutate (dep_t = dep_time / 100) %>%
  select(dep_t, dep_time, everything()) %>%
  mutate (sched_t = sched_dep_time / 100) %>%
  select(sched_t, sched_dep_time, everything()) 

Ejercicios:

1. Cómo usar arrange() para ordenar todos los valores que faltan al principio.

na <- arrange(vuelos, desc(is.na(flights)))
na
## # A tibble: 336,776 × 21
##    sched_t sched_dep_time dep_t dep_time  year month   day dep_delay arr_time
##      <dbl>          <int> <dbl>    <int> <int> <int> <int>     <dbl>    <int>
##  1   15.4            1545    NA       NA  2013     1     2        NA       NA
##  2   16.0            1601    NA       NA  2013     1     2        NA       NA
##  3    8.57            857    NA       NA  2013     1     3        NA       NA
##  4    6.45            645    NA       NA  2013     1     3        NA       NA
##  5    8.45            845    NA       NA  2013     1     4        NA       NA
##  6   18.3            1830    NA       NA  2013     1     4        NA       NA
##  7    8.4             840    NA       NA  2013     1     5        NA       NA
##  8    8.2             820    NA       NA  2013     1     7        NA       NA
##  9   16.4            1645    NA       NA  2013     1     8        NA       NA
## 10    7.55            755    NA       NA  2013     1     9        NA       NA
## # ℹ 336,766 more rows
## # ℹ 12 more variables: sched_arr_time <int>, arr_delay <dbl>, carrier <chr>,
## #   flight <int>, tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>,
## #   distance <dbl>, hour <dbl>, minute <dbl>, time_hour <dttm>

2. Vuelo más demorado. Y vuelo que sale más temprano

v_demorado <- arrange(vuelos, desc(dep_delay))
v_temprano <- arrange(vuelos, dep_time)
v_rapidos <- arrange(vuelos, dep_delay)

select()

select(vuelos, year, month,day)
## # A tibble: 336,776 × 3
##     year month   day
##    <int> <int> <int>
##  1  2013     1     1
##  2  2013     1     1
##  3  2013     1     1
##  4  2013     1     1
##  5  2013     1     1
##  6  2013     1     1
##  7  2013     1     1
##  8  2013     1     1
##  9  2013     1     1
## 10  2013     1     1
## # ℹ 336,766 more rows
# todas las columnas entre year y day 

select(vuelos, year:day)
## # A tibble: 336,776 × 3
##     year month   day
##    <int> <int> <int>
##  1  2013     1     1
##  2  2013     1     1
##  3  2013     1     1
##  4  2013     1     1
##  5  2013     1     1
##  6  2013     1     1
##  7  2013     1     1
##  8  2013     1     1
##  9  2013     1     1
## 10  2013     1     1
## # ℹ 336,766 more rows
# exceptuando

select(vuelos, -(year:day))
## # A tibble: 336,776 × 18
##    sched_t sched_dep_time dep_t dep_time dep_delay arr_time sched_arr_time
##      <dbl>          <int> <dbl>    <int>     <dbl>    <int>          <int>
##  1    5.15            515  5.17      517         2      830            819
##  2    5.29            529  5.33      533         4      850            830
##  3    5.4             540  5.42      542         2      923            850
##  4    5.45            545  5.44      544        -1     1004           1022
##  5    6               600  5.54      554        -6      812            837
##  6    5.58            558  5.54      554        -4      740            728
##  7    6               600  5.55      555        -5      913            854
##  8    6               600  5.57      557        -3      709            723
##  9    6               600  5.57      557        -3      838            846
## 10    6               600  5.58      558        -2      753            745
## # ℹ 336,766 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Se puede utilizar para muchas funciones. Ejemplo: starts_with(“abc”), end_with, contains, matches, num_range Se puede utilizar como rename() pero mejor utilizar rename. ej rename(vuelos, tal_num = tailnum)

Si es muy grande la base usamos everything.

select(vuelos, time_hour, air_time, everything())
## # A tibble: 336,776 × 21
##    time_hour           air_time sched_t sched_dep_time dep_t dep_time  year
##    <dttm>                 <dbl>   <dbl>          <int> <dbl>    <int> <int>
##  1 2013-01-01 05:00:00      227    5.15            515  5.17      517  2013
##  2 2013-01-01 05:00:00      227    5.29            529  5.33      533  2013
##  3 2013-01-01 05:00:00      160    5.4             540  5.42      542  2013
##  4 2013-01-01 05:00:00      183    5.45            545  5.44      544  2013
##  5 2013-01-01 06:00:00      116    6               600  5.54      554  2013
##  6 2013-01-01 05:00:00      150    5.58            558  5.54      554  2013
##  7 2013-01-01 06:00:00      158    6               600  5.55      555  2013
##  8 2013-01-01 06:00:00       53    6               600  5.57      557  2013
##  9 2013-01-01 06:00:00      140    6               600  5.57      557  2013
## 10 2013-01-01 06:00:00      138    6               600  5.58      558  2013
## # ℹ 336,766 more rows
## # ℹ 14 more variables: month <int>, day <int>, dep_delay <dbl>, arr_time <int>,
## #   sched_arr_time <int>, arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, distance <dbl>, hour <dbl>,
## #   minute <dbl>

Ejercicios

1. seleccionar algunas variables.

select(vuelos, dep_time, dep_delay, arr_time, arr_delay)
## # A tibble: 336,776 × 4
##    dep_time dep_delay arr_time arr_delay
##       <int>     <dbl>    <int>     <dbl>
##  1      517         2      830        11
##  2      533         4      850        20
##  3      542         2      923        33
##  4      544        -1     1004       -18
##  5      554        -6      812       -25
##  6      554        -4      740        12
##  7      555        -5      913        19
##  8      557        -3      709       -14
##  9      557        -3      838        -8
## 10      558        -2      753         8
## # ℹ 336,766 more rows
# funcion any_of()

vars <- c("year", "month", "day", "dep_delay", "arr_delay")

select(vuelos, any_of(vars))
## # A tibble: 336,776 × 5
##     year month   day dep_delay arr_delay
##    <int> <int> <int>     <dbl>     <dbl>
##  1  2013     1     1         2        11
##  2  2013     1     1         4        20
##  3  2013     1     1         2        33
##  4  2013     1     1        -1       -18
##  5  2013     1     1        -6       -25
##  6  2013     1     1        -4        12
##  7  2013     1     1        -5        19
##  8  2013     1     1        -3       -14
##  9  2013     1     1        -3        -8
## 10  2013     1     1        -2         8
## # ℹ 336,766 more rows
select(vuelos, (contains("TIME")))
## # A tibble: 336,776 × 6
##    sched_dep_time dep_time arr_time sched_arr_time air_time time_hour          
##             <int>    <int>    <int>          <int>    <dbl> <dttm>             
##  1            515      517      830            819      227 2013-01-01 05:00:00
##  2            529      533      850            830      227 2013-01-01 05:00:00
##  3            540      542      923            850      160 2013-01-01 05:00:00
##  4            545      544     1004           1022      183 2013-01-01 05:00:00
##  5            600      554      812            837      116 2013-01-01 06:00:00
##  6            558      554      740            728      150 2013-01-01 05:00:00
##  7            600      555      913            854      158 2013-01-01 06:00:00
##  8            600      557      709            723       53 2013-01-01 06:00:00
##  9            600      557      838            846      140 2013-01-01 06:00:00
## 10            600      558      753            745      138 2013-01-01 06:00:00
## # ℹ 336,766 more rows

mutate()

vuelos_sml <- select(vuelos,year:day,
                     ends_with("delay"),
                     distance,
                     air_time)
mutate(vuelos_sml,
  gain = dep_delay - arr_delay,
  speed = distance / air_time * 60
  )
## # A tibble: 336,776 × 9
##     year month   day dep_delay arr_delay distance air_time  gain speed
##    <int> <int> <int>     <dbl>     <dbl>    <dbl>    <dbl> <dbl> <dbl>
##  1  2013     1     1         2        11     1400      227    -9  370.
##  2  2013     1     1         4        20     1416      227   -16  374.
##  3  2013     1     1         2        33     1089      160   -31  408.
##  4  2013     1     1        -1       -18     1576      183    17  517.
##  5  2013     1     1        -6       -25      762      116    19  394.
##  6  2013     1     1        -4        12      719      150   -16  288.
##  7  2013     1     1        -5        19     1065      158   -24  404.
##  8  2013     1     1        -3       -14      229       53    11  259.
##  9  2013     1     1        -3        -8      944      140     5  405.
## 10  2013     1     1        -2         8      733      138   -10  319.
## # ℹ 336,766 more rows

Si queremos usar solo las nuevas variables creadas, usamos transmute()

transmute(vuelos,
  gain = dep_delay - arr_delay,
  hours = air_time / 60,
  gain_per_hour = gain / hours
  )
## # A tibble: 336,776 × 3
##     gain hours gain_per_hour
##    <dbl> <dbl>         <dbl>
##  1    -9 3.78          -2.38
##  2   -16 3.78          -4.23
##  3   -31 2.67         -11.6 
##  4    17 3.05           5.57
##  5    19 1.93           9.83
##  6   -16 2.5           -6.4 
##  7   -24 2.63          -9.11
##  8    11 0.883         12.5 
##  9     5 2.33           2.14
## 10   -10 2.3           -4.35
## # ℹ 336,766 more rows

Nota La clave principal es: vectorizar. + operadores aritméticos ej: air_time / 60, hour * 60+ minutes, etc. otros: x / sum(x) calcula una porción del total, y y- mean(y) calcula la diferencia de la media

  • dividir por ejemplo horas, minutos y segundos: %/% ( division integer) %%(resto)
transmute(vuelos,
          dep_time,
          hour = dep_time %/% 100,
          minute = dep_time %% 100)
## # A tibble: 336,776 × 3
##    dep_time  hour minute
##       <int> <dbl>  <dbl>
##  1      517     5     17
##  2      533     5     33
##  3      542     5     42
##  4      544     5     44
##  5      554     5     54
##  6      554     5     54
##  7      555     5     55
##  8      557     5     57
##  9      557     5     57
## 10      558     5     58
## # ℹ 336,766 more rows
  • interesante loslogs: log(), log2(), log10(). transforma en orden de magnitud logaritmica.

  • Offsets: lead(), and lag() valores adelantados o atrasados.

(x <- 1:10)
##  [1]  1  2  3  4  5  6  7  8  9 10
lag(x)
##  [1] NA  1  2  3  4  5  6  7  8  9
lead(x)
##  [1]  2  3  4  5  6  7  8  9 10 NA
  • Sumas acumulativas, minimos y máximos: cumsum(), cumprod(),cummin(), cummax(); cumean() -RcppRoll-

  • rankings ver que hacen estas funciones:min_rank(), row_number(), dense_rank(), percent_rank(), cume_dist(), ntile().

Ejercicios

1- Comparar air_time con arr_time - dep_time. Que esperamos ver. Que vemos. Que necesitamos arreglar.

vuelos <-vuelos %>%
  mutate(air_t = air_time /100) %>%
  select(air_t, air_time, everything()) %>%
  mutate(arr_t = arr_time/100) %>%
  select(arr_t, everything())

2- Analizar dep_t, sched_t y dep_delay

vuelos %>% select(dep_t, sched_t, dep_delay)
## # A tibble: 336,776 × 3
##    dep_t sched_t dep_delay
##    <dbl>   <dbl>     <dbl>
##  1  5.17    5.15         2
##  2  5.33    5.29         4
##  3  5.42    5.4          2
##  4  5.44    5.45        -1
##  5  5.54    6           -6
##  6  5.54    5.58        -4
##  7  5.55    6           -5
##  8  5.57    6           -3
##  9  5.57    6           -3
## 10  5.58    6           -2
## # ℹ 336,766 more rows

3- Encuentro los 10 vuelos más demorados usando la función ranking.

Summaries with summarise()

summarise(vuelos, delay =mean(dep_delay, na.rm = TRUE))
## # A tibble: 1 × 1
##   delay
##   <dbl>
## 1  12.6

summarise + group_by()

by_day <- group_by(vuelos, year, month, day)
summarise(by_day, delay = mean(dep_delay, na.rm = TRUE))
## `summarise()` has grouped output by 'year', 'month'. You can override using the
## `.groups` argument.
## # A tibble: 365 × 4
## # Groups:   year, month [12]
##     year month   day delay
##    <int> <int> <int> <dbl>
##  1  2013     1     1 11.5 
##  2  2013     1     2 13.9 
##  3  2013     1     3 11.0 
##  4  2013     1     4  8.95
##  5  2013     1     5  5.73
##  6  2013     1     6  7.15
##  7  2013     1     7  5.42
##  8  2013     1     8  2.55
##  9  2013     1     9  2.28
## 10  2013     1    10  2.84
## # ℹ 355 more rows

Concepto de Pipa

Si queremos ver la relación entre la distancia y el promedio de demoras por cada ubicación. Podemos:

by_dest <- group_by(flights, dest)
delay <- summarise(by_dest,
  count = n(),
  dist = mean(distance, na.rm = TRUE),
  delay = mean(arr_delay, na.rm = TRUE)
)
delay <- filter(delay, count > 20, dest != "HNL")
# Mejor forma de escribir con pipa

delays <- flights %>% 
  group_by(dest) %>% 
  summarise(
    count = n(),
    dist = mean(distance, na.rm = TRUE),
    delay = mean(arr_delay, na.rm = TRUE)
  ) %>% 
  filter(count > 20, dest != "HNL")
ggplot(data = delay, mapping = aes(x = dist, y = delay)) +
  geom_point(aes(size = count), alpha = 1/3) +
  geom_smooth(se = FALSE)
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

Missing value

not_cancelled <- flights %>% 
  filter(!is.na(dep_delay), !is.na(arr_delay))

not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(mean = mean(dep_delay))
## `summarise()` has grouped output by 'year', 'month'. You can override using the
## `.groups` argument.
## # A tibble: 365 × 4
## # Groups:   year, month [12]
##     year month   day  mean
##    <int> <int> <int> <dbl>
##  1  2013     1     1 11.4 
##  2  2013     1     2 13.7 
##  3  2013     1     3 10.9 
##  4  2013     1     4  8.97
##  5  2013     1     5  5.73
##  6  2013     1     6  7.15
##  7  2013     1     7  5.42
##  8  2013     1     8  2.56
##  9  2013     1     9  2.30
## 10  2013     1    10  2.84
## # ℹ 355 more rows

Counts

Cuando se hacen agregaciones es buena idea contar )n()) o contar los valores perdidos (sum(!is.na(x))) así se pueden chequear los resultados basados en un pequeño grupo de datos. Ej. ( planes in tailnum) que tiene el primedio más alto de las demoras.

delays <- not_cancelled %>% 
  group_by(tailnum) %>% 
  summarise(
    delay = mean(arr_delay)
  )

ggplot(data = delays, mapping = aes(x = delay)) + 
  geom_freqpoly(binwidth = 10)

Con más detalle para ver numeros de vuelos y el promedio de demoras:

delays <- not_cancelled %>% 
  group_by(tailnum) %>% 
  summarise(
    delay = mean(arr_delay, na.rm = TRUE),
    n = n()
  )

ggplot(data = delays, mapping = aes(x = n, y = delay)) + 
  geom_point(alpha = 1/10)

No sorprende, de que hay mas variación en el promedio de demora cuando tomamos pocos vuelos. Cuando miramos este tipo de gráfica usualmente es útil que filtramos con los números más chicos de observaciones, así podemos ver los patrones y menos las variaciones. Esto es lo que permite el código.

Tal vez cueste al principio acostumbrarse pero luego ya nos queda interiorizado y nos facilita bastante.

delays %>% 
  filter(n > 25) %>% 
  ggplot(mapping = aes(x = n, y = delay)) + 
    geom_point(alpha = 1/10)

Otra variación en estos patrones.

Para ver esto, tomamos los datos del paquete Lahman, queremos ver el promedio de las ligas mayores de basquet ( número de aciertos / número de intentos)

Veremos:

  • La variación desciende cuando agregamos más datos.
  • Hay una relación correlativa positiva entre “skill” y la oportunidad de acierto (ab). Esto es porque el equipo elige obviamente el mejor jugador.
# Convertimos a tibble. 

#batting <- as_tibble(Lahman::Batting)

#batters <- batting %>%
#  group_by(playerID) %>%
#  summarise(
#    ba = sum(H, na.rm = TRUE / sum(AB, na.rm = TRUE),
#             ab = sum(AB, na.rm = TRUE))
#  )

#batters %>%
#  filter(ab > 100) %>%
#  ggplot(mapping = aes(x =ab, y =ba)) +
#  geom_point() +
#  geom_smooth(se = FALSE)

# geom_smooth() usa el método = gam y la formula es 'y ~ s(x, bs = "cs")

Esto también tiene implicaciones importantes para la clasificación. Si clasifica ingenuamente en desc (ba), las personas con los mejores promedios de bateo son claramente afortunadas, no hábiles:

http://varianceexplained.org/r/empirical_bayes_baseball/ and http://www.evanmiller.org/how-not-to-sort-by-average-rating.html>

#batters %>% 
#  arrange(desc(ba))

Funciones comunes de Summary

Las medidas means, conts y sum nos brindan mucha información. Tengamos en cuenta estas medidas por ubicación: mean() entendiendo que es la suma dividida la longitud. median() es el punto medio del 50% arriba y abajo de los datos.

not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(
    avg_delay1 = mean(arr_delay),
    avg_delay2 = mean(arr_delay[arr_delay > 0]))
## `summarise()` has grouped output by 'year', 'month'. You can override using the
## `.groups` argument.
## # A tibble: 365 × 5
## # Groups:   year, month [12]
##     year month   day avg_delay1 avg_delay2
##    <int> <int> <int>      <dbl>      <dbl>
##  1  2013     1     1     12.7         32.5
##  2  2013     1     2     12.7         32.0
##  3  2013     1     3      5.73        27.7
##  4  2013     1     4     -1.93        28.3
##  5  2013     1     5     -1.53        22.6
##  6  2013     1     6      4.24        24.4
##  7  2013     1     7     -4.95        27.8
##  8  2013     1     8     -3.23        20.8
##  9  2013     1     9     -0.264       25.6
## 10  2013     1    10     -5.90        27.3
## # ℹ 355 more rows
# usamos >0 para que sean positivos 

Medidas de desviaciones - spread-: sd(x), IQR(), mad(x) repasemos que son:3

sd(x) Desviación estándar, raiz del promedio cuadrado de la desviación ( mejor dicho: desviación cuadrática media raíz) es la medida estándar de la desviación.

IQR rango intercuartil

mad() media absoluta de la desviación. Esta medida es robusta y es muy útil si tenemos valores atípicos.

Ejemplo: ¿Porqué algunos destinos son más variables que otros?

not_cancelled %>% 
  group_by(dest) %>% 
  summarise(distance_sd = sd(distance)) %>% 
  arrange(desc(distance_sd))
## # A tibble: 104 × 2
##    dest  distance_sd
##    <chr>       <dbl>
##  1 EGE         10.5 
##  2 SAN         10.4 
##  3 SFO         10.2 
##  4 HNL         10.0 
##  5 SEA          9.98
##  6 LAS          9.91
##  7 PDX          9.87
##  8 PHX          9.86
##  9 LAX          9.66
## 10 IND          9.46
## # ℹ 94 more rows

Medidas de rank min, quantiles, max. Los quantiles son la generalización de la mediana -median- Por ejemplo, quantile(x, 0.25) encontraremos valores de x que sean mas grande que el 25% y menos que el 75%

Ejemplo: ¿Cuándo sale el primer y el último avión?

not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(
    first = min(dep_time),
    last = max(dep_time)
  )
## `summarise()` has grouped output by 'year', 'month'. You can override using the
## `.groups` argument.
## # A tibble: 365 × 5
## # Groups:   year, month [12]
##     year month   day first  last
##    <int> <int> <int> <int> <int>
##  1  2013     1     1   517  2356
##  2  2013     1     2    42  2354
##  3  2013     1     3    32  2349
##  4  2013     1     4    25  2358
##  5  2013     1     5    14  2357
##  6  2013     1     6    16  2355
##  7  2013     1     7    49  2359
##  8  2013     1     8   454  2351
##  9  2013     1     9     2  2252
## 10  2013     1    10     3  2320
## # ℹ 355 more rows

Medidas de posición first(), nth(), last() primero, segundo y último.

not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(
    first_dep = first(dep_time), 
    last_dep = last(dep_time)
  )
## `summarise()` has grouped output by 'year', 'month'. You can override using the
## `.groups` argument.
## # A tibble: 365 × 5
## # Groups:   year, month [12]
##     year month   day first_dep last_dep
##    <int> <int> <int>     <int>    <int>
##  1  2013     1     1       517     2356
##  2  2013     1     2        42     2354
##  3  2013     1     3        32     2349
##  4  2013     1     4        25     2358
##  5  2013     1     5        14     2357
##  6  2013     1     6        16     2355
##  7  2013     1     7        49     2359
##  8  2013     1     8       454     2351
##  9  2013     1     9         2     2252
## 10  2013     1    10         3     2320
## # ℹ 355 more rows

Podemos utilizar estas funciones con filter, así nos da todas las variables con las observaciones en filas separadas.

not_cancelled %>% 
  group_by(year, month, day) %>% 
  mutate(r = min_rank(desc(dep_time))) %>% 
  filter(r %in% range(r))
## # A tibble: 770 × 20
## # Groups:   year, month, day [365]
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1     2356           2359        -3      425            437
##  3  2013     1     2       42           2359        43      518            442
##  4  2013     1     2     2354           2359        -5      413            437
##  5  2013     1     3       32           2359        33      504            442
##  6  2013     1     3     2349           2359       -10      434            445
##  7  2013     1     4       25           2359        26      505            442
##  8  2013     1     4     2358           2359        -1      429            437
##  9  2013     1     4     2358           2359        -1      436            445
## 10  2013     1     5       14           2359        15      503            445
## # ℹ 760 more rows
## # ℹ 12 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>, r <int>

** counts: vimos n()que no toma argumentos sino que nos da el tamaño del grupo. si queremos contar el número de los valores no perdidos, sum(!is.na(x)). Contar el número de valores únicos (unique) usamos n_distint(x)

Ejemplo: ¿Qué destinos tienen más transportistas?

not_cancelled %>% 
  group_by(dest) %>% 
  summarise(carriers = n_distinct(carrier)) %>% 
  arrange(desc(carriers))
## # A tibble: 104 × 2
##    dest  carriers
##    <chr>    <int>
##  1 ATL          7
##  2 BOS          7
##  3 CLT          7
##  4 ORD          7
##  5 TPA          7
##  6 AUS          6
##  7 DCA          6
##  8 DTW          6
##  9 IAD          6
## 10 MSP          6
## # ℹ 94 more rows

Si queremos solo contar dplyr nos provee un ayudante perfecto:

not_cancelled %>% 
  count(dest)
## # A tibble: 104 × 2
##    dest      n
##    <chr> <int>
##  1 ABQ     254
##  2 ACK     264
##  3 ALB     418
##  4 ANC       8
##  5 ATL   16837
##  6 AUS    2411
##  7 AVL     261
##  8 BDL     412
##  9 BGR     358
## 10 BHM     269
## # ℹ 94 more rows

Si queremos darle peso a la variables, por ejemplo vemos la cantidad de millas que voló ese avion.

not_cancelled %>% 
  count(tailnum, wt = distance)
## # A tibble: 4,037 × 2
##    tailnum      n
##    <chr>    <dbl>
##  1 D942DN    3418
##  2 N0EGMQ  239143
##  3 N10156  109664
##  4 N102UW   25722
##  5 N103US   24619
##  6 N104UW   24616
##  7 N10575  139903
##  8 N105UW   23618
##  9 N107US   21677
## 10 N108UW   32070
## # ℹ 4,027 more rows

Podemos hacer mix con los valores lógicos. sum(x>10), mean(y==0) Cuando usamos funciones numericas, TRUE se convierte en 1 y FALSE se convierte en 0. Esto nos convierte las funciones sum() y mean() muy útiles: sum() nos va el numero de TRUE s in x, y mean() nos da la proporción.

¿ Cuantos vuelos salieron antes de las 5am? ( generalmente son vuelos demorados)

not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(n_early = sum(dep_time < 500))
## `summarise()` has grouped output by 'year', 'month'. You can override using the
## `.groups` argument.
## # A tibble: 365 × 4
## # Groups:   year, month [12]
##     year month   day n_early
##    <int> <int> <int>   <int>
##  1  2013     1     1       0
##  2  2013     1     2       3
##  3  2013     1     3       4
##  4  2013     1     4       3
##  5  2013     1     5       3
##  6  2013     1     6       2
##  7  2013     1     7       2
##  8  2013     1     8       1
##  9  2013     1     9       3
## 10  2013     1    10       3
## # ℹ 355 more rows

¿Que proporción de vuelos están demorados por más de una hora?

not_cancelled %>% 
  group_by(year, month, day) %>% 
  summarise(hour_prop = mean(arr_delay > 60))
## `summarise()` has grouped output by 'year', 'month'. You can override using the
## `.groups` argument.
## # A tibble: 365 × 4
## # Groups:   year, month [12]
##     year month   day hour_prop
##    <int> <int> <int>     <dbl>
##  1  2013     1     1    0.0722
##  2  2013     1     2    0.0851
##  3  2013     1     3    0.0567
##  4  2013     1     4    0.0396
##  5  2013     1     5    0.0349
##  6  2013     1     6    0.0470
##  7  2013     1     7    0.0333
##  8  2013     1     8    0.0213
##  9  2013     1     9    0.0202
## 10  2013     1    10    0.0183
## # ℹ 355 more rows

Agrupar por múltiples variables

Cuando se agrupa varias variables, cada summary elimina un nivel de esa agrupación. Esto facilita la acumulación progresiva de un conjunto de datos.

daily <- group_by(vuelos, year, month, day)
(per_day <- summarise(daily, flights =n()))
## `summarise()` has grouped output by 'year', 'month'. You can override using the
## `.groups` argument.
## # A tibble: 365 × 4
## # Groups:   year, month [12]
##     year month   day flights
##    <int> <int> <int>   <int>
##  1  2013     1     1     842
##  2  2013     1     2     943
##  3  2013     1     3     914
##  4  2013     1     4     915
##  5  2013     1     5     720
##  6  2013     1     6     832
##  7  2013     1     7     933
##  8  2013     1     8     899
##  9  2013     1     9     902
## 10  2013     1    10     932
## # ℹ 355 more rows
(per_month <- summarise(per_day, flights = sum(flights)))
## `summarise()` has grouped output by 'year'. You can override using the
## `.groups` argument.
## # A tibble: 12 × 3
## # Groups:   year [1]
##     year month flights
##    <int> <int>   <int>
##  1  2013     1   27004
##  2  2013     2   24951
##  3  2013     3   28834
##  4  2013     4   28330
##  5  2013     5   28796
##  6  2013     6   28243
##  7  2013     7   29425
##  8  2013     8   29327
##  9  2013     9   27574
## 10  2013    10   28889
## 11  2013    11   27268
## 12  2013    12   28135
(per_year  <- summarise(per_month, flights = sum(flights)))
## # A tibble: 1 × 2
##    year flights
##   <int>   <int>
## 1  2013  336776

Ungrouping

Desarmando lo armado. Desagrupamos.

daily %>%
  ungroup()%>%
  summarise(flights =n())
## # A tibble: 1 × 1
##   flights
##     <int>
## 1  336776

EJERCICIOS:

  1. Cinco formas de atraso de vuelo.
  • Un vuelo esta 15 minutos antes ( 50% del timepo) y 15 minutos tarde el otro 50% del tiempo.

  • Un vuelo por lo general tiene 10 minutos de demora.

  • 99% de los vuelos estan a tiempo. 1% incurren en 2 horas de demora.

¿Qué es más importante: el retraso en la llegada o el retraso en la salida?

Proponga otro enfoque que le proporcione el mismo resultado que not_cancelled %>% count(dest) y not_cancelled %>% count(tailnum, wt = distance) (sin usar count()).

Nuestra definición de vuelos cancelados (is.na(dep_delay) | is.na(arr_delay) ) es ligeramente inferior a la óptima. ¿Por qué? ¿Cuál es la columna más importante?

Mira la cantidad de vuelos cancelados por día. ¿Hay un patrón? ¿La proporción de vuelos cancelados está relacionada con el retraso promedio?

¿Qué transportista tiene los peores retrasos? Desafío: ¿puede desentrañar los efectos de los malos aeropuertos frente a los malos transportistas? ¿Por qué por qué no? (Sugerencia: piensa en vuelos %>% group_by(carrier, dest) %>% summarise(n()))

¿Qué hace el argumento de clasificación para contar ()? ¿Cuándo podría usarlo?

Grouped mutates ( y filters)

Agrupar es muy útil junto a summarise(), pero también es conveniente las operaciones con mutate() y filter()

Encuentra los peores miembros de cada grupo.

#flights_sml %>% 
  group_by(year, month, day) %>%
  filter(rank(desc(arr_delay)) < 10)
## # A tibble: 3,306 × 19
## # Groups:   month, day [365]
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      848           1835       853     1001           1950
##  2  2013     1     1     1815           1325       290     2120           1542
##  3  2013     1     1     1842           1422       260     1958           1535
##  4  2013     1     1     1942           1705       157     2124           1830
##  5  2013     1     1     2006           1630       216     2230           1848
##  6  2013     1     1     2115           1700       255     2330           1920
##  7  2013     1     1     2205           1720       285       46           2040
##  8  2013     1     1     2312           2000       192       21           2110
##  9  2013     1     1     2343           1724       379      314           1938
## 10  2013     1     2     1244            900       224     1431           1104
## # ℹ 3,296 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Encuentre todos los grupos más grandes que un umbral:

popular_dests <- flights %>% 
  group_by(dest) %>% 
  filter(n() > 365)
popular_dests
## # A tibble: 332,577 × 19
## # Groups:   dest [77]
##     year month   day dep_time sched_dep_time dep_delay arr_time sched_arr_time
##    <int> <int> <int>    <int>          <int>     <dbl>    <int>          <int>
##  1  2013     1     1      517            515         2      830            819
##  2  2013     1     1      533            529         4      850            830
##  3  2013     1     1      542            540         2      923            850
##  4  2013     1     1      544            545        -1     1004           1022
##  5  2013     1     1      554            600        -6      812            837
##  6  2013     1     1      554            558        -4      740            728
##  7  2013     1     1      555            600        -5      913            854
##  8  2013     1     1      557            600        -3      709            723
##  9  2013     1     1      557            600        -3      838            846
## 10  2013     1     1      558            600        -2      753            745
## # ℹ 332,567 more rows
## # ℹ 11 more variables: arr_delay <dbl>, carrier <chr>, flight <int>,
## #   tailnum <chr>, origin <chr>, dest <chr>, air_time <dbl>, distance <dbl>,
## #   hour <dbl>, minute <dbl>, time_hour <dttm>

Estandarizar para calcular métricas por grupo:

popular_dests %>% 
  filter(arr_delay > 0) %>% 
  mutate(prop_delay = arr_delay / sum(arr_delay)) %>% 
  select(year:day, dest, arr_delay, prop_delay)
## # A tibble: 131,106 × 6
## # Groups:   dest [77]
##     year month   day dest  arr_delay prop_delay
##    <int> <int> <int> <chr>     <dbl>      <dbl>
##  1  2013     1     1 IAH          11  0.000111 
##  2  2013     1     1 IAH          20  0.000201 
##  3  2013     1     1 MIA          33  0.000235 
##  4  2013     1     1 ORD          12  0.0000424
##  5  2013     1     1 FLL          19  0.0000938
##  6  2013     1     1 ORD           8  0.0000283
##  7  2013     1     1 LAX           7  0.0000344
##  8  2013     1     1 DFW          31  0.000282 
##  9  2013     1     1 ATL          12  0.0000400
## 10  2013     1     1 DTW          16  0.000116 
## # ℹ 131,096 more rows

Ejercicios

  • Revisa las listas de funciones útiles de mutación y filtrado. Describí cómo cambia cada operacón cuando la combinamos con la agrupación.

  • ¿Qué avión (tailnum) tiene el peor récord de puntualidad?

  • ¿A qué hora del día debemos volar si queremos evitar los retrasos tanto como sea posible?

  • Para cada destino, calcular el total de minutos de demora. Para cada vuelo, calcular la proporción de la demora total para su destino.

  • Los retrasos suelen tener una correlación temporal: incluso una vez que se ha resuelto el problema que causó el retraso inicial, los vuelos posteriores se retrasan para permitir que salgan los vuelos anteriores. Usando lag(), explora cómo se relaciona el retraso de un vuelo con el retraso del vuelo inmediatamente anterior.

  • Mira cada destino. ¿Podes encontrar vuelos sospechosamente rápidos? (es decir, vuelos que representan un posible error de entrada de datos). Calcular el tiempo de aire de un vuelo en relación con el vuelo más corto a ese destino. ¿Qué vuelos se retrasaron más en el aire?

  • Encontrá todos los destinos en los que vuelan al menos dos transportistas. Utilizá esa información para clasificar a los transportistas.

  • Para cada avión, contá el número de vuelos antes del primer retraso de más de 1 hora.