This assignment analyzes arrival delay data for Alaska Airlines and AM West across five cities: Los Angeles, Phoenix, San Diego, San Francisco, and Seattle. The goal is to tidy and transform the original data and compare the arrival delay percentages of the two airlines both overall and across the five cities.
First, I will read the airline delay data from a CSV file stored in my GitHub repository into R. I will clean the data by assigning names to the unlabeled columns, removing the empty row, and filling in the missing airline names. Then, I will transform the dataset from wide format to long format.
After tidying the data, I will calculate the overall delay percentage for each airline and compare the results using a table and a bar chart. I will also calculate the delay percentages for the two airlines in each of the five cities and compare them using a table and a bar chart. Finally, I will compare the overall results with the city-by-city results and explain the reasons for any differences between them.
In the original table, the airline name is shown only once for each group, so the airline names are missing in the delayed rows. These missing values will need to be filled before the data are transformed.
I will use the tidyverse package for data cleaning, transformation, and analysis. It includes the dplyr and tidyr packages that I will use to fill missing values, reshape the dataset, and calculate delay percentages.
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
The airline delay dataset is stored as a CSV file in my GitHub repository. I will read the data directly from GitHub into R and store it in the airline_data data frame. I will then display the original data to examine its structure before making any changes.
data_url <- "https://raw.githubusercontent.com/OzgeG01/DATA607-Assignment/refs/heads/main/airline_delays.csv"
airline_data <- read.csv2(
data_url,
check.names = FALSE
)
airline_data
## Los Angeles Phoenix San Diego San Francisco Seattle
## 1 ALASKA on time 497 221 212 503 1841
## 2 delayed 62 12 20 102 305
## 3 NA NA NA NA NA
## 4 AM WEST on time 694 4840 383 320 201
## 5 delayed 117 415 65 129 61
The first two columns in the original dataset do not have column names. I will assign the names Airline and Status to these columns to make the data easier to work with in R.
names(airline_data)[1:2] <- c("Airline", "Status")
airline_data
## Airline Status Los Angeles Phoenix San Diego San Francisco Seattle
## 1 ALASKA on time 497 221 212 503 1841
## 2 delayed 62 12 20 102 305
## 3 NA NA NA NA NA
## 4 AM WEST on time 694 4840 383 320 201
## 5 delayed 117 415 65 129 61
The original dataset contains a completely empty row. I removed this row while keeping all rows that contain at least one value.
airline_data <- airline_data %>%
filter(if_any(everything(), ~ !is.na(.) & . != ""))
airline_data
## Airline Status Los Angeles Phoenix San Diego San Francisco Seattle
## 1 ALASKA on time 497 221 212 503 1841
## 2 delayed 62 12 20 102 305
## 3 AM WEST on time 694 4840 383 320 201
## 4 delayed 117 415 65 129 61
In the original dataset, the airline name is only listed once for each airline, leaving the airline name blank in the delayed rows. I first converted these blank values to NA, then used fill() to fill them with the airline name from the previous row.
airline_data <- airline_data %>%
mutate(Airline = na_if(Airline, "")) %>%
fill(Airline)
airline_data
## Airline Status Los Angeles Phoenix San Diego San Francisco Seattle
## 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
The original dataset is in wide format, with each destination stored in a separate column. To make the data easier to analyze, I will transform it into long format so that the destination names are stored in one column and the number of flights is stored in another column.
airline_long <- airline_data %>%
pivot_longer(
cols = c(`Los Angeles`, Phoenix, `San Diego`, `San Francisco`, Seattle),
names_to = "City",
values_to = "Flights"
)
airline_long
## # A tibble: 20 × 4
## Airline Status City Flights
## <chr> <chr> <chr> <int>
## 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
To compare the overall performance of the two airlines, I will calculate the total number of on-time and delayed flights for each airline. I will then calculate the percentage of flights that were delayed. Using percentages provides a more meaningful comparison because the two airlines have different total numbers of flights.
overall_delay <- airline_long %>%
group_by(Airline, Status) %>%
summarise(
Flights = sum(Flights),
.groups = "drop"
) %>%
group_by(Airline) %>%
mutate(
Percentage = round(Flights / sum(Flights) * 100, 2)
) %>%
ungroup()
overall_delay
## # A tibble: 4 × 4
## Airline Status Flights Percentage
## <chr> <chr> <int> <dbl>
## 1 ALASKA delayed 501 13.3
## 2 ALASKA on time 3274 86.7
## 3 AM WEST delayed 787 10.9
## 4 AM WEST on time 6438 89.1
The following chart compares the overall percentage of delayed flights for the two airlines.
overall_delay %>%
filter(Status == "delayed") %>%
ggplot(aes(x = Airline, y = Percentage)) +
geom_col() +
geom_text(
aes(label = paste0(Percentage, "%")),
vjust = -0.5
) +
labs(
title = "Overall Delay Percentage by Airline",
x = "Airline",
y = "Delayed Flights (%)"
) +
theme_minimal()
Overall, Alaska Airlines had a higher percentage of delayed flights than AM West. Approximately 13.27% of Alaska Airlines flights were delayed, compared with approximately 10.89% of AM West flights. Based on the overall percentages, AM West had a lower overall delay rate.
I grouped the data by airline and city and calculated the total number of flights for each group. Then, I calculated the percentage of delayed flights and kept only the delayed flight results for the comparison.
city_delay <- airline_long %>%
group_by(Airline, City) %>%
mutate(
Total_Flights = sum(Flights),
Percentage = round(Flights / Total_Flights * 100, 2)
) %>%
filter(Status == "delayed") %>%
select(Airline, City, Flights, Total_Flights, Percentage) %>%
ungroup()
city_delay
## # A tibble: 10 × 5
## Airline City Flights Total_Flights Percentage
## <chr> <chr> <int> <int> <dbl>
## 1 ALASKA Los Angeles 62 559 11.1
## 2 ALASKA Phoenix 12 233 5.15
## 3 ALASKA San Diego 20 232 8.62
## 4 ALASKA San Francisco 102 605 16.9
## 5 ALASKA Seattle 305 2146 14.2
## 6 AM WEST Los Angeles 117 811 14.4
## 7 AM WEST Phoenix 415 5255 7.9
## 8 AM WEST San Diego 65 448 14.5
## 9 AM WEST San Francisco 129 449 28.7
## 10 AM WEST Seattle 61 262 23.3
The bar chart compares the delay percentages of Alaska Airlines and AM West across the five cities.
ggplot(city_delay, aes(x = City, y = Percentage, fill = Airline)) +
geom_col(position = "dodge") +
geom_text(
aes(label = paste0(Percentage, "%")),
position = position_dodge(width = 0.9),
vjust = -0.5
) +
labs(
title = "Delay Percentage by Airline and City",
x = "City",
y = "Delayed Flights (%)",
fill = "Airline"
) +
theme_minimal()
Across all five cities, Alaska Airlines had a lower delay percentage than AM West. The largest difference was in San Francisco, where Alaska Airlines had a delay rate of 16.86% compared with 28.73% for AM West. Alaska Airlines also had lower delay percentages in Los Angeles, Phoenix, San Diego, and Seattle.
The city-by-city comparison shows a different pattern from the overall comparison. Alaska Airlines had a lower delay percentage than AM West in each of the five cities. However, when all five cities were combined, Alaska Airlines had an overall delay rate of 13.27%, while AM West had a lower overall delay rate of 10.89%.
This discrepancy occurs because the two airlines have different distributions of flights across the five cities. AM West had a very large number of flights in Phoenix, where both airlines had relatively low delay rates. In contrast, a large portion of Alaska Airlines flights were in Seattle, where the delay rates were higher. As a result, the overall percentages are influenced by the number of flights each airline had in each city. This causes the overall comparison to show a different pattern from the city-by-city comparison.
This analysis compared the arrival delay percentages of Alaska Airlines and AM West both overall and across five cities. Overall, Alaska Airlines had a delay rate of 13.27%, compared with 10.89% for AM West. However, the city-by-city comparison showed that Alaska Airlines had a lower delay percentage than AM West in all five cities.
The difference between the overall and city-by-city results is caused by the different distribution of flights across the cities. AM West had a large number of flights in Phoenix, where delay rates were relatively low, while many of Alaska Airlines’ flights were in Seattle, where delay rates were higher. This analysis shows why percentages should be examined both overall and within individual groups when comparing performance.
I used ChatGPT (GPT-5.6 Luna), developed by OpenAI, to help me understand some of the functions I used in this assignment and to check my work.
OpenAI. (2026). ChatGPT (GPT-5.6 Luna) [Large language model]. [https://chatgpt.com/ Accessed September 30, 2026].
Link: