AD Code Base

Author

Andre Thomson

Approach

For this assignment, I used the airline delay table provided in Week 5. The data compares Alaska Airlines and AM West across five destinations. My goal is to recreate the wide table, clean it, change it to long format, and compare delay percentages overall and by destination.

Load Packages

library(tidyverse)
library(knitr)

Load the Data

airline_wide <- read_csv(
  "airline_delays_wide.csv",
  show_col_types = FALSE,
  na = c("", "NA")
)

airline_wide
# A tibble: 4 × 7
  airline status  `Los Angeles` Phoenix `San Diego` `San Francisco` Seattle
  <chr>   <chr>           <dbl>   <dbl>       <dbl>           <dbl>   <dbl>
1 ALASKA  on time           497     221         212             503    1841
2 <NA>    delayed            62      12          20             102     305
3 AM WEST on time           694    4840         383             320     201
4 <NA>    delayed           117     415          65             129      61

The source table leaves the airline name blank on the delayed row. I kept those blank cells in the CSV so I could practice filling the missing values in R.

Fill the Missing Airline Names

# Fill the blank airline names from the row above
airline_clean <- airline_wide %>%
  fill(airline)

airline_clean
# A tibble: 4 × 7
  airline status  `Los Angeles` Phoenix `San Diego` `San Francisco` Seattle
  <chr>   <chr>           <dbl>   <dbl>       <dbl>           <dbl>   <dbl>
1 ALASKA  on time           497     221         212             503    1841
2 ALASKA  delayed            62      12          20             102     305
3 AM WEST on time           694    4840         383             320     201
4 AM WEST delayed           117     415          65             129      61

I used fill() so each delayed row has the correct airline name.

Change the Data from Wide to Long

# Change the destination columns into rows
airline_long <- airline_clean %>%
  pivot_longer(
    cols = -c(airline, status),
    names_to = "destination",
    values_to = "flights"
  )

airline_long
# A tibble: 20 × 4
   airline status  destination   flights
   <chr>   <chr>   <chr>           <dbl>
 1 ALASKA  on time Los Angeles       497
 2 ALASKA  on time Phoenix           221
 3 ALASKA  on time San Diego         212
 4 ALASKA  on time San Francisco     503
 5 ALASKA  on time Seattle          1841
 6 ALASKA  delayed Los Angeles        62
 7 ALASKA  delayed Phoenix            12
 8 ALASKA  delayed San Diego          20
 9 ALASKA  delayed San Francisco     102
10 ALASKA  delayed Seattle           305
11 AM WEST on time Los Angeles       694
12 AM WEST on time Phoenix          4840
13 AM WEST on time San Diego         383
14 AM WEST on time San Francisco     320
15 AM WEST on time Seattle           201
16 AM WEST delayed Los Angeles       117
17 AM WEST delayed Phoenix           415
18 AM WEST delayed San Diego          65
19 AM WEST delayed San Francisco     129
20 AM WEST delayed Seattle            61

The long version has one row for each airline, flight status, and destination combination.

Check the Data

# Check the tidy data before starting the analysis
stopifnot(nrow(airline_long) == 20)
stopifnot(sum(airline_long$flights) == 11000)
stopifnot(!any(is.na(airline_long$airline)))
stopifnot(!any(is.na(airline_long$flights)))

airline_long %>%
  count(airline, destination)
# A tibble: 10 × 3
   airline destination       n
   <chr>   <chr>         <int>
 1 ALASKA  Los Angeles       2
 2 ALASKA  Phoenix           2
 3 ALASKA  San Diego         2
 4 ALASKA  San Francisco     2
 5 ALASKA  Seattle           2
 6 AM WEST Los Angeles       2
 7 AM WEST Phoenix           2
 8 AM WEST San Diego         2
 9 AM WEST San Francisco     2
10 AM WEST Seattle           2

These checks confirm that the long data has 20 rows, 11,000 total flights, and no missing airline names or flight counts.

Overall Delay Percentage

# Calculate the overall delay percentage for each airline
overall_delay <- airline_long %>%
  group_by(airline) %>%
  summarise(
    total_flights = sum(flights),
    delayed_flights = sum(flights[status == "delayed"]),
    delay_percent = 100 * delayed_flights / total_flights,
    .groups = "drop"
  )

overall_table <- overall_delay %>%
  mutate(
    delay_percent = paste0(round(delay_percent, 2), "%")
  ) %>%
  rename(
    Airline = airline,
    `Total Flights` = total_flights,
    `Delayed Flights` = delayed_flights,
    `Delay Percentage` = delay_percent
  )

