Research Question

How concentrated is air travel capacity in a country’s largest international airport?

I chose the Global Airports dataset from the World Bank because I was interested in how international air travel is distributed within different countries. The dataset includes airport locations with international travel and the total number of seats reported for each airport.

For this analysis, I wanted to see whether a country’s air travel capacity is spread across many international airports or mostly concentrated in its largest airport.

Setup

library(dplyr)
library(ggplot2)
library(readr)

Import and Explore the Data

First, I imported the data and looked at the size, column names, and first few rows.

airport_data <- read_csv("airport_volume_airport_locations.csv")

print(dim(airport_data))
## [1] 2173    6
print(names(airport_data))
## [1] "Orig"              "Name"              "TotalSeats"       
## [4] "Country Name"      "Airport1Latitude"  "Airport1Longitude"
print(head(airport_data))
## # A tibble: 6 × 6
##   Orig  Name        TotalSeats `Country Name` Airport1Latitude Airport1Longitude
##   <chr> <chr>            <dbl> <chr>                     <dbl>             <dbl>
## 1 HEA   Herat           22042. Afghanistan                34.2              62.2
## 2 JAA   Jalalabad        6344. Afghanistan                34.4              70.5
## 3 KBL   Kabul Inte…   1016197. Afghanistan                34.6              69.2
## 4 KDH   Kandahar I…     39924. Afghanistan                31.5              65.8
## 5 MZR   Mazar-e-Sh…     58327. Afghanistan                36.7              67.2
## 6 OAI   Bagram Air…     18017. Afghanistan                34.9              69.3

The dataset has 2,174 rows and 6 columns. The variables include the airport code, airport name, total seats, country, latitude, and longitude.

Data Preparation

Before doing the analysis, I checked each column for missing values.

missing_values <- colSums(is.na(airport_data))

print(missing_values)
##              Orig              Name        TotalSeats      Country Name 
##                 0                 0                 0                 0 
##  Airport1Latitude Airport1Longitude 
##                 0                 0

The result shows that one row contains missing values. I removed the incomplete row before continuing the analysis.

clean_airport_data <- na.omit(airport_data)

print(dim(clean_airport_data))
## [1] 2173    6

One row contained missing values and was removed, leaving 2,173 rows for analysis.

Insight 1: Number of International Airports by Country

First, I used count() to see how many international airports are represented for each country.

airport_count <- clean_airport_data %>%
  count(`Country Name`, sort = TRUE)

print(head(airport_count, 10))
## # A tibble: 10 × 2
##    `Country Name`         n
##    <chr>              <int>
##  1 United States        291
##  2 China                102
##  3 Russian Federation    93
##  4 Canada                82
##  5 France                62
##  6 Japan                 53
##  7 United Kingdom        52
##  8 Mexico                47
##  9 Italy                 46
## 10 Spain                 43

The result shows the 10 countries with the most international airports represented in the dataset. The United States has the highest number, with 291 airports.

This made me wonder if having many international airports means that air travel capacity is spread across those airports, or if most of the capacity can still be concentrated in one major airport.

Insight 2: How Concentrated Is Air Travel Capacity?

Next, I used group_by() and summarize() to calculate the number of airports, total reported seats, and seats at the largest airport for each country.

country_summary <- clean_airport_data %>%
  group_by(`Country Name`) %>%
  summarize(
    airport_count = n(),
    total_seats = sum(TotalSeats, na.rm = TRUE),
    largest_airport_seats = max(TotalSeats, na.rm = TRUE)
  )

print(head(country_summary))
## # A tibble: 6 × 4
##   `Country Name`      airport_count total_seats largest_airport_seats
##   <chr>                       <int>       <dbl>                 <dbl>
## 1 Afghanistan                     7    1175318.              1016197.
## 2 Albania                         1    2063323.              2063323.
## 3 Algeria                        18    5796917.              3904926.
## 4 Angola                          4    1235516.              1227093.
## 5 Anguilla                        1      28511.                28511.
## 6 Antigua and Barbuda             2     631487.               630335.

The result gives one row for each country. It shows the number of airports represented, the total reported seats, and the seats at the largest airport.

Next, I calculated the percentage of each country’s total reported seats that comes from its largest airport.

