Soy Jeiner Velandia, licenciado en Psicología y Pedagogía, con formación en maestría en TI aplicadas a la educación. Actualmente curso un doctorado en Gestión de la Innovación Tecnológica y una especialización en Métodos Estadísticos para el Análisis de Datos.
En este documento presento los 6 pasos de la actividad: instalación de paquetes, selección y limpieza de datos, creación de data frames, cálculo de medidas de localización, dispersión y forma, y finalmente la generación de gráficos para el análisis.
Preámbulo. Ajusto el sistema con
options(digits = 4) para que todos los números en consola
se muestren con máximo cuatro decimales. Esto facilita la lectura de
resultados y evita valores demasiado largos que pueden ser confusos.
Paso 1. Instalo y cargo librerías esenciales:
nycflights13 trae la base de datos de vuelos,
dplyr sirve para manipular tablas, ggplot2
para graficar, e1071 y DescTools para calcular
asimetría y curtosis, y readr para importar o exportar CSV.
Se usan install.packages() y luego library()
para tenerlas listas.
#Ajusto el sistema para que todos los datos se vean máximo 4 décimales
options(digits = 4)
#========================================== PASO 1 ===========================
# Instalo los paquetes
install.packages("nycflights13") # Base de datos de vuelos de NY en 2013
install.packages("dplyr") # Pauete de manipulacion de datos
install.packages("ggplot2") # Liberia para usar gráficos
install.packages("e1071") # skewness y kurtosis (Fisher-Pearson)
install.packages("DescTools") # Skew(), Kurt(), BowleySkew()
install.packages("readr") #importar/exportar CSV
## Cargo todas las librerias instaladas``
library(nycflights13)
library(dplyr)
library(ggplot2)
library(e1071)
library(DescTools)
library(readr)
Paso 2. Cargo la base flights con
data(). Primero exploro su estructura con
str() y glimpse() para conocer columnas y
tipos de datos. Después selecciono solo cuatro variables relevantes
(distance, air_time, dep_delay,
arr_delay) con dplyr::select(). Reviso las
primeras y últimas filas con head(), tail(),
abro el conjunto con View(), obtengo estadísticas básicas
con summary() y cuento valores faltantes con
colSums(is.na()).
#========================================== PASO 2 ===========================
# Cargar datos y seleccionar variables
data("flights") # TRAIGO LA DATA DE FLIGT
str(flights) # QUIERO VER LAS COLUMNAS Y EL TIPO DE DATOS QUE HAY
## tibble [336,776 × 19] (S3: tbl_df/tbl/data.frame)
## $ year : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
## $ month : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
## $ day : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
## $ dep_time : int [1:336776] 517 533 542 544 554 554 555 557 557 558 ...
## $ sched_dep_time: int [1:336776] 515 529 540 545 600 558 600 600 600 600 ...
## $ dep_delay : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
## $ arr_time : int [1:336776] 830 850 923 1004 812 740 913 709 838 753 ...
## $ sched_arr_time: int [1:336776] 819 830 850 1022 837 728 854 723 846 745 ...
## $ arr_delay : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
## $ carrier : chr [1:336776] "UA" "UA" "AA" "B6" ...
## $ flight : int [1:336776] 1545 1714 1141 725 461 1696 507 5708 79 301 ...
## $ tailnum : chr [1:336776] "N14228" "N24211" "N619AA" "N804JB" ...
## $ origin : chr [1:336776] "EWR" "LGA" "JFK" "JFK" ...
## $ dest : chr [1:336776] "IAH" "IAH" "MIA" "BQN" ...
## $ air_time : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
## $ distance : num [1:336776] 1400 1416 1089 1576 762 ...
## $ hour : num [1:336776] 5 5 5 5 6 5 6 6 6 6 ...
## $ minute : num [1:336776] 15 29 40 45 0 58 0 0 0 0 ...
## $ time_hour : POSIXct[1:336776], format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...
dplyr::glimpse(flights) #USO UNA LIBERIA DPLYR para con glimpse= vista rápida y compacta de un dataframe
## Rows: 336,776
## Columns: 19
## $ year <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2…
## $ month <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ day <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ dep_time <int> 517, 533, 542, 544, 554, 554, 555, 557, 557, 558, 558, …
## $ sched_dep_time <int> 515, 529, 540, 545, 600, 558, 600, 600, 600, 600, 600, …
## $ dep_delay <dbl> 2, 4, 2, -1, -6, -4, -5, -3, -3, -2, -2, -2, -2, -2, -1…
## $ arr_time <int> 830, 850, 923, 1004, 812, 740, 913, 709, 838, 753, 849,…
## $ sched_arr_time <int> 819, 830, 850, 1022, 837, 728, 854, 723, 846, 745, 851,…
## $ arr_delay <dbl> 11, 20, 33, -18, -25, 12, 19, -14, -8, 8, -2, -3, 7, -1…
## $ carrier <chr> "UA", "UA", "AA", "B6", "DL", "UA", "B6", "EV", "B6", "…
## $ flight <int> 1545, 1714, 1141, 725, 461, 1696, 507, 5708, 79, 301, 4…
## $ tailnum <chr> "N14228", "N24211", "N619AA", "N804JB", "N668DN", "N394…
## $ origin <chr> "EWR", "LGA", "JFK", "JFK", "LGA", "EWR", "EWR", "LGA",…
## $ dest <chr> "IAH", "IAH", "MIA", "BQN", "ATL", "ORD", "FLL", "IAD",…
## $ air_time <dbl> 227, 227, 160, 183, 116, 150, 158, 53, 140, 138, 149, 1…
## $ distance <dbl> 1400, 1416, 1089, 1576, 762, 719, 1065, 229, 944, 733, …
## $ hour <dbl> 5, 5, 5, 5, 6, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6…
## $ minute <dbl> 15, 29, 40, 45, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 59, 0…
## $ time_hour <dttm> 2013-01-01 05:00:00, 2013-01-01 05:00:00, 2013-01-01 0…
df <- dplyr::select(flights, distance, air_time, dep_delay, arr_delay) # para la actividad trabajaremos 4 variables
#View(flights)
##### Visualizo el DF en crudo
head(df,20) # Muestra las primeras 20 Filas
## # A tibble: 20 × 4
## distance air_time dep_delay arr_delay
## <dbl> <dbl> <dbl> <dbl>
## 1 1400 227 2 11
## 2 1416 227 4 20
## 3 1089 160 2 33
## 4 1576 183 -1 -18
## 5 762 116 -6 -25
## 6 719 150 -4 12
## 7 1065 158 -5 19
## 8 229 53 -3 -14
## 9 944 140 -3 -8
## 10 733 138 -2 8
## 11 1028 149 -2 -2
## 12 1005 158 -2 -3
## 13 2475 345 -2 7
## 14 2565 361 -2 -14
## 15 1389 257 -1 31
## 16 187 44 0 -4
## 17 2227 337 -1 -8
## 18 1076 152 0 -7
## 19 762 134 0 12
## 20 1023 147 1 -6
tail(df,20) # Muesta las ultimas 20 filas
## # A tibble: 20 × 4
## distance air_time dep_delay arr_delay
## <dbl> <dbl> <dbl> <dbl>
## 1 209 39 -9 -16
## 2 301 50 194 194
## 3 378 61 -2 8
## 4 764 97 27 7
## 5 872 120 72 57
## 6 273 48 -14 -21
## 7 2565 318 80 42
## 8 944 123 154 130
## 9 266 43 -8 -8
## 10 209 41 -5 -17
## 11 301 52 -10 -20
## 12 264 47 -5 -16
## 13 187 33 12 1
## 14 1617 196 -10 -25
## 15 764 NA NA NA
## 16 213 NA NA NA
## 17 198 NA NA NA
## 18 764 NA NA NA
## 19 419 NA NA NA
## 20 431 NA NA NA
#View(df) # Abre en otra pestaña el DF
summary(df) # Aplica los estadisticos básicos // (mínimo, cuartiles, media, máximo y los NA).
## distance air_time dep_delay arr_delay
## Min. : 17 Min. : 20 Min. : -43.0 Min. : -86.00
## 1st Qu.: 502 1st Qu.: 82 1st Qu.: -5.0 1st Qu.: -17.00
## Median : 872 Median :129 Median : -2.0 Median : -5.00
## Mean :1040 Mean :151 Mean : 12.6 Mean : 6.89
## 3rd Qu.:1389 3rd Qu.:192 3rd Qu.: 11.0 3rd Qu.: 14.00
## Max. :4983 Max. :695 Max. :1301.0 Max. :1272.00
## NA's :9430 NA's :8255 NA's :9430
colSums(is.na(df)) # cuenta exactamente cuántos NA hay por variable.
## distance air_time dep_delay arr_delay
## 0 9430 8255 9430
Paso 3. Elimino filas con datos faltantes usando
dplyr::filter() junto con !is.na() para cada
variable. Esto asegura que los cálculos no se vean afectados por huecos
en la información. Luego verifico que no haya NA con
colSums(is.na()) y reviso el nuevo dataframe limpio con
knitr::kable().
#========================================== PASO 3 ===========================
# Limpiamos la base de los NA
df <- dplyr::filter(df,
!is.na(distance),
!is.na(air_time),
!is.na(dep_delay),
!is.na(arr_delay))
# Vuelvo a psar el Colsum debe ser 0
knitr::kable(head(df,10)) # En mark Down no funciona el VIEW()
| distance | air_time | dep_delay | arr_delay |
|---|---|---|---|
| 1400 | 227 | 2 | 11 |
| 1416 | 227 | 4 | 20 |
| 1089 | 160 | 2 | 33 |
| 1576 | 183 | -1 | -18 |
| 762 | 116 | -6 | -25 |
| 719 | 150 | -4 | 12 |
| 1065 | 158 | -5 | 19 |
| 229 | 53 | -3 | -14 |
| 944 | 140 | -3 | -8 |
| 733 | 138 | -2 | 8 |
knitr::kable(tail(df,10)) #Uso este comando con Head y tail para ver 10 y 10
| distance | air_time | dep_delay | arr_delay |
|---|---|---|---|
| 872 | 120 | 72 | 57 |
| 273 | 48 | -14 | -21 |
| 2565 | 318 | 80 | 42 |
| 944 | 123 | 154 | 130 |
| 266 | 43 | -8 | -8 |
| 209 | 41 | -5 | -17 |
| 301 | 52 | -10 | -20 |
| 264 | 47 | -5 | -16 |
| 187 | 33 | 12 | 1 |
| 1617 | 196 | -10 | -25 |
colSums(is.na(df)) # Compruebo que en DF no hay NA con un conteo por variable
## distance air_time dep_delay arr_delay
## 0 0 0 0
Paso 4. Creo la función limites_iqr()
que define un rango aceptable de datos usando cuartiles
(quantile()) e intervalo intercuartílico
(IQR()). Aplico la función a distance y
air_time, obtengo límites inferior y superior y filtro
valores atípicos con dplyr::filter(). El resultado se
guarda en df_clean. Finalmente muestro cuántas filas quedan
con nrow() y reviso el nuevo dataset con
knitr::kable().
#========================================== PASO 4 ===========================
# Voy a establecer los limittes para que no hayan datos "extraños"
# Creo una función limites_iqr
limites_iqr <- function(x) {
q1 <- quantile(x, 0.25, na.rm = TRUE)
q3 <- quantile(x, 0.75, na.rm = TRUE)
iqr <- IQR(x, na.rm = TRUE)
setNames(c(q1 - 1.5 * iqr, q3 + 1.5 * iqr), c("inf", "sup"))
}
##### Aplico la funcion Limites iqr a la variable distancia y tiempo de vuelo
### Guardo en un objeto los limites para los dos
lims_dist <- limites_iqr(df$distance)
lims_air <- limites_iqr(df$air_time)
print(lims_dist)
## inf sup
## -811 2709
print(lims_air)
## inf sup
## -83 357
#### Vamos a filtrar sacando los datos que no están los limites inf y sup
df_clean <- dplyr::filter( # Cree un NUEVO DF llamado DF_CLEAN!!!!!!!
df,
distance >= lims_dist["inf"], distance <= lims_dist["sup"], # Cuando la distancia se mayor o igual al inferior y menor o igual al superior
air_time >= lims_air["inf"], air_time <= lims_air["sup"]
)
knitr::kable(head(df_clean,5)) # En mark Down no funciona el VIEW()
| distance | air_time | dep_delay | arr_delay |
|---|---|---|---|
| 1400 | 227 | 2 | 11 |
| 1416 | 227 | 4 | 20 |
| 1089 | 160 | 2 | 33 |
| 1576 | 183 | -1 | -18 |
| 762 | 116 | -6 | -25 |
knitr::kable(tail(df_clean,5)) #Uso este comando con Head y tail para ver 5 y 5
| distance | air_time | dep_delay | arr_delay |
|---|---|---|---|
| 209 | 41 | -5 | -17 |
| 301 | 52 | -10 | -20 |
| 264 | 47 | -5 | -16 |
| 187 | 33 | 12 | 1 |
| 1617 | 196 | -10 | -25 |
cat("Filas finales:", nrow(df_clean), "\n")# Muestro las filas finales de DF clean
## Filas finales: 321898
Paso 5. Construyo la función analizar()
que genera una tabla con estadísticas de cada variable. Incluye medidas
de localización (mean(), median(), moda con
table()), dispersión (var(),
sd(), rango, IQR(), coeficiente de variación)
y forma (skewness(), kurtosis()). Agrupo
resultados para todas las variables con rbind() en un
objeto llamado estadisticas y lo visualizo con
knitr::kable().
#===================. PASO 5 ========================
#Creare una función dentro de la función creo un DF nuevo donde están los todos los estadisticos Localización, Dispersión , Forma
analizar <- function(x, nom) {
data.frame(
Variable = nom,
# Centralidad
Media = mean(x, na.rm = TRUE),
Mediana = median(x, na.rm = TRUE),
Moda = as.numeric(names(which.max(table(x)))),
Q1 = quantile(x, 0.25, na.rm = TRUE),
Q2 = quantile(x, 0.50, na.rm = TRUE),
Q3 = quantile(x, 0.75, na.rm = TRUE),
#DISPERSIÓN
Varianza = var(x, na.rm = TRUE),
Desv_Est = sd(x, na.rm = TRUE),
Rango = max(x, na.rm = TRUE) - min(x, na.rm = TRUE),
RIQ = IQR(x, na.rm = TRUE),
CV = sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE) * 100,
#FORMA
Asimetria = e1071::skewness(x, type=2, na.rm = TRUE),
Curtosis = e1071::kurtosis(x, type=2, na.rm = TRUE),
row.names = NULL
)
}
###### VOY A CREAR un objeto llamdo esttadisticas que va a construir el datta frame final
estadisticas <- rbind( # RBIND me crea las filas por variable y las guara para graficar
analizar(df_clean$distance, "DISTANCE"),
analizar(df_clean$air_time, "AIR_TIME"),
analizar(df_clean$dep_delay, "DEP_DELAY"),
analizar(df_clean$arr_delay, "ARR_DELAY")
)
#View(estadisticas) # Acá ya veo la tabla con los datos guardados de la función
knitr::kable(estadisticas)
| Variable | Media | Mediana | Moda | Q1 | Q2 | Q3 | Varianza | Desv_Est | Rango | RIQ | CV | Asimetria | Curtosis |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| DISTANCE | 1017.794 | 872 | 2475 | 502 | 872 | 1389 | 483267 | 695.17 | 2506 | 887 | 68.30 | 0.9361 | -0.0790 |
| AIR_TIME | 146.464 | 128 | 42 | 81 | 128 | 186 | 7735 | 87.95 | 337 | 105 | 60.05 | 0.9087 | -0.0879 |
| DEP_DELAY | 12.596 | -2 | -5 | -5 | -2 | 11 | 1609 | 40.11 | 1180 | 16 | 318.42 | 4.7381 | 41.4081 |
| ARR_DELAY | 6.688 | -5 | -13 | -17 | -5 | 13 | 1988 | 44.59 | 1213 | 30 | 666.76 | 3.6786 | 27.6714 |
Paso 6. Para distance y air_time utilizo geom_histogram() con intervalos definidos por binwidth. Resalto la media de cada distribución con geom_vline(linetype=“dashed”, color=“red”). Ajusto escalas con scale_x_continuous() y scale_y_continuous(), y aplico theme_minimal() para un diseño limpio.
En el caso de los retrasos de salida (dep_delay) y llegada (arr_delay), empleo geom_histogram() combinado con case_when() para clasificar los vuelos en categorías: Adelantado, A Tiempo, Retraso Leve y Retraso Fuerte. Personalizo colores con scale_fill_manual() y limito el foco de los datos con coord_cartesian(xlim=…) para concentrarme en los valores más frecuentes. También agrego convenciones con leyendas claras.
Para un análisis más avanzado de los retrasos en salida, combino geom_histogram(aes(y=..density..)) con geom_density() para representar la forma de la distribución y resaltar la media con geom_vline(). Calculo asimetría y curtosis usando skewness() y kurtosis() de la librería moments, defino la forma de la curva con condicionales ifelse(), y muestro el resultado dentro del gráfico con annotate(“text”, …).
Finalmente, para explorar la relación entre retraso en despegue y retraso en aterrizaje, utilizo geom_hex() con scale_fill_viridis_c(), generando un gráfico tipo panal de abeja que permite visualizar zonas de alta concentración sin sobrecargar la visualización.
#===================. PASO 6 ========================
# Grafico: distancia y air time (Histograma y box plot)
# Graficos : Retraso (Histograma)
#gradicos: Simetria y Curtosis (Graficos avanzados)
#######======= 1. Histograma Distance================
ggplot(df_clean, aes(x = distance)) + ### SELECCIONO la variable
geom_histogram(binwidth = 50 , fill = "steelblue", color = "black") + # SELECCIONO el tipo de grafico
geom_vline(aes(xintercept = mean(distance, na.rm = TRUE)), # CREO la LINEA Vertical con la media.
color = "red", linetype = "dashed", linewidth = 1) +
labs(title = "Distribución de distancias de vuelos (Distance)",
x = "Distancia (millas)",
y = "Número de vuelos") +
####### Eje y
scale_y_continuous(breaks = seq(0, 50000, by = 5000)) +
######## EJE X
scale_x_continuous(breaks = seq(0, 5000, by = 500))+
theme_minimal()
#####======= 2. Histograma Air time ====================
ggplot(df_clean, aes(x = air_time)) + # Le digo que vamos a graficar air_time
geom_histogram(binwidth = 10, fill = "steelblue", color = "black") + # agrupo lo vuelos en tiempoos de 10 min / relleno y color de línea
geom_vline(aes(xintercept = mean(air_time, na.rm = TRUE)), # geom_vline(...): linea roja es la media del tiempo de vuelo.
color = "red" , linetype = "dashed", linewidth = 1) +
labs(title = "Distribución del tiempo de vuelo (air_time)", # Etiquetas
x = "Tiempo de vuelo (minutos)",
y = "Número de vuelos") +
####### Eje y
scale_y_continuous(breaks = seq(0, 50000, by = 5000)) +
######## EJE X
scale_x_continuous(breaks = seq(0, 500, by = 50))+
theme_minimal() # Fondo blanco lineas
#####===== Retrasos / despegar
#para este histograma se deben realizar un grafico mas elaborado
#1. se debe usar un Case_When_ es un condicional de datos que permite etiquetar
#2. se hace un zoom sobre el X -
#3. Creamos convenciones que salen al lado derecho
############## HISTOGRAMAS CONDICIONAL COLOR Y CATEGORIA=======
ggplot(df_clean, aes(x = dep_delay)) +
# Histograma con las categorías de color para poder visualizar el histograma
geom_histogram(
aes(fill = case_when(
dep_delay < 0 ~ "Adelantado",
dep_delay == 0 ~ "A Tiempo",
dep_delay <=120 ~ "Retraso Leve",
TRUE ~ "Retraso Fuerte" # TRUE captura todos los casos restantes
)),
binwidth = 5,
color = "white",
na.rm = TRUE # Omite los valores NA para evitar errores
) +
######## Importante ZOOM
coord_cartesian(xlim = c(-43, 100)) +
######## Convensiones
scale_fill_manual(
name = "Tipo de Puntualidad",
values = c(
"Adelantado" = "seagreen",
"A Tiempo" = "steelblue",
"Retraso Leve" = "orange",
"Retraso Fuerte" = "firebrick"
)
) +
########
labs(
title = "Retrasos vuelos Vuelos ",
subtitle = " Rango: -43 a 100 minutos",
x = "Retraso en la Salida (Minutos)",
y = "Cantidad de Vuelos"
) +
theme_minimal()
##############====================================== RETRASOS ATERRIZAR
#para este histograma se deben realizar un grafico mas elaborado
#1. se debe usar un Case_When_ es un condicional de datos que permite etiquetar
#2. se hace un zoom sobre el X -
#3. Creamos convenciones que salen al lado derecho
#4. Creamos un Scale en X / Y para ver numeros mas pequeños en los labels
ggplot(df_clean, aes(x = arr_delay)) +
# Histograma con las categorías de color para poder visualizar el histograma
geom_histogram(
aes(fill = case_when(
arr_delay < 0 ~ "Adelantado",
arr_delay == 0 ~ "A Tiempo",
arr_delay <= 60 ~ "Retraso Leve",
TRUE ~ "Retraso Fuerte" # TRUE captura todos los casos restantes
)),
binwidth = 10,
color = "white",
na.rm = TRUE # Omite los valores NA para evitar errores
) +
######## Importante ZOOM delimito el foco de los datos
coord_cartesian(xlim = c(-90, 200)) +
####### Eje y
scale_y_continuous(breaks = seq(0, 70000, by = 10000)) +
######## EJE X
scale_x_continuous(breaks = seq(-100, 200, by = 50))+
######## Convensiones
scale_fill_manual(
name = "Tipo de Puntualidad",
values = c(
"Adelantado" = "seagreen",
"A Tiempo" = "steelblue",
"Retraso Leve" = "orange",
"Retraso Fuerte" = "firebrick"
)
) +
########
labs(
title = "Retrasos llegadas vuelos ",
subtitle = " Rango: -90 a 200 minutos",
x = "Retraso en la llegada (Minutos)",
y = "Cantidad de Vuelos"
) +
theme_minimal()
#####================================
#####================================ AVANZADOS PRO ==============
###### Densidad, Asimetría y curtois
##########=============================RETRASOS SALIDAS=====================================
# Calcular curtosis y asimetría
kurt_val <- kurtosis(df_clean$dep_delay, na.rm = TRUE) # Creo un objeto donde guardo la operacion Kurtosis
skew_val <- skewness(df_clean$dep_delay, na.rm = TRUE) # Creo un objeto donde guardo la asimetría
# Definir el tipo de distribución según la curtosis creo ubn condicional con IF
tipo_curtosis <- ifelse(kurt_val > 3, "Leptocúrtica (colas pesadas)",
ifelse(kurt_val < 3, "Platicúrtica (aplanada)",
"Mesocúrtica (normal)"))
# Definir el tipo de asimetría , condicional
tipo_asimetria <- ifelse(skew_val > 0, "Positiva (cola a la derecha)",
ifelse(skew_val < 0, "Negativa (cola a la izquierda)",
"Simétrica"))
# Texto que se va a mostrar en la anotación
texto <- paste0("Asimetría: ", tipo_asimetria,
"\nCurtosis: ", tipo_curtosis,
"\n(skew = ", round(skew_val,2), #llamo el objeto guardado y el digo que muestre 2 decimales
", kurt = ", round(kurt_val,2), ")")
# --- Gráfico ---
ggplot(df_clean, aes(x = dep_delay)) +
geom_histogram(aes(y = ..density..), bins = 100, fill = "orange", color = "black") + #histograma
geom_density(color = "magenta", linewidth = 1) + #liena de densidad
geom_vline(aes(xintercept = mean(dep_delay, na.rm = TRUE)), # Linea de la Media
color = "red", linetype = "dashed", linewidth = 1) +
######## Importante ZOOM delimito el foco de los datos
coord_cartesian(xlim = c(-50, 100)) + # Zoom en el eje X lo ajusto de acuerdo a los valores de los datos
######## EJE X
scale_x_continuous(breaks = seq(-50, 200, by = 10))+ # como se ve el eje X en el grafico
labs(title = "Distribución de retraso en despegue (dep_delay)",
x = "Retraso en despegue (min)", y = "Densidad") +
annotate("text", x = 60, y = 0.06, # El texto en el gráifco
label = texto, color = "black", size = 3, fontface = "bold") +
theme_minimal()
#########==========
###### Panal Exaginal
library(ggplot2)
ggplot(df_clean, aes(x = dep_delay, y = arr_delay)) +
geom_hex(bins = 100) +
scale_fill_viridis_c() +
labs(title = "Relación entre retraso en despegue y aterrizaje",
x = "Retraso en despegue (min)",
y = "Retraso en aterrizaje (min)",
fill = "Cantidad") +
theme_minimal()