-
Notifications
You must be signed in to change notification settings - Fork 12
/
05-transform.Rmd
551 lines (338 loc) · 14.5 KB
/
05-transform.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
# Transformación de datos {#transform}
## Introducción
```{r, message = FALSE}
library(tidyverse)
library(datos)
```
## 5.2 Filtrar filas con `filter()` {-#filter}
### 5.2.4 Ejercicios{-#ejercicios-524}
1. Encuentra todos los vuelos que:
1. Tuvieron un retraso de llegada de dos o más horas
<div class="solucion">
<h3>Solución</h3>
```{r}
filter(vuelos, atraso_llegada >= 120)
```
</div>
2. Volaron a Houston (`IAH` o` HOU`)
<div class="solucion">
<h3>Solución</h3>
```{r}
#Opcion 1
filter(vuelos, destino %in% c("IAH", "HOU"))
#Opción 2
filter(vuelos,destino == "IAH" | destino == "HOU" )
```
</div>
3. Fueron operados por United, American o Delta
<div class="solucion">
<h3>Solución</h3>
Los códigos de estas aerolíneas son `UA`, `AA` y `DL`.
```{r}
filter(vuelos, aerolinea %in% c("UA", "AA", "DL"))
```
</div>
4. Partieron en el invierno del hemisferio sur (julio, agosto y septiembre)
<div class="solucion">
<h3>Solución</h3>
```{r}
filter(vuelos, mes %in% c(7, 8, 9))
```
</div>
5. Llegaron más de dos horas tarde, pero no salieron tarde
<div class="solucion">
<h3>Solución</h3>
```{r}
filter(vuelos, atraso_salida <= 0 & atraso_llegada > 120)
```
</div>
6. Se retrasaron por lo menos una hora, pero repusieron más de 30 minutos en vuelo
<div class="solucion">
<h3>Solución</h3>
```{r}
filter(vuelos, atraso_salida >= 60 & atraso_salida - atraso_llegada > 30)
```
</div>
7. Partieron entre la medianoche y las 6 a.m. (incluyente)
<div class="solucion">
<h3>Solución</h3>
```{r}
filter(vuelos,horario_salida %in% c(1:600) | horario_salida == 2400 )
```
</div>
2. Otra función de **dplyr** útil para usar filtros es `between()`. ¿Qué hace? ¿Puedes usarlo para simplificar el código necesario para responder a los desafíos anteriores?
<div class="solucion">
<h3>Solución</h3>
Esta función del paquete __dplyr__ permite abreviar la escritura de código que tiene esta estructura `x >= derecha & x <= izquierda` por `between(x, derecha, izquierda)`.
Podemos reescribir el código para encontrar los vuelos que partieron en el invierno del hemisferio sur así:
```{r}
filter(vuelos, between(mes, 7, 9))
```
</div>
3. ¿Cuántos vuelos tienen datos faltantes de `horario_salida`? ¿Qué otras variables tienen valores faltantes? ¿Qué representan estas filas?
<div class="solucion">
<h3>Solución</h3>
Podemos buscar datos faltantes con la función `is.na`.
```{r}
filter(vuelos, is.na(horario_salida))
```
Los vuelos que tienen `NA` en su horario de salida, también lo tienen en el horario de llegada, por lo que se puede inferir que son vuelos que fueron cancelados.
</div>
4. ¿Por qué `NA ^ 0` no es faltante? ¿Por qué `NA | TRUE` no es faltante? ¿Por qué `FALSE & NA` no es faltante? ¿Puedes descubrir la regla general? (¡`NA * 0` es un contraejemplo complicado!)
<div class="solucion">
<h3>Solución</h3>
```{r}
x <- c(NA)
is.na(x)
```
La función `is.na()` determina si falta un valor y devuelve un valor lógico `TRUE` en los casos en que es NA (Not Available).
```{r}
x^0
```
Dado que el NA podría tomar cualquier valor, es práctico pensar que cualquier número (aunque sea muy grande) a la potencia cero es igual a 1.
```{r}
x | TRUE
```
Es igual a TRUE pues el NA se entiende como un valor lógico (`TRUE` or `FALSE`) y por lógica proposicional `TRUE` | `TRUE` y `FALSE` | `TRUE` es siempre igual a `TRUE`.
```{r}
x & FALSE
```
Es igual a `TRUE` pues el NA se entiende como un valor lógico (`TRUE` or `FALSE`) y por lógica proposicional `TRUE`&`FALSE` y `FALSE`&`FALSE` es siempre `FALSE`.
El contraejemplo a la regla general:
```{r}
x * 0
```
```{r}
Inf*0
```
En este contraejemplo puede ser útil pensar que el `NA` puede tomar cualquier valor, incluso podría ser un número muy grande; el cual al multiplicarse por cero nos da una indeterminación que `R` define como `NaN` (Not a Number). Por otro lado, si el `NA` fuese un valor pequeño, entonces `NA*0` sería igual a cero. Luego, es mejor pensar en `x*0` como un `NA` porque no sabemos en cual de los dos casos anteriores estamos.
</div>
## 5.3 Reordenar las filas con `arrange()` {-#arrange}
### 5.3.1 Ejercicios{-#ejercicios-531}
1. ¿Cómo podrías usar `arrange()` para ordenar todos los valores faltantes al comienzo? (Sugerencia: usa `is.na()`).
<div class="solucion">
<h3>Solución</h3>
```{r}
arrange(vuelos,desc(is.na(tiempo_vuelo)))
```
Se usa la variable `tiempo_vuelo` porque es la que contiene mayor número de NA´s.
</div>
2. Ordena `vuelos` para encontrar los vuelos más retrasados. Encuentra los vuelos que salieron más temprano.
<div class="solucion">
<h3>Solución</h3>
Vuelos que salieron con más retraso
```{r}
arrange(vuelos, desc(atraso_salida))
```
Vuelos que salieron más temprano
```{r}
arrange(vuelos, atraso_salida)
```
</div>
3. Ordena `vuelos` para encontrar los vuelos más rápidos.
<div class="solucion">
<h3>Solución</h3>
Si se considera que la velocidad es igual a `distancia`/`tiempo_vuelo` (distancia recorrida por minuto).
Los datos ordenados de forma descendente nos dará como resultado los vuelos más rápidos primero.
```{r}
arrange(vuelos,desc(distancia/tiempo_vuelo))
```
</div>
4. ¿Cuáles vuelos viajaron más lejos? ¿Cuál viajó menos cerca?
<div class="solucion">
<h3>Solución</h3>
Vuelos que viajaron más lejos (considerando la distancia en millas entre aeropuertos):
```{r}
arrange(vuelos,desc(distancia))
```
Vuelos que viajaron más cerca (considerando la distancia en millas entre aeropuertos):
```{r}
arrange(vuelos,distancia)
```
</div>
## 5.4 Seleccionar columnas con `select()` {-#select}
### 5.4.1 Ejercicios{-#ejercicios-541}
1. Haz una lluvia de ideas de tantas maneras como sea posible para seleccionar `horario_salida`,` atraso_salida`,`horario_llegada`, y` atraso_llegada` de `vuelos`.
<div class="solucion">
<h3>Solución</h3>
Una primera opción sería seleccionaras por su nombre:
```{r}
select(vuelos, horario_salida, atraso_salida, horario_llegada, atraso_llegada)
```
Otra forma es seleccionando las variables que empiezan con "horario" y "atraso" con la función `starts_with()` ("empieza con") del paquete __dplyr__:
```{r}
select(vuelos, starts_with("horario"), starts_with("atraso"))
```
También es útil en este caso utilizar la función `ends_with()`:
```{r}
select(vuelos,ends_with("llegada"),ends_with("salida"))
```
Y una manera adicional es usando la función `contains()`:
```{r}
select(vuelos,contains("horario"),contains("atraso"))
```
</div>
2. ¿Qué sucede si incluyes el nombre de una variable varias veces en una llamada `select()`?
<div class="solucion">
<h3>Solución</h3>
A diferencia de lo que podría pensarse inicialmente, aunque se incluya más de una vez una variable al utilizar `select()` esta solo se considerará una vez:
```{r}
select(vuelos, horario_salida, horario_salida, horario_salida)
```
</div>
3. ¿Qué hace la función `one_of()`? ¿Por qué podría ser útil en conjunto con este vector?
```{r}
vars <- c ("anio", "mes", "dia", "atraso_salida", "atraso_llegada")
```
<div class="solucion">
<h3>Solución</h3>
Con la función `one_of()` podemos indicar las variables que queremos seleccionar con el nombre del vector que las contiene.
La función `one_of()` selecciona todas las variables que están en el vector `vars`:
```{r}
select(vuelos, one_of(vars))
```
Sin embargo, es posible también hacerlo de la siguiente forma (Siempre y cuando no exista una variable que se llame `vars` en el set de datos):
```{r}
select(vuelos,vars)
```
</div>
4. ¿Te sorprende el resultado de ejecutar el siguiente código? ¿Cómo tratan por defecto las funciones auxiliares de `select()` a las palabras en mayúsculas o en minúsculas? ¿Cómo puedes cambiar ese comportamiento predeterminado?
```{r, eval = FALSE}
select(vuelos, contains("SALIDA"))
```
<div class="solucion">
<h3>Solución</h3>
La función `contains()` ("contiene") no distingue entre mayúsculas y minúsculas, por eso puede identificar sin problema todas las variables que contienen "salida". Si queremos cambiar este comportamiento y que sí las diferencie, entonces debemos agregar el argumento `ignore.case = FALSE` (por defecto, es TRUE):
```{r}
select(vuelos, contains("SALIDA", ignore.case = FALSE))
```
</div>
## 5.5 Añadir nuevas variables con `mutate()` {-#mutate}
### 5.5.2 Ejercicios{-#ejercicios-552}
```{r, eval = FALSE, echo = FALSE}
vuelos <- vuelos %>% mutate(
horario_salida = hora * 60 + minuto,
horario_llegada = (horario_llegada %/% 100) * 60 + (horario_llegada %% 100),
tiempo_vuelo2 = horario_llegada - horario_salida,
salida_programada = horario_salida + atraso_salida
)
ggplot(vuelos, aes(salida_programada)) + geom_histogram(binwidth = 60)
ggplot(vuelos, aes(salida_programada %% 60)) + geom_histogram(binwidth = 1)
ggplot(vuelos, aes(tiempo_vuelo - tiempo_vuelo2)) + geom_histogram()
```
1. Las variables `horario_salida` y `salida_programada` tienen un formato conveniente para leer, pero es difícil realizar cualquier cálculo con ellas porque no son realmente números continuos. Transfórmalas a un formato más conveniente, como número de minutos desde la medianoche.
<div class="solucion">
<h3>Solución</h3>
Los datos de estas variables son de tal forma que las 6:59 AM toman el valor 659. Luego, el número de horas desde la media noche es:
```{r}
659%/%100 #division entera
```
La cantidad de minutos en esas 6 horas:
```{r}
659%/%100 *60
```
Solo queda sumar los 59 minutos:
```{r}
659 %% 100 #resto
```
Entonces, el número de minutos transcurridos desde las 00:00 hasta las 6:59 AM son:
```{r}
659 %/% 100 * 60 + 659 %% 100
```
Sin embargo, la medianoche toma el valor 24:00 con lo cual el número de minutos desde la medianoche es 1440 en lugar de 0. Para resolver esto usamos nuevamente `%%`.
```{r}
(659 %/% 100 * 60 + 659 %% 100) %% 1440 #mismo resultado anterior
(2400 %/% 100 * 60 + 2400 %% 100) %% 1440 #cero minutos desde la medianoche
```
```{r}
mutate(vuelos, salida_programada_min = (salida_programada %/% 100 * 60 + salida_programada %% 100) %% 1440)
mutate(vuelos, horario_salida_min = (horario_salida %/% 100 * 60 + horario_salida %% 100) %% 1440)
```
</div>
2. Compara `tiempo_vuelo` con `horario_llegada - horario_salida`. ¿Qué esperas ver? ¿Qué ves? ¿Qué necesitas hacer para arreglarlo?
<div class="solucion">
<h3>Solución</h3>
Lo que se espera es que `tiempo_vuelo` = `horario_llegada` - `horario_salida`.
</div>
3. Compara `horario_salida`, `salida_programada`, y `atraso_salida`. ¿Cómo esperarías que esos tres números estén relacionados?
<div class="solucion">
<h3>Solución</h3>
</div>
4. Encuentra los 10 vuelos más retrasados utilizando una función de ordenamiento. ¿Cómo quieres manejar los empates? Lee atentamente la documentación de `min_rank()`.
<div class="solucion">
<h3>Solución</h3>
</div>
5. ¿Qué devuelve `1:3 + 1:10`? ¿Por qué?
<div class="solucion">
<h3>Solución</h3>
</div>
6. ¿Qué funciones trigonométricas proporciona R?
<div class="solucion">
<h3>Solución</h3>
</div>
## 5.6 Resúmenes agrupados con `summarise()` {-#sumamarise}
### 5.6.7 Ejercicios{-#ejercicios-567}
1. Haz una lluvia de ideas de al menos 5 formas diferentes de evaluar las características de un retraso típico de un grupo de vuelos. Considera los siguientes escenarios:
*Un vuelo llega 15 minutos antes 50% del tiempo, y 15 minutos tarde 50% del tiempo.
*Un vuelo llega siempre 10 minutos tarde.
*Un vuelo llega 30 minutos antes 50% del tiempo, y 30 minutos tarde 50% del tiempo.
*Un vuelo llega a tiempo en el 99% de los casos. 1% de las veces llega 2 horas tarde.
¿Qué es más importante: retraso de la llegada o demora de salida?
<div class="solucion">
<h3>Solución</h3>
</div>
2. Sugiere un nuevo enfoque que te dé el mismo *output* que `no_cancelados %>% count(destino)` y
`no_cancelado %>% count(codigo_cola, wt = distancia)` (sin usar `count()`).
<div class="solucion">
<h3>Solución</h3>
</div>
3. Nuestra definición de vuelos cancelados (`is.na(atraso_salida) | is.na (atraso_llegada)`) es un poco subóptima. ¿Por qué? ¿Cuál es la columna más importante?
<div class="solucion">
<h3>Solución</h3>
</div>
4. 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?
<div class="solucion">
<h3>Solución</h3>
</div>
5. ¿Qué compañía tiene los peores retrasos? Desafío: ¿puedes desenredar el efecto de malos aeropuertos vs. el efecto de malas aerolíneas? ¿Por qué o por qué no? (Sugerencia: piensa en `vuelos %>% group_by(aerolinea, destino) %>% summarise(n())`)
<div class="solucion">
<h3>Solución</h3>
</div>
6. ¿Qué hace el argumento `sort` a `count()`. ¿Cuándo podrías usarlo?
<div class="solucion">
<h3>Solución</h3>
</div>
## 5.7 Transformaciones agrupadas (y filtros) {-#mutate-filter}
### 5.7.1 Ejercicios {-#ejercicios-571}
1. Remítete a las listas de funciones útiles de mutación y filtrado. Describe cómo cambia cada operación cuando las combinas con la agrupación.
<div class="solucion">
<h3>Solución</h3>
</div>
2. ¿Qué avión (`codigo_cola`) tiene el peor registro de tiempo?
<div class="solucion">
<h3>Solución</h3>
</div>
3. ¿A qué hora del día deberías volar si quieres evitar los retrasos lo más posible?
<div class="solucion">
<h3>Solución</h3>
</div>
4. Para cada destino, calcula los minutos totales de demora. Para cada vuelo, calcula la proporción de la demora total para su destino.
<div class="solucion">
<h3>Solución</h3>
</div>
5. Los retrasos suelen estar temporalmente correlacionados: incluso una vez que el problema que causó el retraso inicial se ha resuelto, los vuelos posteriores se retrasan para permitir que salgan los vuelos anteriores. Usando `lag()`, explora cómo el retraso de un vuelo está relacionado con el retraso del vuelo inmediatamente anterior.
<div class="solucion">
<h3>Solución</h3>
</div>
6. Mira cada destino. ¿Puedes encontrar vuelos sospechosamente rápidos? (es decir, vuelos que representan un posible error de entrada de datos). Calcula el tiempo en el aire de un vuelo relativo al vuelo más corto a ese destino. ¿Cuáles vuelos se retrasaron más en el aire?
<div class="solucion">
<h3>Solución</h3>
</div>
7. Encuentra todos los destinos que son volados por al menos dos operadores. Usa esta información para clasificar a las aerolíneas.
<div class="solucion">
<h3>Solución</h3>
</div>
8. Para cada avión, cuenta el número de vuelos antes del primer retraso de más de 1 hora.
<div class="solucion">
<h3>Solución</h3>
</div>