A. Introduction
The COVID-19 pandemic impacted many areas of life for people around the world. In 2023, WHO declared the pandemic to be over but people, industries, and economies globally still feel COVID-19’s lasting impact (Centers for Disease Control and Prevention, 2023). One industry severely affected by COVID-19 is the airline industry. As countries rushed to contain the virus, borders closed, travel plans were cancelled and flights were grounded, halting an entire sector overnight.
Has airline travel recovered to pre-pandemic levels? To investigate, I am using enplanement data retrieved from National Capital Region Transportation Planning Board to analyze the three DMV international airports: Dulles International Airport (IAD), Washington National Airport (DCA), and Baltimore/Washington International Thurgood Marshall Airport (BWI).
Source: Washington Metropolitan Council of Governments, Enplanement data 2000-2023. (https://rtdc-mwcog.opendata.arcgis.com/documents/b58ae0e96b034867afd809a9896b9442/about)
#import the libraries and data sets
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(dslabs)
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats 1.0.1 ✔ readr 2.2.0
## ✔ ggplot2 4.0.3 ✔ stringr 1.6.0
## ✔ lubridate 1.9.5 ✔ tibble 3.3.1
## ✔ purrr 1.2.2 ✔ tidyr 1.3.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(readxl)
## Warning: package 'readxl' was built under R version 4.6.1
setwd("/Users/cassidystauffer/Documents/MCCC/Data 101/Week 6") #Set the working directory to the correct folder
enplanement_19 <- read_excel("Enplanement_Data.xlsx", #Read the excel file
sheet = "2019" #Choose the sheet from 2019
)
enplanement_19
## # A tibble: 36 × 11
## Year Month Airport Enplaned Deplaned Enplaned_Deplaned Dom_Enplaned
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 2019 January BWI 894637 898974 1793611 845630
## 2 2019 January DCA 789540 830426 1619966 777640
## 3 2019 January IAD 774129 827238 1601367 529654
## 4 2019 February BWI 835130 824399 1659529 789757
## 5 2019 February DCA 820575 814965 1635540 809281
## 6 2019 February IAD 728391 724784 1453175 497127
## 7 2019 March BWI 1104285 1117183 2221468 1046214
## 8 2019 March DCA 1041578 1055493 2097071 1025050
## 9 2019 March IAD 971146 991241 1962387 661039
## 10 2019 April BWI 1137744 1114088 2251832 1090516
## # ℹ 26 more rows
## # ℹ 4 more variables: Intl_Enplaned <dbl>, Dom_Intl_Enplaned <dbl>,
## # Year_txt <chr>, YM <chr>
#excel_sheets("Enplanement_Data.xlsx")
B. Data Analysis
For my exploratory data analysis, I used the head function to get an understanding of the data in the file. I then went back and I chose to filter the data by airport and by year and to do that I needed to first import the individual sheets I would need. Next I used the “anyNA” function to check for empty values. Fortunately, my data had none. I then removed the columns I would not need. I repeated these steps for all three airports for from 2019-2021. I then used the mean function to find the average enplaned value from each airport, each year to see if there was a anything that stood out. Before plotting, I used the rbind function to combine the nine data frames I had cleaned.
head(enplanement_19)
## # A tibble: 6 × 11
## Year Month Airport Enplaned Deplaned Enplaned_Deplaned Dom_Enplaned
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
## 1 2019 January BWI 894637 898974 1793611 845630
## 2 2019 January DCA 789540 830426 1619966 777640
## 3 2019 January IAD 774129 827238 1601367 529654
## 4 2019 February BWI 835130 824399 1659529 789757
## 5 2019 February DCA 820575 814965 1635540 809281
## 6 2019 February IAD 728391 724784 1453175 497127
## # ℹ 4 more variables: Intl_Enplaned <dbl>, Dom_Intl_Enplaned <dbl>,
## # Year_txt <chr>, YM <chr>
str(enplanement_19)
## tibble [36 × 11] (S3: tbl_df/tbl/data.frame)
## $ Year : num [1:36] 2019 2019 2019 2019 2019 ...
## $ Month : chr [1:36] "January" "January" "January" "February" ...
## $ Airport : chr [1:36] "BWI" "DCA" "IAD" "BWI" ...
## $ Enplaned : num [1:36] 894637 789540 774129 835130 820575 ...
## $ Deplaned : num [1:36] 898974 830426 827238 824399 814965 ...
## $ Enplaned_Deplaned: num [1:36] 1793611 1619966 1601367 1659529 1635540 ...
## $ Dom_Enplaned : num [1:36] 845630 777640 529654 789757 809281 ...
## $ Intl_Enplaned : num [1:36] 49008 11900 244475 45373 11294 ...
## $ Dom_Intl_Enplaned: num [1:36] 894637 789540 774129 835130 820575 ...
## $ Year_txt : chr [1:36] "2019" "2019" "2019" "2019" ...
## $ YM : chr [1:36] "2019-01" "2019-01" "2019-01" "2019-02" ...
#Clean the data
anyNA(enplanement_19) #Check for NAs
## [1] FALSE
#Get rid of the columns I won't need
enplanement_19[c("Enplaned_Deplaned", "Dom_Intl_Enplaned", "YM", "NM")] <- list(NULL)
#Filter by airport
iad_19 <- enplanement_19 %>% filter(Airport == "IAD")
iad_19
## # A tibble: 12 × 8
## Year Month Airport Enplaned Deplaned Dom_Enplaned Intl_Enplaned Year_txt
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 2019 January IAD 774129 827238 529654 244475 2019
## 2 2019 February IAD 728391 724784 497127 231264 2019
## 3 2019 March IAD 971146 991241 661039 310107 2019
## 4 2019 April IAD 1002803 1027129 673277 329526 2019
## 5 2019 May IAD 1132554 1103661 731276 401278 2019
## 6 2019 June IAD 1220533 1169625 769138 451395 2019
## 7 2019 July IAD 1218537 1242379 790993 427544 2019
## 8 2019 August IAD 1165068 1205995 746671 418397 2019
## 9 2019 September IAD 998394 1021301 648148 350246 2019
## 10 2019 October IAD 1077888 1079480 733527 344361 2019
## 11 2019 November IAD 979843 963309 670758 309221 2019
## 12 2019 December IAD 1059640 1005350 700370 359270 2019
iad_19_avg <-mean(iad_19$Enplaned) #Average enplanements a month in 2019 at IAD
iad_19_avg
## [1] 1027410
bwi_19 <- enplanement_19 %>% filter(Airport == "BWI") #Filter for BWI
bwi_19_avg <-mean(bwi_19$Enplaned) #Average enplanements a month in 2019 at BWI
bwi_19_avg
## [1] 1128479
dca_19 <- enplanement_19 %>% filter(Airport == "DCA")
dca_19_avg <-mean(dca_19$Enplaned) #Average enplanements a month in 2019 at DCA
#2020 data
enplanement_20 <- read_excel("Enplanement_Data.xlsx", #Read the excel file
sheet = "2020" #Choose the sheet from 2020
)
anyNA(enplanement_20) #Check for NAs
## [1] FALSE
#Get rid of the columns I won't need
enplanement_20[c("Enplaned_Deplaned", "Dom_Intl_Enplaned", "YM", "NM")] <- list(NULL)
#Filter by airport
iad_20 <- enplanement_20 %>% filter(Airport == "IAD")
#iad_20
iad_20_avg <-mean(iad_20$Enplaned) #Average enplanements a month in 2020 at IAD
iad_20_avg
## [1] 340614
bwi_20 <- enplanement_20 %>% filter(Airport == "BWI") #Filter for BWI
bwi_20_avg <-mean(bwi_20$Enplaned) #Average enplanements a month in 2020 at BWI
bwi_20_avg
## [1] 467233.4
dca_20 <- enplanement_20 %>% filter(Airport == "DCA")
dca_20_avg <-mean(dca_20$Enplaned) #Average enplanements a month in 2020 at DCA
dca_20_avg
## [1] 313961.4
#2021 data
enplanement_21 <- read_excel("Enplanement_Data.xlsx", #Read the excel file
sheet = "2021" #Choose the sheet from 2021
)
anyNA(enplanement_21) #Check for NAs
## [1] FALSE
#Get rid of the columns I won't need
enplanement_21[c("Enplaned_Deplaned", "Dom_Intl_Enplaned", "YM", "NM")] <- list(NULL)
#Filter by airport
iad_21 <- enplanement_21 %>% filter(Airport == "IAD")
#iad_20
iad_21_avg <-mean(iad_21$Enplaned) #Average enplanements a month in 2021 at IAD
iad_21_avg
## [1] 614618.2
bwi_21 <- enplanement_21 %>% filter(Airport == "BWI") #Filter for BWI
bwi_21_avg <-mean(bwi_21$Enplaned) #Average enplanements a month in 2021 at BWI
bwi_21_avg
## [1] 784436.3
dca_21 <- enplanement_21 %>% filter(Airport == "DCA")
dca_21_avg <-mean(dca_21$Enplaned) #Average enplanements a month in 2021 at DCA
dca_21_avg
## [1] 587413.6
#Combine the data from 2019-2021
updated_enplanement <- rbind(iad_19, iad_20, iad_21, dca_19, dca_20, dca_21, bwi_19, bwi_20, bwi_21)
updated_enplanement
## # A tibble: 108 × 8
## Year Month Airport Enplaned Deplaned Dom_Enplaned Intl_Enplaned Year_txt
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <chr>
## 1 2019 January IAD 774129 827238 529654 244475 2019
## 2 2019 February IAD 728391 724784 497127 231264 2019
## 3 2019 March IAD 971146 991241 661039 310107 2019
## 4 2019 April IAD 1002803 1027129 673277 329526 2019
## 5 2019 May IAD 1132554 1103661 731276 401278 2019
## 6 2019 June IAD 1220533 1169625 769138 451395 2019
## 7 2019 July IAD 1218537 1242379 790993 427544 2019
## 8 2019 August IAD 1165068 1205995 746671 418397 2019
## 9 2019 September IAD 998394 1021301 648148 350246 2019
## 10 2019 October IAD 1077888 1079480 733527 344361 2019
## # ℹ 98 more rows
iad_19_avg
## [1] 1027410
iad_20_avg
## [1] 340614
iad_21_avg
## [1] 614618.2
dca_19_avg
## [1] 995753.5
dca_20_avg
## [1] 313961.4
dca_21_avg
## [1] 587413.6
bwi_19_avg
## [1] 1128479
bwi_20_avg
## [1] 467233.4
bwi_21_avg
## [1] 784436.3
#Graph the data
library(ggplot2)
ggplot(updated_enplanement,
aes(x = Airport,
y = Enplaned,
fill = factor(Year))) +
geom_col(position = "dodge") +
scale_y_continuous(
labels = scales::label_comma())+
labs(
title = "Enplanement Trends of DC Area Airports from 2019-2021",
x = "Airport",
y = "Number of Enplanements",
fill = "Year"
) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid.major.y = element_line(
color = "gray80",
linewidth = 0.4
),
panel.grid.minor.y = element_line(
color = "gray90",
linewidth = 0.2
),
panel.grid.major.x = element_blank()
)
C. Conclusion
In conclusion, the pandemic impacted all three airports and airport travel has not returned to pre-pandemic levels as of 2021. BWI and DCA saw a positive recovery while IAD’s total enplanements for 2021 decreased compared to 2020.
To further the analysis of this data, I think looking at the emplacements by month in addition to year would be a good indicator of how busy each airport is throughout the year. While COVID-19 is one event that impacts air travel, there are many other that could be taking place concurrently such as severe weather.
D. References
Centers for Disease Control and Prevention. (2023, September 12). End of the federal COVID-19 public health emergency (PHE) declaration. https://archive.cdc.gov/www_cdc_gov/coronavirus/2019-ncov/your-health/end-of-phe.html
Metropolitan Washington Council of Governments. (n.d.). Enplanement data: 2000–2023 [Data set]. Regional Transportation Data Clearinghouse. https://rtdc-mwcog.opendata.arcgis.com/documents/b58ae0e96b034867afd809a9896b9442/about