library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.2.1     ✔ readr     2.2.0
✔ forcats   1.0.1     ✔ stringr   1.6.0
✔ ggplot2   4.0.3     ✔ tibble    3.3.1
✔ lubridate 1.9.5     ✔ tidyr     1.3.2
✔ purrr     1.2.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggplot2)
library(nycflights23)

data(flights)
head(flights)
# A tibble: 6 × 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  2023     1     1        1           2038       203      328              3
2  2023     1     1       18           2300        78      228            135
3  2023     1     1       31           2344        47      500            426
4  2023     1     1       33           2140       173      238           2352
5  2023     1     1       36           2048       228      223           2252
6  2023     1     1      503            500         3      808            815
# ℹ 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>
str(flights)
tibble [435,352 × 19] (S3: tbl_df/tbl/data.frame)
 $ year          : int [1:435352] 2023 2023 2023 2023 2023 2023 2023 2023 2023 2023 ...
 $ month         : int [1:435352] 1 1 1 1 1 1 1 1 1 1 ...
 $ day           : int [1:435352] 1 1 1 1 1 1 1 1 1 1 ...
 $ dep_time      : int [1:435352] 1 18 31 33 36 503 520 524 537 547 ...
 $ sched_dep_time: int [1:435352] 2038 2300 2344 2140 2048 500 510 530 520 545 ...
 $ dep_delay     : num [1:435352] 203 78 47 173 228 3 10 -6 17 2 ...
 $ arr_time      : int [1:435352] 328 228 500 238 223 808 948 645 926 845 ...
 $ sched_arr_time: int [1:435352] 3 135 426 2352 2252 815 949 710 818 852 ...
 $ arr_delay     : num [1:435352] 205 53 34 166 211 -7 -1 -25 68 -7 ...
 $ carrier       : chr [1:435352] "UA" "DL" "B6" "B6" ...
 $ flight        : int [1:435352] 628 393 371 1053 219 499 996 981 206 225 ...
 $ tailnum       : chr [1:435352] "N25201" "N830DN" "N807JB" "N265JB" ...
 $ origin        : chr [1:435352] "EWR" "JFK" "JFK" "JFK" ...
 $ dest          : chr [1:435352] "SMF" "ATL" "BQN" "CHS" ...
 $ air_time      : num [1:435352] 367 108 190 108 80 154 192 119 258 157 ...
 $ distance      : num [1:435352] 2500 760 1576 636 488 ...
 $ hour          : num [1:435352] 20 23 23 21 20 5 5 5 5 5 ...
 $ minute        : num [1:435352] 38 0 44 40 48 0 10 30 20 45 ...
 $ time_hour     : POSIXct[1:435352], format: "2023-01-01 20:00:00" "2023-01-01 23:00:00" ...
colSums(is.na(flights))
          year          month            day       dep_time sched_dep_time 
             0              0              0          10738              0 
     dep_delay       arr_time sched_arr_time      arr_delay        carrier 
         10738          11453              0          12534              0 
        flight        tailnum         origin           dest       air_time 
             0           1913              0              0          12534 
      distance           hour         minute      time_hour 
             0              0              0              0 
clean_flights<- filter(flights, !is.na(dep_delay) & !is.na(arr_delay) & !is.na(dep_delay))

colSums(is.na(clean_flights))
          year          month            day       dep_time sched_dep_time 
             0              0              0              0              0 
     dep_delay       arr_time sched_arr_time      arr_delay        carrier 
             0              0              0              0              0 
        flight        tailnum         origin           dest       air_time 
             0              0              0              0              0 
      distance           hour         minute      time_hour 
             0              0              0              0 
library(lubridate)

clean_flights$month <- month(clean_flights$time_hour, label = TRUE)

graph3<- clean_flights %>%
  group_by(month) %>%
  summarise(mean_delay = mean(dep_delay)) %>%
  ggplot(aes(x = month, y = mean_delay, fill= mean_delay)) + 
  geom_col() +
  labs(x = 'Months', y='Average flight delay',
       title = 'Average flight delay per month',
       fill = 'Average delay length',
       caption = "Source: Flight dataset") +
  theme_minimal() +
  theme(legend.position = 'bottom') +
  scale_fill_gradient(low = "pink", high = "black")
  
graph3

My goal by analyzing the “flights” data set was to create a visualization that identifies the months with the longest and shortest average delay and eventually infer what could be the reason behind that. The chart shows that flight delays change during the year. July has the highest average delay, at just over 30 minutes, followed by June at about 24 minutes. This may be because more people travel during the summer, which can make airports more crowded. Summer thunderstorms can also cause many flight delays and affect other flights. In contrast, October and November have the lowest average delays, at around 5–6 minutes. The weather is usually more stable during these months, so there may be fewer weather-related delays. Also, fewer people travel after the summer, which can reduce airport traffic and make it easier for airlines to stay on s