kable(
  overall_table,
  align = c("l", "r", "r", "r"),
  caption = "Overall Delay Percentage by Airline"
)
Overall Delay Percentage by Airline
Airline Total Flights Delayed Flights Delay Percentage
ALASKA 3775 501 13.27%
AM WEST 7225 787 10.89%

Overall, AM West has the lower delay percentage. AM West is about 10.89% delayed compared with about 13.27% for Alaska.

ggplot(overall_delay, aes(x = airline, y = delay_percent, fill = airline)) +
  geom_col(width = 0.65, show.legend = FALSE) +
  geom_text(
    aes(label = paste0(round(delay_percent, 1), "%")),
    vjust = -0.5,
    size = 4
  ) +
  labs(
    title = "Overall Delay Percentage",
    subtitle = "AM West has the lower overall delay percentage",
    x = NULL,
    y = "Delayed Flights (%)"
  ) +
  scale_y_continuous(
    limits = c(0, 16),
    breaks = seq(0, 16, 4),
    expand = expansion(mult = c(0, 0.05))
  ) +
  theme_minimal(base_size = 12) +
  theme(
    panel.grid.major.x = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold"),
    plot.subtitle = element_text(size = 10)
  )

Delay Percentage by Destination

# Calculate the delay percentage for each destination
city_delay <- airline_long %>%
  group_by(airline, destination) %>%
  summarise(
    total_flights = sum(flights),
    delayed_flights = sum(flights[status == "delayed"]),
    delay_percent = 100 * delayed_flights / total_flights,
    .groups = "drop"
  )

city_table <- city_delay %>%
  arrange(destination, airline) %>%
  mutate(
    delay_percent = paste0(round(delay_percent, 2), "%")
  ) %>%
  rename(
    Airline = airline,
    Destination = destination,
    `Total Flights` = total_flights,
    `Delayed Flights` = delayed_flights,
    `Delay Percentage` = delay_percent
  )

kable(
  city_table,
  align = c("l", "l", "r", "r", "r"),
  caption = "Delay Percentage by Destination"
)
Delay Percentage by Destination
Airline Destination Total Flights Delayed Flights Delay Percentage
ALASKA Los Angeles 559 62 11.09%
AM WEST Los Angeles 811 117 14.43%
ALASKA Phoenix 233 12 5.15%
AM WEST Phoenix 5255 415 7.9%
ALASKA San Diego 232 20 8.62%
AM WEST San Diego 448 65 14.51%
ALASKA San Francisco 605 102 16.86%
AM WEST San Francisco 449 129 28.73%
ALASKA Seattle 2146 305 14.21%
AM WEST Seattle 262 61 23.28%

When I compare the airlines by destination, Alaska has the lower delay percentage in all five cities.

ggplot(
  city_delay,
  aes(x = destination, y = delay_percent, fill = airline)
) +
  geom_col(
    position = position_dodge(width = 0.8),
    width = 0.7
  ) +
  geom_text(
    aes(label = paste0(round(delay_percent, 1), "%")),
    position = position_dodge(width = 0.8),
    vjust = -0.4,
    size = 3.2
  ) +
  labs(
    title = "Delay Percentage by Destination",
    subtitle = "Alaska has the lower delay percentage in every destination",
    x = NULL,
    y = "Delayed Flights (%)",
    fill = "Airline"
  ) +
  scale_y_continuous(
    limits = c(0, 32),
    breaks = seq(0, 32, 8),
    expand = expansion(mult = c(0, 0.05))
  ) +
  theme_minimal(base_size = 11) +
  theme(
    panel.grid.major.x = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold"),
    plot.subtitle = element_text(size = 9),
    legend.position = "top",
    axis.text.x = element_text(angle = 20, hjust = 1)
  )

Why the Results Look Different

The overall comparison gives AM West the better delay percentage, but the city-by-city comparison gives Alaska the better percentage in every city. This happens because the airlines do not have the same number of flights at each destination. AM West has a very large number of flights in Phoenix, where its delay percentage is relatively low. That large group has a strong effect on its overall percentage.

This is why looking only at the overall percentage can give a different picture from looking at each destination separately.

Conclusion

I recreated the airline data in a wide CSV file, filled the missing airline names, and changed the data to long format. AM West has the lower overall delay percentage, but Alaska has the lower delay percentage at every individual destination. The difference comes from how the flights are distributed across the five destinations.

AI Use

AI tools were used for general assistance and review.