country_summary <- country_summary %>%
  mutate(
    largest_airport_share = largest_airport_seats / total_seats * 100
  )

print(head(country_summary))
## # A tibble: 6 × 5
##   `Country Name`      airport_count total_seats largest_airport_seats
##   <chr>                       <int>       <dbl>                 <dbl>
## 1 Afghanistan                     7    1175318.              1016197.
## 2 Albania                         1    2063323.              2063323.
## 3 Algeria                        18    5796917.              3904926.
## 4 Angola                          4    1235516.              1227093.
## 5 Anguilla                        1      28511.                28511.
## 6 Antigua and Barbuda             2     631487.               630335.
## # ℹ 1 more variable: largest_airport_share <dbl>

The largest_airport_share variable shows the percentage of a country’s reported seats that comes from its largest airport. A higher percentage means that more of the country’s air travel capacity is concentrated in one airport.

For the comparison, I only included countries with at least 5 international airports represented in the dataset.

concentration_data <- country_summary %>%
  filter(airport_count >= 5) %>%
  arrange(desc(largest_airport_share))

print(head(concentration_data, 10))
## # A tibble: 10 × 5
##    `Country Name`   airport_count total_seats largest_airport_seats
##    <chr>                    <int>       <dbl>                 <dbl>
##  1 Belarus                      6    2753340.              2729413.
##  2 Chile                       11    7094794.              7009498.
##  3 Israel                       6   14048713.             13820203.
##  4 Estonia                      5    1923393.              1888248.
##  5 Peru                         7    7352555.              7214675.
##  6 Panama                       9   10318333.             10113504.
##  7 Sudan                        6    1945812.              1905692.
##  8 Senegal                      5    1637042.              1578607.
##  9 Papua New Guinea            11     472358.               455316.
## 10 Azerbaijan                   5    2783342.              2681377.
## # ℹ 1 more variable: largest_airport_share <dbl>

This helps avoid comparisons based on countries with only one or two airport observations.

Finland was especially interesting to me. It has 22 international airports represented in the dataset, but about 95% of its reported seats come from its largest airport.

This surprised me because Finland has many international airports represented, but its reported air travel capacity is still highly concentrated in one major airport.

Visualization

For the visualization, I selected Finland and several other countries to compare the percentage of reported seats coming from their largest airport.

comparison_countries <- concentration_data %>%
  filter(`Country Name` %in% c(
    "Finland",
    "Belarus",
    "Chile",
    "Germany",
    "United Kingdom",
    "Spain"
  )) %>%
  mutate(
    `Country Name` = factor(
      `Country Name`,
      levels = c(
        "Spain",
        "Germany",
        "United Kingdom",
        "Chile",
        "Belarus",
        "Finland"
      )
    )
  )

print(comparison_countries)
## # A tibble: 6 × 5
##   `Country Name` airport_count total_seats largest_airport_seats
##   <fct>                  <int>       <dbl>                 <dbl>
## 1 Belarus                    6    2753340.              2729413.
## 2 Chile                     11    7094794.              7009498.
## 3 Finland                   22   12422282.             11762383.
## 4 United Kingdom            52  154411889.             50054383.
## 5 Germany                   38  128494422.             40889303.
## 6 Spain                     43  106829344.             26811681.
## # ℹ 1 more variable: largest_airport_share <dbl>

The selected countries show very different patterns. Finland stands out because even though 22 international airports are represented in the dataset, about 95% of its reported seats come from its largest airport.

ggplot(comparison_countries,
       aes(x = `Country Name`,
           y = largest_airport_share)) +
  geom_col() +
  coord_flip() +
  labs(
    title = "Air Travel Capacity in Selected Countries",
    subtitle = "Finland: 95% of seats concentrated in one airport",
    x = "Country",
    y = "Share of Seats at Largest Airport (%)"
  )

The chart shows that having many international airports does not necessarily mean that air travel capacity is evenly distributed among them.

Conclusion

From this analysis, I found that the number of international airports in a country does not tell the whole story about how its air travel capacity is distributed.

Finland was the most interesting example to me. Out of 22 international airports represented in the dataset, about 95% of Finland’s reported seats come from just its largest airport.

This shows that even when a country has many international airports, its air travel capacity can still be highly concentrated in one major airport.