library(tidyverse)
library(modelr)
library(nycflights13)
library(lubridate)
library(datos)
library(ggdark)
library(ggrepel)
library(RColorBrewer)
library(patchwork)
dark_theme <- list(dark_theme_gray(base_family = "Fira Sans Condensed Light", base_size = 14) +
theme(plot.title = element_text(family = "Fira Sans Condensed", size=rel(0.94), color='grey70'),
plot.background = element_rect(fill = "black"),
plot.caption = element_text(family = "Fira Sans Condensed", size=rel(0.7), color='grey50'),
axis.title.y = element_text(family = "Fira Sans Condensed", size=rel(0.84), color='grey50'),
axis.title.x = element_text(family = "Fira Sans Condensed", size=rel(0.84), color='grey50'),
axis.text.x = element_text(family = "Fira Sans Condensed", size=rel(0.84), color='grey50'),
axis.text.y = element_text(family = "Fira Sans Condensed", size=rel(0.84), color='grey50'),
legend.title = element_text(family = "Fira Sans Condensed", size=rel(0.84), color='grey50'),
legend.text = element_text(family = "Fira Sans Condensed", size=rel(0.8), color='grey50'),
panel.background = element_blank(),
panel.grid.major = element_line(color = "grey30", size = 0.2),
panel.grid.minor = element_line(color = "grey30", size = 0.2),
legend.background = element_blank(),
axis.ticks = element_blank(),
legend.key = element_blank(),
),
scale_color_brewer(palette="Spectral"))
update_geom_defaults("point", list(colour = "deeppink3"))
update_geom_defaults("line", list(colour = "deepskyblue3"))
update_geom_defaults("boxplot", list(colour = "deepskyblue3"))
update_geom_defaults("text_repel", list(box.padding = 0.7,
label.padding = 0,
point.padding = 0.5,
segment.color = 'grey50',
label.size = NA,
fill = "black",
alpha = 0.9))
vuelos_por_dia <- vuelos %>%
mutate(fecha = make_date(anio, mes, dia)) %>%
group_by(fecha) %>%
summarise(n=n())
head(vuelos_por_dia)
## # A tibble: 6 x 2
## fecha n
## <date> <int>
## 1 2013-01-01 842
## 2 2013-01-02 943
## 3 2013-01-03 914
## 4 2013-01-04 915
## 5 2013-01-05 720
## 6 2013-01-06 832
ggplot(vuelos_por_dia, aes(x=fecha, y=n)) +
geom_line(size=1) +
dark_theme +
ggtitle('Cantidad de vuelos de NYC por día')
vuelos_por_dia <- vuelos_por_dia %>%
mutate(dia_semana = wday(fecha, label=T))
ggplot(vuelos_por_dia, aes(x=dia_semana, y=n)) +
geom_boxplot() +
dark_theme +
ggtitle("Cantidad de vuelos cada dia de la semana.")
ggplot(vuelos_por_dia, aes(n)) +
geom_histogram(color='white', fill='deeppink4') +
facet_wrap(~ dia_semana) +
dark_theme
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
ggplot(vuelos_por_dia, aes(n)) +
geom_histogram(aes(color=dia_semana, fill=dia_semana), alpha = 0.3) +
dark_theme +
theme(legend.position = 'right')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
mod <- lm(n ~ dia_semana, data=vuelos_por_dia)
cuadricula <- vuelos_por_dia %>%
data_grid(dia_semana) %>%
add_predictions(mod, "n")
ggplot(vuelos_por_dia, aes(dia_semana, n)) +
geom_point(color='deepskyblue4') +
geom_boxplot(alpha=0.1) +
geom_point(data = cuadricula, size= 4) +
dark_theme +
ggtitle('Predicción del modelo a los dias de la semana.')
# Obs. El modelo es suceptible a valores atípicos.
vuelos_por_dia <- vuelos_por_dia %>%
add_residuals(mod)
ggplot(vuelos_por_dia, aes(x=fecha, y=resid)) +
geom_ref_line(h=0, colour='grey50', size=0.5) +
geom_point() +
geom_line(alpha=0.6) +
dark_theme +
ggtitle("Residuos del modelo lineal")
# Que está pasando? Parece que hay algunas fechas donde la cantidad de vuelos disminuye drásticamente. # Separemos por dias.
ggplot(vuelos_por_dia, aes(fecha, resid, color=dia_semana)) +
geom_ref_line(h=0, colour='grey50', size=0.5) +
geom_line(alpha=0.6) +
geom_point() +
dark_theme
dias_raros <- vuelos_por_dia %>% filter(abs(resid) > 100)
p <- ggplot(vuelos_por_dia, aes(fecha, resid, color=dia_semana)) +
geom_ref_line(h=0, colour='grey50', size=0.5) +
geom_line(alpha=0.6) +
geom_point() +
dark_theme
p + geom_point(data=dias_raros, aes(fecha, resid), size=4, show.legend=F)+
geom_label_repel(data=dias_raros, aes(label=format(fecha, format='%e %b')), show.legend=F) +
dark_theme +
ggtitle("Fechas anómalas")
## Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
# Ejercicio 1: ¿Por qué hay menos vuelos el 20 de enero, el 26 de mayo y el 1ero de septiembre? Se generaliza para otros años? # Son feriados no recurrentes, por ejemplo el 20 de enero se ignaguró el segudno mandato de Obama.
vuelos_por_dia %>%
ggplot(aes(fecha, resid)) +
geom_ref_line(h=0, colour='grey50', size=0.5) +
geom_line() +
geom_smooth(se=F, span=0.3, method = "loess") +
dark_theme +
ggtitle("Tendencia anómala")
## `geom_smooth()` using formula 'y ~ x'
vuelos_por_dia %>%
filter(dia_semana == 'Sat') %>%
ggplot(aes(fecha, resid)) +
geom_ref_line(h=0, colour='grey50', size=0.5) +
geom_line(alpha=1, size=1) +
geom_point()+
dark_theme +
scale_x_date(date_breaks = "1 month", date_labels = '%b') +
ggtitle("Cantidad de vuelos los Sábados")
## Obs. # Una posible explicación de porqué la gente tiende a viajar más los sábados en el verano, # es que se van de vacaciones. Las vacaciones de verano en el 2013 en NYC fueron del 26 de junio hasta el # 9 de setiembre.
trimestre <- function(fecha){
cut(fecha,
breaks = ymd(20130101, 20130605, 20130825, 20140101),
labels = c("primavera", "verano", "otoño")
)
}
vuelos_por_dia <- vuelos_por_dia %>%
mutate(trimestre = trimestre(fecha))
vuelos_por_dia %>%
filter(dia_semana == "Sat") %>%
ggplot(aes(fecha, resid, color = trimestre)) +
geom_point() +
geom_line()+
scale_x_date(date_breaks="1 month", date_labels = "%b") +
dark_theme +
ggtitle("Vuelos los sábados por temporada.")
# Que ocurre con los otros días de semana?
vuelos_por_dia %>%
filter(dia_semana == "Fri") %>%
ggplot(aes(fecha, resid, color = trimestre)) +
geom_point() +
geom_line()+
scale_x_date(date_breaks="1 month", date_labels = "%b") +
dark_theme +
ggtitle("Vuelos los viernes por temporada.")
# Los fines de semana:
vuelos_por_dia %>%
filter(dia_semana %in% c("Fri","Sun","Sat")) %>%
ggplot(aes(n)) +
geom_histogram(aes(color=dia_semana, fill=dia_semana), alpha = 0.3) +
dark_theme +
theme(legend.position = 'right') +
facet_wrap(~trimestre)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
# Todos los dias:
vuelos_por_dia %>%
ggplot(aes(dia_semana, n, color = trimestre)) +
geom_boxplot() +
geom_point(data=cuadricula, color = 'deeppink3', shape=95, size=12) +
dark_theme
mod1 <- lm(n ~ dia_semana, data = vuelos_por_dia)
mod2 <- lm(n ~ dia_semana*trimestre, data = vuelos_por_dia)
vuelos_por_dia %>%
gather_residuals(sin_trimestre = mod1, con_trimestre=mod2) %>%
ggplot(aes(fecha, resid, color = model)) +
geom_line(alpha=0.7, size=1) +
geom_point() +
dark_theme +
scale_color_manual(values=c("cyan3", "deeppink3"))
## Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
cuadricula <- vuelos_por_dia %>%
data_grid(dia_semana, trimestre) %>%
spread_predictions(mod1, mod2)
ggplot(vuelos_por_dia, aes(dia_semana, n, color=trimestre)) +
geom_boxplot()+
geom_point(data=cuadricula, aes(x=dia_semana, y=mod1), color="deeppink3", shape=95, size=10)+
geom_point(data=cuadricula, aes(x= dia_semana, y=mod2), color = "cyan3", shape=95, size=10)+
dark_theme +
theme(legend.position = "none") +
facet_wrap(~ trimestre)
mod3 <- MASS::rlm(n ~ dia_semana*trimestre, data = vuelos_por_dia)
vuelos_por_dia %>%
gather_residuals(sin_trimestre = mod1, con_trimestre=mod2, robusto=mod3) %>%
ggplot(aes(fecha, resid, color = model)) +
geom_line(alpha=0.7, size=1) +
geom_point() +
dark_theme +
scale_color_manual(values=c("deeppink3", "green3", "cyan3"))
## Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
library(splines)
spline_mod <- MASS::rlm(n ~ dia_semana*ns(fecha, 5), data = vuelos_por_dia)
vuelos_por_dia %>%
data_grid(dia_semana, fecha = seq_range(fecha, n = 13)) %>%
add_predictions(spline_mod) %>%
ggplot(aes(fecha, pred, colour = dia_semana)) +
geom_line() +
geom_point() +
dark_theme
# Nuevamente aparece el patrón de los sábados. # Comparemos el modelo de splines con los otros.
vuelos_por_dia %>%
gather_residuals(sin_trimestre = mod1, con_trimestre=mod2, robusto=mod3, splines = spline_mod) %>%
ggplot(aes(fecha, resid, color = model)) +
geom_line(alpha=0.7, size=1) +
geom_point() +
dark_theme +
scale_color_manual(values=c("deeppink3", "green3", "cyan3", "gold2"))
## Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
cuadricula <- vuelos_por_dia %>%
data_grid(dia_semana, fecha=seq_range(fecha, n = 1), trimestre) %>%
spread_predictions(mod1, mod2, mod3, spline_mod)
ggplot(vuelos_por_dia, aes(dia_semana, n, color=trimestre)) +
geom_boxplot()+
geom_point(data=cuadricula, aes(x=dia_semana, y=mod1), color="deeppink3", shape=95, size=10)+
geom_point(data=cuadricula, aes(x= dia_semana, y=mod2), color = "cyan3", shape=95, size=10)+
geom_point(data=cuadricula, aes(x=dia_semana, y=mod3), color="green3", shape=95, size=10)+
geom_point(data=cuadricula, aes(x=dia_semana, y=spline_mod), color="gold2", shape=95, size=10)+
dark_theme +
theme(legend.position = "none") +
facet_wrap(~ trimestre)
vuelos_por_dia %>%
slice_max(n=3, resid) %>%
mutate(descr_fecha = format(fecha, format = "%e %b"))
## # A tibble: 3 x 6
## fecha n dia_semana resid trimestre descr_fecha
## <date> <int> <ord> <dbl> <fct> <chr>
## 1 2013-11-30 857 Sat 112. otoño "30 Nov"
## 2 2013-12-01 987 Sun 95.5 otoño " 1 Dec"
## 3 2013-12-28 814 Sat 69.4 otoño "28 Dec"
trimestre <- function(fecha){
cut(fecha,
breaks = ymd(20130101, 20130605, 20130825, 20140101),
labels = c("primavera", "verano", "otoño")
)
}
dias_tri <- vuelos_por_dia %>%
mutate(trimestre = trimestre(fecha)) %>%
mutate(dias = ifelse(dia_semana == "Sat", paste0(dia_semana, "-", trimestre), as.character(dia_semana)))
head(dias_tri, 14)
## # A tibble: 14 x 6
## fecha n dia_semana resid trimestre dias
## <date> <int> <ord> <dbl> <fct> <chr>
## 1 2013-01-01 842 Tue -109. primavera Tue
## 2 2013-01-02 943 Wed -19.7 primavera Wed
## 3 2013-01-03 914 Thu -51.8 primavera Thu
## 4 2013-01-04 915 Fri -52.5 primavera Fri
## 5 2013-01-05 720 Sat -24.6 primavera Sat-primavera
## 6 2013-01-06 832 Sun -59.5 primavera Sun
## 7 2013-01-07 933 Mon -41.8 primavera Mon
## 8 2013-01-08 899 Tue -52.4 primavera Tue
## 9 2013-01-09 902 Wed -60.7 primavera Wed
## 10 2013-01-10 932 Thu -33.8 primavera Thu
## 11 2013-01-11 930 Fri -37.5 primavera Fri
## 12 2013-01-12 690 Sat -54.6 primavera Sat-primavera
## 13 2013-01-13 828 Sun -63.5 primavera Sun
## 14 2013-01-14 928 Mon -46.8 primavera Mon
mod_sab <- lm(n ~ dias, data = dias_tri)
mod1 <- lm(n ~ dia_semana, data = dias_tri)
mod2 <- lm(n ~ dia_semana*trimestre, data = dias_tri)
dias_tri %>%
gather_residuals(sin_trimestre = mod1, con_trimestre=mod2, sabados=mod_sab) %>%
ggplot(aes(fecha, resid, color = model)) +
geom_line(alpha=0.7, size=1) +
geom_point() +
dark_theme +
scale_color_manual(values=c("deeppink3", "green3", "cyan3"))
## Scale for 'colour' is already present. Adding another scale for 'colour', which will replace the existing scale.
# No hay mejora substancial.
dias_feriados <- dias_tri %>%
mutate(feriados = case_when(fecha %in% ymd(c(20130101, 20130121, 20130218, 20130527, 20130704,
20130902, 20131028, 20131111, 20131128, 20131225)) ~ "feriado", TRUE ~ "None")) %>%
unite(trimestre, dias, feriados)
mod_feriados <- lm(n ~ dia_semana*trimestre, data = dias_feriados)
mod1 <- lm(n ~ dia_semana, data = dias_feriados)
dias_feriados %>%
gather_residuals(feriados=mod_feriados, base=mod1) %>%
ggplot(aes(fecha, resid, color=model)) +
geom_line() +
geom_point() +
dark_theme
# Hay una leve mejora, casi imperceptible.
vuelos_mes <- vuelos_por_dia %>%
mutate(mes = month(fecha))
mod1 <- lm(n ~ dia_semana*trimestre, data=vuelos_mes)
mod_mes <- lm(n ~ dia_semana*mes, data= vuelos_mes)
vuelos_mes %>%
gather_residuals(base = mod1,mes = mod_mes) %>%
ggplot(aes(fecha, resid, color=model)) +
geom_line() +
geom_point() +
dark_theme
# Es peor. Considera ventanas más grandes (meses) y termina con más cantidad de valores atípicos.
domingos <- vuelos %>%
filter(hora > 19, distancia > mean(distancia))
vuelos_domingos <- domingos %>%
mutate(fecha = make_date(anio, mes, dia)) %>%
group_by(fecha) %>%
summarise(n=n())
vuelos_domingos <- vuelos_domingos %>%
mutate(dia_semana = wday(fecha, label=T))
p1 <- ggplot(vuelos_por_dia, aes(x=dia_semana, y=n)) +
geom_boxplot() +
dark_theme
p2 <- ggplot(data=vuelos_domingos, aes(x=dia_semana, y = n)) +
geom_boxplot() +
dark_theme
p1 + p2