Checking the Data:

Importing necessary libraries:

library(readr)
library(skimr)
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(knitr)
library(ggplot2)
library(tidyr)

Reading the data file:

df <- read.csv("Data/airline.csv", header = TRUE)

Understanding the Data:

I did this step to get the name of the columns, so that later when I use the head() function the text won’t be long, because of the reviews from customers were long and it’s not appealing to the eye.

colnames(df)
##  [1] "Airline_Name"               "Review_Date"               
##  [3] "Rating"                     "Comment"                   
##  [5] "Reviewer_Name"              "Reviewer_Country"          
##  [7] "Verified"                   "Seat_Rating"               
##  [9] "Cabin_staff_service_Rating" "Food_Beverages_Rating"     
## [11] "Inflight_Rating"            "Ground_service_Rating"     
## [13] "Wifi_connectivity_Rating"   "Value_Rating"              
## [15] "Full_review"

And here I coppied them and didn’t use the Comment column.

head(df[, c("Airline_Name", "Review_Date", "Rating", "Reviewer_Name", "Reviewer_Country", "Verified", "Seat_Rating", "Cabin_staff_service_Rating", "Food_Beverages_Rating", "Inflight_Rating", "Ground_service_Rating", "Wifi_connectivity_Rating", "Value_Rating")])
##    Airline_Name Review_Date Rating  Reviewer_Name Reviewer_Country Verified
## 1   AB Aviation  2019-11-11      9     Tom Hansen      Netherlands      Yes
## 2   AB Aviation  2019-06-25      1  Gyan Fernando   United Kingdom      Yes
## 3   AB Aviation  2019-06-25      1  Gyan Fernando   United Kingdom      Yes
## 4 Adria Airways  2019-09-28      1 D Praetextatus           Serbia       No
## 5 Adria Airways  2019-09-24      1       D Meijer      Netherlands      Yes
## 6 Adria Airways  2019-09-17      1   Herbse Mayer          Austria      Yes
##   Seat_Rating Cabin_staff_service_Rating Food_Beverages_Rating Inflight_Rating
## 1           4                          5                     4              NA
## 2           2                          2                     1              NA
## 3           2                          1                     1              NA
## 4           1                          1                    NA              NA
## 5           1                          1                     1               1
## 6           1                          1                     1               1
##   Ground_service_Rating Wifi_connectivity_Rating Value_Rating
## 1                     4                       NA            3
## 2                     1                       NA            2
## 3                     1                       NA            2
## 4                     1                       NA            1
## 5                     1                        1            1
## 6                     1                        1            1
dim(df)
## [1] 139128     15

We have a total of 139128 rows and 15 columns

str(df[, c("Airline_Name", "Review_Date", "Rating", "Reviewer_Name", "Reviewer_Country", "Verified", "Seat_Rating", "Cabin_staff_service_Rating", "Food_Beverages_Rating", "Inflight_Rating", "Ground_service_Rating", "Wifi_connectivity_Rating", "Value_Rating")])
## 'data.frame':    139128 obs. of  13 variables:
##  $ Airline_Name              : chr  "AB Aviation" "AB Aviation" "AB Aviation" "Adria Airways" ...
##  $ Review_Date               : chr  "2019-11-11" "2019-06-25" "2019-06-25" "2019-09-28" ...
##  $ Rating                    : int  9 1 1 1 1 1 1 1 1 8 ...
##  $ Reviewer_Name             : chr  "Tom Hansen" "Gyan Fernando" "Gyan Fernando" "D Praetextatus" ...
##  $ Reviewer_Country          : chr  "Netherlands" "United Kingdom" "United Kingdom" "Serbia" ...
##  $ Verified                  : chr  "Yes" "Yes" "Yes" "No" ...
##  $ Seat_Rating               : num  4 2 2 1 1 1 1 1 1 4 ...
##  $ Cabin_staff_service_Rating: num  5 2 1 1 1 1 1 1 2 4 ...
##  $ Food_Beverages_Rating     : num  4 1 1 NA 1 1 1 1 1 3 ...
##  $ Inflight_Rating           : num  NA NA NA NA 1 1 NA 1 1 NA ...
##  $ Ground_service_Rating     : num  4 1 1 1 1 1 1 1 1 5 ...
##  $ Wifi_connectivity_Rating  : num  NA NA NA NA 1 1 NA 1 1 NA ...
##  $ Value_Rating              : num  3 2 2 1 1 1 1 1 1 5 ...
summary(df)
##  Airline_Name       Review_Date            Rating         Comment         
##  Length:139128      Length:139128      Min.   : 1.000   Length:139128     
##  Class :character   Class :character   1st Qu.: 1.000   Class :character  
##  Mode  :character   Mode  :character   Median : 3.000   Mode  :character  
##                                        Mean   : 4.452                     
##                                        3rd Qu.: 8.000                     
##                                        Max.   :10.000                     
##                                        NA's   :4338                       
##  Reviewer_Name      Reviewer_Country     Verified          Seat_Rating   
##  Length:139128      Length:139128      Length:139128      Min.   :0.000  
##  Class :character   Class :character   Class :character   1st Qu.:1.000  
##  Mode  :character   Mode  :character   Mode  :character   Median :3.000  
##                                                           Mean   :2.729  
##                                                           3rd Qu.:4.000  
##                                                           Max.   :5.000  
##                                                           NA's   :14402  
##  Cabin_staff_service_Rating Food_Beverages_Rating Inflight_Rating
##  Min.   :0.000              Min.   :0.000         Min.   :0.000  
##  1st Qu.:1.000              1st Qu.:1.000         1st Qu.:1.000  
##  Median :3.000              Median :3.000         Median :2.000  
##  Mean   :2.986              Mean   :2.666         Mean   :2.501  
##  3rd Qu.:5.000              3rd Qu.:4.000         3rd Qu.:4.000  
##  Max.   :5.000              Max.   :5.000         Max.   :5.000  
##  NA's   :14805              NA's   :37006         NA's   :53970  
##  Ground_service_Rating Wifi_connectivity_Rating  Value_Rating  
##  Min.   :1.000         Min.   :0.000            Min.   :0.000  
##  1st Qu.:1.000         1st Qu.:1.000            1st Qu.:1.000  
##  Median :2.000         Median :1.000            Median :2.000  
##  Mean   :2.401         Mean   :1.969            Mean   :2.631  
##  3rd Qu.:4.000         3rd Qu.:3.000            3rd Qu.:4.000  
##  Max.   :5.000         Max.   :5.000            Max.   :5.000  
##  NA's   :41954         NA's   :105344           NA's   :1816   
##  Full_review       
##  Length:139128     
##  Class :character  
##  Mode  :character  
##                    
##                    
##                    
## 

Dealing with N/A values

Before we start with any manipulation, I want to mention that there are cases where flights got cancelled (either by the flight carrier or the clinets themselves); so this makes our cleaning not so accurate only if we apply some sentiment analysis.

Deleting old records:

Deleting old records make so much sense because in the old times, people didn’t have phones first, second it was a hassle to fill a survey as the only way would be in the airport itself by filling it in a paper form and handling it to some human which would fill the dataset and probably fill it with mistakes.

So for this I guess starting 10 years before the last record makes sense.

df$Review_Date <- as.Date(df$Review_Date, format = "%Y-%m-%d")

df <- df[format(df$Review_Date, "%Y") >= "2014", ]

Counting the amount of N/A values:

colSums(is.na(df))
##               Airline_Name                Review_Date 
##                          0                          0 
##                     Rating                    Comment 
##                       1626                          0 
##              Reviewer_Name           Reviewer_Country 
##                          0                          0 
##                   Verified                Seat_Rating 
##                          0                       6994 
## Cabin_staff_service_Rating      Food_Beverages_Rating 
##                       7386                      29538 
##            Inflight_Rating      Ground_service_Rating 
##                      45719                      22538 
##   Wifi_connectivity_Rating               Value_Rating 
##                      85784                         14 
##                Full_review 
##                          0
df_complete <- df[complete.cases(df), ]
percentage_of_full <- ( nrow(df_complete) / nrow(df) ) * 100
print(percentage_of_full)
## [1] 25.45999

We can see that we have out 139128 rows, only 30442 are full (ie, no NA values in these rows), which is equal to 25.45% of all full.

total_cells <- prod(dim(df))
total_missing <- sum(is.na(df))

percent_missing <- (total_missing / total_cells) * 100
print(percent_missing)
## [1] 11.1289

We can see that out of all the cells that we have; 11.12% are NA cells.

Ok, after taking a look at the dataset and the amount on N/A values, we get to see that some make sense that they are N/A; which are the Food_Beverages_Rating and Wifi_connectivity_Rating; it’s because not all flights provide food and beverages and not all of then provide Wifi, mostly in budget friendly airlines. The other ones are N/A because when answering the survey the clients did not answer because they didn’t feel like it and none of the fields were mandatory to be filled.

Deleting rows with all columns as N/A:

I am going to be deleting rows with ≤ 1 columns (out of 7) because with ≥ 1 N/As per row we can’t fix the data and replace the N/A because we wouldn’t understand the data then.

I did not consider the columns Food_Beverages_Rating and Wifi_connectivity_Rating because they are a different case. So I created a list of the columns that need to be checked, counted the amount of na values in each row, and kept all the rows with at least 1 columns with a value.

cols_to_check <- c("Seat_Rating", "Cabin_staff_service_Rating","Inflight_Rating", "Ground_service_Rating", "Value_Rating")

na_count_subset <- rowSums(is.na(df[, cols_to_check]))

df_filtered <- df[na_count_subset >= 1, ]

I got a total of 63536 rows now, which is not the worst.

colSums(is.na(df_filtered))
##               Airline_Name                Review_Date 
##                          0                          0 
##                     Rating                    Comment 
##                       1625                          0 
##              Reviewer_Name           Reviewer_Country 
##                          0                          0 
##                   Verified                Seat_Rating 
##                          0                       6994 
## Cabin_staff_service_Rating      Food_Beverages_Rating 
##                       7386                      27442 
##            Inflight_Rating      Ground_service_Rating 
##                      45719                      22538 
##   Wifi_connectivity_Rating               Value_Rating 
##                      61284                         14 
##                Full_review 
##                          0
df_complete_filtered <- df_filtered[complete.cases(df), ]
percentage_of_full_filtered <- ( nrow(df_complete_filtered) / nrow(df_filtered) ) * 100
print(percentage_of_full_filtered)
## [1] 47.91299

Now it’s a bit better by reaching 47.91% of full nto containing any N/A values rows.

total_cells_filtered <- prod(dim(df_filtered))
total_missing_filtered <- sum(is.na(df_filtered))

percent_missing_filtered <- (total_missing_filtered / total_cells_filtered) * 100
print(percent_missing_filtered)
## [1] 18.15265

And now we have more N/A in comparison to the whole set with 18.15% but it makes sense becasue we reduced the size of the set by almost half.

Replacing and Filling N/As:

Now, I have to make sense when doing this and set a rule for this:

  • If I have only 1 value filled in the row:
    • then we can copy the closest row to it with the same values knowing it has the same Rating (Because this column makes the most of sense and represents the full rating of the client (by rule) or at least almost).
    • If the Rating is also N/A in that row than we can copy the reviews of another row with the same airlines.
  • If we have 2 or more filled:
    • Then we can fill the rest based on one, because some are related to each other in a sense.
      • for example: Inflight_Rating and Cabin_staff_service_Rating.
      • for Food_Beverages_Rating and Wifi_connectivity_Rating we can just fill it up with the equation so that the score stays the same for the Rating _ If the Rating is also N/A then we fill with the average of the whole other columns except the Value_Rating
rating_vars <- c("Seat_Rating","Cabin_staff_service_Rating","Food_Beverages_Rating",
                 "Inflight_Rating","Ground_service_Rating","Wifi_connectivity_Rating","Value_Rating")

df_cleaned <- df_filtered

col_means_fill <- sapply(df_cleaned[, c("Food_Beverages_Rating","Wifi_connectivity_Rating","Ground_service_Rating")], mean, na.rm = TRUE)

for(i in 1:nrow(df_cleaned)) {
  
  rating_scaled <- ifelse(!is.na(df_cleaned$Rating[i]), df_cleaned$Rating[i] / 2, NA)
  row_vals <- df_cleaned[i, rating_vars]
  na_cols <- names(row_vals)[is.na(row_vals)]
  filled_cols <- names(row_vals)[!is.na(row_vals)]
  filled_count <- length(filled_cols)
  
  if(i > 1){
    prev_row <- df_cleaned[i-1, rating_vars]
  } else{
    prev_row <- df_cleaned[i, rating_vars]  # first row uses itself
  }

  if(filled_count == 1){
    df_cleaned[i, rating_vars] <- prev_row
  }
  # Ground Rating
  else if(filled_count >= 2){ 
    if("Ground_service_Rating" %in% na_cols) {
      df_cleaned$Ground_service_Rating[i] <- prev_row$Ground_service_Rating
      na_cols <- setdiff(na_cols, "Ground_service_Rating")
      filled_cols <- c(filled_cols, "Ground_service_Rating")
    }
    
   # Inflight and cabin staff:
    if(is.na(df_cleaned$Inflight_Rating[i]) & !is.na(df_cleaned$Cabin_staff_service_Rating[i])){
      df_cleaned$Inflight_Rating[i] <- df_cleaned$Cabin_staff_service_Rating[i]
    }
    if(is.na(df_cleaned$Cabin_staff_service_Rating[i]) & !is.na(df_cleaned$Inflight_Rating[i])){
      df_cleaned$Cabin_staff_service_Rating[i] <- df_cleaned$Inflight_Rating[i]
    }
    
    # Wifi, Food, Ground with mean:
    for(col in c("Food_Beverages_Rating", "Wifi_connectivity_Rating", "Ground_service_Rating")){
      if(col %in% na_cols) {
        df_cleaned[i, col] <- round(col_means_fill[col])
        na_cols <- setdiff(na_cols, col)
        filled_cols <- c(filled_cols, col)
      }
    }
    
    # The avrage matching:
    if(!is.na(rating_scaled)) {
      current_sum <- sum(as.numeric(df_cleaned[i, rating_vars][filled_cols]), na.rm=TRUE)
      current_n <- length(filled_cols)
      total_n <- length(rating_vars)
      
      missing_n <- total_n - current_n
      if(missing_n > 0) {
        target_sum <- rating_scaled * total_n
        fill_value <- (target_sum - current_sum) / missing_n
        fill_value <- max(fill_value, 1)
        for(col in na_cols){
          df_cleaned[i, col] <- fill_value
        }
      }
    }
  }
  
  # Rating
  if(is.na(df_cleaned$Rating[i]) & i > 1) {
    df_cleaned$Rating[i] <- df_cleaned$Rating[i-1]
  }
}

for (col in rating_vars) {
  med <- median(df_cleaned[[col]], na.rm = TRUE)
  df_cleaned[[col]][is.na(df_cleaned[[col]])] <- med
}

# Final cleanup:
df_cleaned <- df_cleaned %>%
  mutate(across(all_of(rating_vars), ~ pmax(pmin(round(as.numeric(.x)), 5), 0)))
summary(df_cleaned)
##  Airline_Name        Review_Date             Rating       Comment         
##  Length:63536       Min.   :2014-01-02   Min.   : 1.0   Length:63536      
##  Class :character   1st Qu.:2015-03-04   1st Qu.: 1.0   Class :character  
##  Mode  :character   Median :2018-01-25   Median : 2.0   Mode  :character  
##                     Mean   :2018-03-28   Mean   : 4.1                     
##                     3rd Qu.:2020-09-28   3rd Qu.: 8.0                     
##                     Max.   :2024-03-23   Max.   :10.0                     
##  Reviewer_Name      Reviewer_Country     Verified          Seat_Rating   
##  Length:63536       Length:63536       Length:63536       Min.   :0.000  
##  Class :character   Class :character   Class :character   1st Qu.:1.000  
##  Mode  :character   Mode  :character   Mode  :character   Median :2.000  
##                                                           Mean   :2.514  
##                                                           3rd Qu.:4.000  
##                                                           Max.   :5.000  
##  Cabin_staff_service_Rating Food_Beverages_Rating Inflight_Rating
##  Min.   :0.000              Min.   :0.000         Min.   :0.000  
##  1st Qu.:1.000              1st Qu.:2.000         1st Qu.:1.000  
##  Median :3.000              Median :3.000         Median :1.000  
##  Mean   :2.767              Mean   :2.834         Mean   :2.176  
##  3rd Qu.:4.000              3rd Qu.:3.000         3rd Qu.:4.000  
##  Max.   :5.000              Max.   :5.000         Max.   :5.000  
##  Ground_service_Rating Wifi_connectivity_Rating  Value_Rating  
##  Min.   :1.000         Min.   :1.000            Min.   :0.000  
##  1st Qu.:1.000         1st Qu.:2.000            1st Qu.:1.000  
##  Median :1.000         Median :2.000            Median :2.000  
##  Mean   :2.247         Mean   :2.008            Mean   :2.508  
##  3rd Qu.:4.000         3rd Qu.:2.000            3rd Qu.:4.000  
##  Max.   :5.000         Max.   :5.000            Max.   :5.000  
##  Full_review       
##  Length:63536      
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Checking again the N/A values:

colSums(is.na(df_cleaned))
##               Airline_Name                Review_Date 
##                          0                          0 
##                     Rating                    Comment 
##                          0                          0 
##              Reviewer_Name           Reviewer_Country 
##                          0                          0 
##                   Verified                Seat_Rating 
##                          0                          0 
## Cabin_staff_service_Rating      Food_Beverages_Rating 
##                          0                          0 
##            Inflight_Rating      Ground_service_Rating 
##                          0                          0 
##   Wifi_connectivity_Rating               Value_Rating 
##                          0                          0 
##                Full_review 
##                          0
df_complete_cleaned <- df_cleaned[complete.cases(df), ]
percentage_of_full_cleaned <- ( nrow(df_complete_cleaned) / nrow(df_cleaned) ) * 100
print(percentage_of_full_cleaned)
## [1] 47.91299
total_cells_cleaned <- prod(dim(df_cleaned))
total_missing_cleaned <- sum(is.na(df_cleaned))

percent_missing_cleaned <- (total_missing_cleaned / total_cells_cleaned) * 100
print(percent_missing_cleaned)
## [1] 0

Everything 0 so now no N/A and now after that the data is all clean and makes sense, I can proceed with the marketing analytics.

Marketing Analytics :

Overall satisfaction index CSI:

sat_items <- c("Seat_Rating","Cabin_staff_service_Rating","Food_Beverages_Rating",
               "Inflight_Rating","Ground_service_Rating","Wifi_connectivity_Rating",
               "Value_Rating")

df_cleaned$CSI <- rowMeans(df_cleaned[, sat_items], na.rm = TRUE)
df_cleaned$CSI_Percentage <- df_cleaned$CSI * 20

CSI_overall_percent <- mean(df_cleaned$CSI_Percentage, na.rm = TRUE)
CSI_overall_percent
## [1] 48.72824

A CSI of 48% means that, on average, customers rate their overall experience just below the midpoint of your 0–100% scale (which corresponds to about 2.4 on a 0–5 scale).

It signals moderate to low satisfaction: customers are not completely unhappy, but they are far from being genuinely satisfied or enthusiastic. There is likely high variability between airlines and touchpoints (onboard vs ground vs wifi), so some areas or carriers perform much better than others.

but this can be seen also as a room for improvement as it’s so close the midpoint.

Sub-indices:

Onboard vs ground vs digital:

df_cleaned$Onboard_Index <- rowMeans(df_cleaned[, c("Seat_Rating","Cabin_staff_service_Rating",
                                                    "Food_Beverages_Rating","Inflight_Rating")], na.rm = TRUE)
df_cleaned$Onboard_Percentage <- df_cleaned$Onboard_Index * 20

df_cleaned$Ground_Index <- rowMeans(df_cleaned[, c("Ground_service_Rating","Wifi_connectivity_Rating")], na.rm = TRUE)
df_cleaned$Ground_Percentage <- df_cleaned$Ground_Index * 20

This code snippet is to show data in a better table.

agg <- aggregate(cbind(CSI_Percentage, Onboard_Percentage, Ground_Percentage) ~ Airline_Name,
          data = df_cleaned,
          FUN = mean,
          na.rm = TRUE)

kable(agg, digits = 2)
Airline_Name CSI_Percentage Onboard_Percentage Ground_Percentage
AB Aviation 45.71 48.33 40.00
Adria Airways 61.76 63.09 57.65
Aegean Airlines 61.96 65.65 53.18
Aer Lingus 55.19 57.08 50.46
Aero VIP 73.33 78.33 63.33
Aeroflot Russian Airlines 56.84 58.98 49.17
AeroItalia 28.57 30.00 30.00
Aerolineas Argentinas 50.23 54.70 37.16
Aeromar 43.43 49.00 40.00
Aeromexico 48.06 52.02 41.03
Africa World Airlines 44.76 50.83 33.33
Aigle Azur 44.76 45.00 41.11
Air Algerie 42.42 42.69 42.31
Air Antilles 47.62 50.00 43.33
Air Arabia 39.90 42.13 36.21
Air Astana 68.49 74.52 54.25
Air Austral 34.29 37.14 32.86
Air Bagan 62.86 72.50 30.00
Air Berlin 55.52 55.49 54.82
Air Botswana 36.33 33.57 47.14
Air Burkina 61.43 67.50 45.00
Air Busan 69.43 71.00 62.00
Air Cairo 50.57 51.50 46.00
Air Canada 41.82 46.23 33.57
Air Canada rouge 37.77 37.10 40.84
Air Caraibes 33.06 37.86 30.00
Air China 52.68 53.25 49.87
Air Corsica 73.06 74.29 64.29
Air Costa 80.00 85.00 60.00
Air Djibouti 57.14 55.00 60.00
Air Dolomiti 57.14 62.29 45.71
Air Europa 41.57 44.64 34.89
Air France 56.78 57.57 55.66
Air Greenland 28.57 30.00 30.00
Air Iceland Connect 85.71 95.00 65.00
Air India 54.78 58.72 44.29
Air India Express 43.90 43.41 42.86
Air Italy 49.45 51.54 44.62
Air Juan 32.67 35.22 32.17
Air KBZ 74.92 78.89 61.11
Air Koryo 65.55 69.71 54.12
Air Macau 42.29 41.00 40.00
Air Madagascar 47.81 51.33 40.00
Air Malta 42.48 44.28 37.89
Air Mauritius 50.60 54.08 42.63
Air Mediterranee 57.14 60.00 40.00
Air Moldova 45.84 47.17 41.30
Air Namibia 55.54 58.80 49.60
Air New Zealand 56.59 59.39 51.95
Air Niugini 30.11 30.00 35.38
Air North Yukon’s Airline 81.43 88.75 65.00
Air Nostrum 59.57 61.50 52.00
Air Panama 46.94 48.21 43.57
Air Pegasus 50.00 51.25 45.00
Air Rarotonga 89.52 98.33 70.00
Air Serbia 58.67 61.60 51.05
Air Seychelles 56.29 57.00 54.00
Air Tahiti Nui 50.65 49.70 53.94
Air Tanzania 42.38 47.50 35.56
Air Transat 48.16 54.31 33.26
Air Vanuatu 43.47 47.14 36.07
Air Zimbabwe 44.29 47.50 35.00
AirAsia 52.53 52.73 49.07
AirAsia India 52.71 56.20 45.70
AirAsia Philippines 41.63 43.61 36.58
AirAsia X 59.06 61.48 46.15
AirAsia Zest 52.50 52.50 45.00
airBaltic 52.39 56.72 43.50
airblue 51.60 52.06 48.82
Aircalin 42.60 39.55 46.36
AirConnect 14.29 0.00 50.00
Airlink 63.49 69.50 52.00
Airnorth 46.31 45.00 50.83
AirSWIFT 44.29 45.00 43.33
Akasa Air 53.39 55.62 48.43
Alaska Airlines 50.40 52.51 47.48
Alitalia 52.49 52.57 51.13
Allegiant Air 39.48 40.68 36.13
Alliance Air 36.68 37.84 35.68
Alliance Airlines 42.86 45.00 40.00
Amaszonas 45.93 48.85 40.77
American Airlines 38.05 41.00 34.24
American Eagle 50.71 51.12 50.53
ANA All Nippon Airways 71.94 76.05 60.46
AnadoluJet 51.60 52.06 46.47
Andes Líneas Aéreas 23.57 22.50 30.00
Arajet 72.86 82.50 50.00
Ariana Afghan Airlines 60.00 55.00 50.00
Arik Air 37.78 40.00 33.33
Arkefly 17.50 11.88 30.00
Arkia Israeli Airlines 38.80 37.89 42.63
Armenia Air Company 28.57 30.00 30.00
Asiana Airlines 68.78 71.34 61.03
ASKY Airlines 36.19 38.75 35.00
ATA Airlines 30.00 25.00 35.00
Atlantic Airways 85.71 95.00 65.00
Atlasglobal 52.93 57.62 41.43
Auric Air 80.00 80.00 70.00
Aurigny Air 56.55 60.86 50.34
Austrian Airlines 53.33 56.82 46.36
Avelo Airlines 47.93 50.98 42.50
Avianca 42.77 44.06 42.35
Avianca Brazil 55.56 63.33 37.78
Avianca Ecuador 34.03 36.82 34.55
Avior Airlines 42.86 40.00 40.00
Azerbaijan Airlines 51.87 53.85 47.69
Azul Airlines 36.11 36.60 35.60
Azur Air Germany 28.57 30.00 30.00
BA CityFlyer 78.44 85.68 61.59
Badr Airlines 74.29 90.00 40.00
Bahamasair 40.26 44.70 37.58
Bamboo Airways 56.34 61.20 46.40
Bangkok Airways 69.63 73.06 59.61
Bassaka Air 78.10 83.89 62.22
Batik Air 48.52 50.44 43.33
Beijing Capital Airlines 44.29 47.50 30.00
Belavia 61.04 64.77 48.64
BH Air 52.00 51.00 50.00
Bhutan Airlines 61.14 69.00 36.00
Biman Bangladesh Airlines 65.45 71.67 46.67
Binter Canarias 73.65 76.11 62.22
Blu-express 28.57 30.00 30.00
Blue Air 46.04 48.54 41.67
Blue Islands 40.43 45.25 38.00
Blue Panorama Airlines 33.66 35.87 33.04
Blue1 22.86 20.00 30.00
Bluebird Airways 43.43 45.33 41.33
bmi Regional 48.78 53.93 41.43
Boliviana de Aviacion 56.95 59.00 44.67
BoraJet 40.00 50.00 30.00
Boutique Air 43.04 46.41 38.75
Breeze Airways 49.25 52.84 41.96
British Airways 55.04 56.81 51.43
Brussels Airlines 46.23 48.75 41.50
Buddha Air 47.38 49.17 44.17
Bulgaria Air 45.38 45.50 42.67
Buta Airways 47.50 49.38 43.75
Camair-Co 30.00 27.50 30.00
Cambodia Airways 68.57 70.00 60.00
Cambodia Angkor Air 44.35 44.92 42.92
Cambodia Bayon Airlines 54.29 50.00 50.00
Canadian North 67.62 75.00 53.33
Canaryfly 68.57 70.83 55.00
Cape Air 33.37 33.57 36.43
Caribbean Airlines 49.14 54.38 39.00
Cathay Dragon 72.00 77.00 58.00
Cathay Pacific Airways 59.24 70.48 31.51
Cayman Airways 43.12 45.00 40.91
Cebu Pacific 49.28 50.55 43.04
CemAir 57.71 61.00 48.00
Central Mountain Air 45.14 48.00 46.00
China Airlines 63.64 62.34 64.53
China Eastern Airlines 55.87 55.42 53.27
China Southern Airlines 73.55 75.63 65.11
China United Airlines 40.00 40.00 35.00
Citilink 63.14 66.33 52.00
CityJet 52.51 58.02 38.97
Coastal Aviation 71.43 72.50 60.00
Cobalt 63.88 66.43 53.57
Comair 53.25 57.64 42.50
Condor Airlines 41.87 45.88 32.69
Contour Airlines 28.57 30.00 30.00
Copa Airlines 43.64 47.64 37.54
Corendon Airlines 43.71 45.81 39.19
Corsair 31.43 35.00 30.00
Croatia Airlines 49.02 51.84 41.32
CSA Czech Airlines 44.08 45.00 42.60
Cubana Airlines 39.73 41.55 33.81
Cyprus Airways 46.35 46.67 36.67
Danish Air Transport 57.14 60.00 50.00
Darwin Airline 50.89 58.44 34.38
Delta Air Lines 49.28 50.74 48.65
Dimonim Air 71.43 65.00 70.00
Discover Airlines 28.57 30.00 30.00
Dragonair 67.92 70.42 59.58
Druk Air 76.07 82.50 63.75
Dynamic International Airways 37.14 40.00 40.00
Eastar Jet 53.19 53.46 47.69
Eastern Airlines 29.52 31.67 30.00
Eastern Airways 49.63 51.67 49.63
Easyfly 59.59 60.71 52.86
easyJet 53.74 57.99 41.89
Edelweiss Air 59.71 68.17 40.33
Egyptair 44.86 49.57 33.46
El Al Israel Airlines 46.01 51.64 33.73
Ellinair 73.77 81.36 56.36
Emirates 56.02 65.92 31.93
Ernest Airlines 42.86 45.00 40.00
Estonian Air 71.43 75.71 58.57
Ethiopian Airlines 55.54 54.64 56.39
Etihad Airways 53.84 52.33 58.40
euroAtlantic Airways 29.52 30.00 33.33
Europe Airpost 65.71 75.00 30.00
Eurowings 44.04 46.63 39.26
EVA Air 71.06 73.04 64.26
EWA Air 34.29 40.00 30.00
Far Eastern Air Transport 41.43 35.00 45.00
fastjet 55.03 58.70 47.04
Felix Airways 80.00 80.00 70.00
Fiji Airways 53.47 59.73 37.43
Finnair 51.66 56.42 39.76
Firefly 60.06 63.75 50.62
Flair Airlines 43.44 45.91 39.71
Fly540.com 38.10 37.92 37.50
flyadeal 35.97 37.06 34.12
FlyArystan 74.29 80.00 56.67
flybe 62.14 65.00 55.00
flybondi 31.43 25.00 30.00
flydubai 45.77 48.56 40.38
Flynas 32.78 33.42 34.21
FLYONE 38.39 39.38 40.62
FlySafair 53.12 55.70 47.10
FMI Air 84.29 90.00 70.00
Freebird Airlines 40.87 40.15 41.21
French Bee 33.86 36.30 32.59
Frontier Airlines 34.43 35.94 33.57
Fuji Dream Airlines 88.57 95.00 70.00
Garuda Indonesia 78.81 84.98 62.77
Georgian Airways 42.10 44.83 38.00
Germania Airline 37.14 39.29 34.29
Germanwings 48.18 50.26 36.03
Go First 37.47 39.50 35.95
GoAir 38.64 40.64 37.07
Gol Transportes Aéreos 54.11 55.15 47.58
Golden Myanmar Airlines 80.95 86.67 63.33
Grand Cru Airlines 91.43 100.00 70.00
Greater Bay Airlines 40.95 43.33 36.67
Gulf Air 45.32 51.08 33.54
Hainan Airlines 67.58 71.59 56.36
Hawaiian Airlines 46.27 50.58 36.75
Helvetic Airways 67.90 73.82 54.12
Hi Fly 64.76 70.83 53.33
Himalaya Airlines 32.38 33.33 30.00
HiSky 58.37 60.00 52.86
HK Express 49.78 49.67 46.67
Hong Kong Airlines 53.29 55.58 45.12
HOP! 61.67 68.33 49.17
Horizon Air 70.95 75.83 58.33
Hunnu Air 82.86 95.00 60.00
Iberia 51.04 51.49 49.12
Iberia Express 43.59 44.61 41.57
Icelandair 49.18 53.64 36.39
IndiGo 59.66 61.54 52.43
Insel Air 31.17 33.11 30.89
Intercaribbean Airways 41.22 47.14 35.71
Interjet 37.43 40.18 34.75
InterSky 64.29 67.50 50.00
Iran Air 69.80 75.71 52.86
Iran Aseman Airlines 52.38 60.00 30.00
Island Air 42.08 36.82 50.91
Israir Airlines 36.67 35.00 43.33
ITA Airways 38.40 40.54 36.67
Japan Airlines 69.40 71.51 65.00
Jazeera Airways 36.24 38.16 35.26
Jazz 75.24 78.33 70.00
JC International Airlines 74.29 80.00 70.00
Jeju Air 49.62 51.58 44.21
Jet Airways 51.01 54.35 41.47
Jet2.com 65.96 68.02 58.73
Jetairfly 56.19 55.00 58.33
Jetblue Airways 39.98 43.33 35.83
JetSmart 42.60 43.18 42.73
Jetstar Airways 43.34 45.94 36.92
Jetstar Asia 47.39 47.90 42.29
Jetstar Japan 38.07 39.73 35.14
Jetstar Pacific 40.59 39.48 42.76
JetsuiteX 91.43 100.00 70.00
Jin Air 69.18 72.14 56.43
Joon 35.71 35.00 45.00
Jordan Aviation 88.57 95.00 70.00
Juneyao Air 53.43 54.25 50.00
Kan Air 61.43 67.50 50.00
KD Air 28.57 30.00 30.00
Kenya Airways 51.59 57.92 37.04
Kish Airlines 68.57 65.00 70.00
KLM Royal Dutch Airlines 57.21 63.74 42.45
Korean Air 67.52 73.92 50.50
Kulula 45.78 48.60 40.47
Kuwait Airways 42.04 45.00 33.21
La Compagnie 46.67 49.17 41.67
LAM Mozambique 41.51 45.88 35.88
LAN Airlines 56.16 65.71 31.43
LAN Colombia 57.14 60.00 35.00
LAN Peru 35.71 42.50 30.00
Lao Airlines 70.00 75.00 56.67
Lao Skyway 67.96 73.75 56.43
LATAM Airlines 39.76 42.34 37.57
Laudamotion 42.09 42.31 38.46
LC Perú 44.84 48.46 37.69
Level 41.98 43.59 39.49
LIAT 36.57 38.00 35.14
Lion Air 43.27 44.42 39.77
Loganair 64.45 71.03 52.65
LOT Polish Airlines 52.41 55.78 44.68
Lubeck Air 91.43 100.00 70.00
Lucky Air 28.57 30.00 30.00
Lufthansa 57.79 62.59 47.20
Luxair 57.40 61.82 48.18
Lynx Air 45.12 47.70 40.45
Mack Air 77.14 75.00 70.00
Madagasikara Airways 87.14 92.50 70.00
Mahan Air 45.71 38.33 60.00
Malawian Airlines 51.43 56.67 42.50
Malaysia Airlines 54.28 61.40 34.49
Maldivian 57.62 57.50 60.00
Malindo Air 48.78 50.00 45.21
Mandarin Airlines 71.43 77.50 50.00
Mango Airlines 44.91 47.39 39.30
Mann Yadanarpon Airlines 65.71 80.00 45.00
Manta Air 82.86 100.00 60.00
Mauritania Airlines 40.00 40.00 40.00
Maya Island Air 30.00 32.50 30.00
MAYAir 57.14 55.00 50.00
MEGA Maldives Airlines 40.00 45.00 40.00
Meridiana 50.36 52.88 42.25
MIAT Mongolian Airlines 50.95 53.33 45.00
Middle East Airlines 39.00 36.75 45.00
Mihin Lanka 49.14 48.00 42.00
Mokulele Airlines 38.86 37.00 42.00
Monarch Airlines 56.55 53.76 57.92
Montenegro Airlines 48.10 48.33 43.33
Motor Sich Airlines 65.71 66.67 56.67
Myanmar Airways 62.14 56.88 70.00
Myanmar National Airlines 75.00 84.38 56.25
NAM Air 56.48 57.69 52.31
Nature Air 37.86 40.31 37.50
Nauru Airlines 88.57 100.00 70.00
Nepal Airlines 59.18 65.00 47.14
NIKI 61.04 60.45 60.00
Nile Air 74.29 80.00 50.00
Nok Air 54.81 56.27 48.27
NokScoot 50.00 47.50 50.00
Nordavia 35.71 40.00 30.00
Nordic Regional Airlines 60.00 60.00 60.00
Nordica 77.14 80.00 70.00
NordStar 71.43 65.00 70.00
Nordwind Airlines 74.29 72.50 70.00
Norse Atlantic Airways 41.61 44.87 36.41
Norwegian 49.26 52.93 37.90
Nouvelair 50.29 49.50 49.00
Novoair 68.57 75.00 50.00
Okay Airways 40.00 25.00 50.00
Olympic Air 58.53 63.33 49.49
Oman Air 44.93 48.36 33.44
Omni Air International 85.71 90.00 70.00
Onur Air 34.93 34.19 31.29
Openskies 14.29 8.75 30.00
Orient Thai Airlines 50.00 40.00 70.00
Pacific Airlines 44.68 49.09 39.09
Pakistan Intl Airlines 45.17 46.81 39.83
PAL Express 50.95 44.17 63.33
Pan Pacific Airlines 22.86 20.00 30.00
Passaredo 31.43 30.00 40.00
Passion Air 46.67 48.33 40.00
PAWA Dominicana 65.71 72.50 45.00
Peach Aviation 48.42 49.91 41.90
Pegasus Airlines 44.51 45.13 40.34
PenAir 41.90 43.33 43.33
Peruvian Airlines 34.46 35.94 33.12
Petroleum Air Services 65.71 67.50 55.00
Philippine Airlines 53.08 55.41 47.03
PLAY 62.55 66.35 52.01
Pobeda Airlines 38.37 38.86 36.57
Porter Airlines 46.76 50.67 40.49
Precision Air 43.64 46.09 40.55
Primera Air 45.14 39.00 46.00
Privilege Style 73.71 80.00 52.00
Qantas Airways 63.33 67.12 55.26
QantasLink 56.74 55.47 61.25
Qatar Airways 62.32 69.65 42.56
Qazaq Air 81.43 87.50 60.00
Ravn Alaska 37.74 40.00 35.79
Red Wings Airlines 47.14 55.00 40.00
Regent Airways 54.64 53.75 50.00
Regional Express 66.75 69.39 60.00
Rex Airlines 81.39 87.95 65.61
Rhein-Neckar Air 88.57 95.00 70.00
Rossiya Airlines 61.63 62.14 55.00
Royal Air Maroc 42.72 46.50 34.80
Royal Brunei Airlines 76.37 77.69 67.95
Royal Jordanian Airlines 51.98 53.88 48.21
Rwandair 52.92 56.09 45.22
Ryanair 49.81 52.70 39.91
S7 Siberia Airlines 62.32 65.00 52.19
SA Express 27.06 25.59 34.12
Safarilink 61.43 67.50 55.00
Safi Airways 25.71 27.50 25.00
Salam Air 30.00 31.25 28.75
Sansa Airlines 52.14 56.25 45.00
Santa Barbara Airlines 31.43 35.00 30.00
SAS Scandinavian 47.51 48.78 44.71
SATA Air Azores 42.38 42.59 42.89
SATA International 44.89 47.33 36.00
SATENA 54.29 55.00 50.00
Saudi Arabian Airlines 52.66 56.13 44.22
SCAT Airlines 67.14 68.75 50.00
Scoot 49.19 50.12 43.77
Seaborne Airlines 35.05 37.67 34.00
SereneAir 44.44 47.22 41.11
Shaheen Air 66.98 71.67 47.78
Shandong Airlines 44.00 45.00 42.00
Shanghai Airlines 46.94 47.50 42.14
Shenzhen Airlines 43.67 46.43 38.57
Sichuan Airlines 49.64 50.62 46.25
SilkAir 61.07 60.60 61.04
Silver Airways 35.26 37.41 34.30
Singapore Airlines 66.24 71.30 55.28
Sky Airline 46.13 48.90 40.24
Sky Express Airlines 48.74 51.52 43.77
Skybus 40.00 40.00 30.00
Skymark Airlines 61.90 62.50 50.00
Skytrans Airlines 44.00 48.00 38.00
SkyWest Airlines 60.95 58.75 65.00
SkyWork Airlines 50.00 55.00 45.00
Small Planet Airlines 65.46 67.87 57.06
Smartavia 32.14 31.25 32.50
SmartLynx Airlines 38.29 39.67 38.67
SmartWings 46.73 47.40 44.17
Solomon Airlines 74.29 80.00 62.00
Somon Air 34.29 30.00 50.00
South African Airways 54.95 58.55 47.35
Southern Airways Express 28.57 30.00 30.00
Southwest Airlines 50.39 52.23 46.80
SpiceJet 50.38 52.75 45.08
Spirit Airlines 37.30 38.59 35.24
Spring Airlines 45.18 45.16 40.94
SriLankan Airlines 56.85 58.65 52.26
Sriwijaya Air 53.18 54.20 46.82
Star Peru 40.95 40.42 42.50
STARLUX Airlines 37.14 38.33 33.33
Sun Country Airlines 42.38 45.44 37.44
Sun-Air 91.43 100.00 70.00
SunExpress 49.78 52.78 44.67
Sunwing Airlines 43.93 46.07 39.01
Super Air Jet 39.52 40.83 38.33
Surinam Airways 35.14 35.00 39.00
SVG Air 60.00 60.00 60.00
Swiss Intl Air Lines 55.73 60.02 46.42
Swoop 44.50 46.69 41.16
T’Way Air 50.00 52.19 45.62
TAAG Angola Airlines 34.45 34.41 34.12
TACA Airlines 54.29 60.00 30.00
TACV Cabo Verde Airlines 47.01 51.36 38.18
TAG Airlines 47.79 49.55 44.55
Tailwind Airlines 47.14 47.50 45.00
TAM Airlines 51.16 58.24 33.15
TAME 32.95 35.00 32.00
Tame Línea Aérea Del Ecuador 37.50 36.88 40.00
TAP Portugal 47.40 51.11 39.73
TAR Aerolineas 53.88 55.00 50.00
TAROM Romanian 60.90 66.45 46.16
Thai AirAsia 59.31 61.34 50.74
Thai Airways 64.44 65.83 60.78
Thai Lion Air 48.50 50.42 44.07
Thai Smile Airways 74.07 79.46 59.60
Thomas Cook Airlines 53.46 51.76 56.04
Thomas Cook Airlines Scandinavia 62.86 65.00 60.00
Thomson Airways 50.84 57.34 34.15
Tianjin Airlines 50.00 52.50 45.00
Tigerair 52.48 53.01 47.14
Tigerair Australia 42.86 45.08 38.24
Tigerair Taiwan 47.76 50.00 41.43
Titan Airways 70.07 75.00 57.62
Transaero Airlines 41.79 43.75 30.00
Transavia 46.54 49.32 39.88
TransNusa 64.29 62.50 60.00
Trigana Air 70.00 72.50 65.00
Tropic Air Belize 60.95 63.33 56.67
TUI Airways 55.84 59.13 46.09
TUIfly 58.51 60.22 52.17
Tunisair 47.65 50.00 37.50
Turkish Airlines 49.06 55.47 34.09
Turkmenistan Airlines 49.29 52.50 35.00
TUS Airways 67.86 76.25 52.50
Uganda Airlines 76.43 85.00 57.50
Ukraine International 49.00 49.53 44.75
Ultra Air 81.43 82.50 70.00
United Airlines 39.91 43.21 34.65
UP by El Al 34.29 30.00 40.00
Ural Airlines 54.29 57.33 45.33
US Airways 38.33 41.21 30.99
US-Bangla Airlines 57.14 58.75 51.25
Utair Aviation 43.57 37.50 52.50
Uzbekistan Airways 52.32 54.38 41.25
V Air 59.52 62.50 50.00
Vanilla Air 58.18 59.55 50.00
ViaAir 30.29 32.00 32.00
VietJet Air 41.92 43.97 38.36
Vietnam Airlines 58.93 59.46 54.15
Virgin America 52.11 59.94 32.75
Virgin Atlantic 64.07 63.01 67.03
Virgin Australia 54.99 57.79 48.93
Vistara 68.18 74.53 56.07
Viva Air 31.14 32.80 30.40
VivaAerobús 37.87 39.03 36.43
VivaColombia 33.71 34.33 33.33
VLM Airlines 71.90 79.17 58.33
Volaris 34.51 35.67 33.88
Volotea 61.16 64.53 51.71
Voyage Air 45.71 40.00 30.00
Vueling Airlines 40.16 41.85 37.00
Wamos Air 57.14 60.00 50.00
WestJet Airlines 45.28 48.49 40.82
Wideroe 44.90 48.57 40.00
Winair 37.14 41.11 35.56
Wingo 35.51 37.38 34.76
Wings Air 45.96 49.35 41.74
Wizz Air 43.06 44.99 38.15
World2Fly 60.00 65.00 30.00
WOW air 44.43 45.92 40.75
Xiamen Airlines 49.66 55.52 40.00
XL Airways France 42.29 45.00 32.00
Yakutia Airlines 54.29 55.00 50.00
Yangon Airways 62.86 70.00 40.00
Yeti Airlines 52.00 52.00 48.00
Zambia Airways 42.86 40.00 40.00
ZIPAIR 43.71 45.38 40.75
df_cleaned$NPS_group <- cut(df_cleaned$Rating,
                            breaks = c(-Inf, 6, 8, Inf),
                            labels = c("Detractor","Passive","Promoter"))
nps_by_airline <- df_cleaned %>%
  group_by(Airline_Name) %>%
  summarise(
    promoters = mean(NPS_group == "Promoter") * 100,
    detractors = mean(NPS_group == "Detractor") * 100,
    NPS = promoters - detractors
  )
kable(nps_by_airline, digits = 2)
Airline_Name promoters detractors NPS
AB Aviation 33.33 66.67 -33.33
ANA All Nippon Airways 46.71 29.61 17.11
ASKY Airlines 8.33 91.67 -83.33
ATA Airlines 0.00 100.00 -100.00
Adria Airways 32.35 47.06 -14.71
Aegean Airlines 38.28 46.65 -8.37
Aer Lingus 25.36 58.70 -33.33
Aero VIP 66.67 0.00 66.67
AeroItalia 0.00 100.00 -100.00
Aeroflot Russian Airlines 23.79 54.37 -30.58
Aerolineas Argentinas 14.93 59.70 -44.78
Aeromar 0.00 80.00 -80.00
Aeromexico 15.88 74.68 -58.80
Africa World Airlines 16.67 83.33 -66.67
Aigle Azur 11.11 66.67 -55.56
Air Algerie 15.38 76.92 -61.54
Air Antilles 33.33 66.67 -33.33
Air Arabia 8.05 86.21 -78.16
Air Astana 56.16 26.03 30.14
Air Austral 0.00 85.71 -85.71
Air Bagan 0.00 0.00 0.00
Air Berlin 21.34 59.15 -37.80
Air Botswana 57.14 42.86 14.29
Air Burkina 0.00 50.00 -50.00
Air Busan 50.00 30.00 20.00
Air Cairo 20.00 70.00 -50.00
Air Canada 11.37 79.91 -68.54
Air Canada rouge 6.27 87.47 -81.20
Air Caraibes 0.00 100.00 -100.00
Air China 17.88 68.21 -50.33
Air Corsica 42.86 42.86 0.00
Air Costa 0.00 0.00 0.00
Air Djibouti 0.00 100.00 -100.00
Air Dolomiti 22.86 45.71 -22.86
Air Europa 7.69 78.02 -70.33
Air France 21.63 61.59 -39.97
Air Greenland 0.00 100.00 -100.00
Air Iceland Connect 100.00 0.00 100.00
Air India 21.74 55.90 -34.16
Air India Express 4.76 74.60 -69.84
Air Italy 15.38 76.92 -61.54
Air Juan 0.00 95.65 -95.65
Air KBZ 44.44 0.00 44.44
Air Koryo 23.53 35.29 -11.76
Air Macau 0.00 100.00 -100.00
Air Madagascar 6.67 73.33 -66.67
Air Malta 7.89 76.32 -68.42
Air Mauritius 13.16 57.89 -44.74
Air Mediterranee 0.00 0.00 0.00
Air Moldova 17.39 65.22 -47.83
Air Namibia 28.00 60.00 -32.00
Air New Zealand 29.59 56.21 -26.63
Air Niugini 0.00 84.62 -84.62
Air North Yukon’s Airline 75.00 25.00 50.00
Air Nostrum 20.00 50.00 -30.00
Air Panama 7.14 64.29 -57.14
Air Pegasus 0.00 75.00 -75.00
Air Rarotonga 100.00 0.00 100.00
Air Serbia 34.55 51.83 -17.28
Air Seychelles 25.00 65.00 -40.00
Air Tahiti Nui 6.06 75.76 -69.70
Air Tanzania 5.56 83.33 -77.78
Air Transat 28.74 60.15 -31.42
Air Vanuatu 10.71 71.43 -60.71
Air Zimbabwe 0.00 100.00 -100.00
AirAsia 14.49 59.97 -45.48
AirAsia India 18.00 69.00 -51.00
AirAsia Philippines 11.39 87.34 -75.95
AirAsia X 31.84 44.13 -12.29
AirAsia Zest 37.50 62.50 -25.00
AirConnect 0.00 100.00 -100.00
AirSWIFT 16.67 66.67 -50.00
Aircalin 9.09 63.64 -54.55
Airlink 42.00 40.00 2.00
Airnorth 29.17 58.33 -29.17
Akasa Air 25.84 60.67 -34.83
Alaska Airlines 27.08 66.27 -39.19
Alitalia 22.01 61.49 -39.48
Allegiant Air 13.08 79.53 -66.45
Alliance Air 5.41 89.19 -83.78
Alliance Airlines 20.00 80.00 -60.00
Amaszonas 7.69 69.23 -61.54
American Airlines 7.29 88.30 -81.01
American Eagle 23.68 68.42 -44.74
AnadoluJet 17.65 58.82 -41.18
Andes Líneas Aéreas 0.00 100.00 -100.00
Arajet 50.00 50.00 0.00
Ariana Afghan Airlines 0.00 100.00 -100.00
Arik Air 0.00 88.89 -88.89
Arkefly 12.50 37.50 -25.00
Arkia Israeli Airlines 10.53 84.21 -73.68
Armenia Air Company 0.00 100.00 -100.00
Asiana Airlines 43.30 37.11 6.19
Atlantic Airways 100.00 0.00 100.00
Atlasglobal 23.81 54.76 -30.95
Auric Air 100.00 0.00 100.00
Aurigny Air 34.48 51.72 -17.24
Austrian Airlines 21.76 62.53 -40.77
Avelo Airlines 19.64 77.68 -58.04
Avianca 10.38 82.69 -72.31
Avianca Brazil 33.33 44.44 -11.11
Avianca Ecuador 0.00 100.00 -100.00
Avior Airlines 0.00 100.00 -100.00
Azerbaijan Airlines 23.08 53.85 -30.77
Azul Airlines 16.00 72.00 -56.00
Azur Air Germany 0.00 100.00 -100.00
BA CityFlyer 52.27 13.64 38.64
BH Air 20.00 60.00 -40.00
Badr Airlines 0.00 0.00 0.00
Bahamasair 6.06 84.85 -78.79
Bamboo Airways 20.00 56.00 -36.00
Bangkok Airways 50.49 29.13 21.36
Bassaka Air 66.67 22.22 44.44
Batik Air 12.28 71.93 -59.65
Beijing Capital Airlines 50.00 50.00 0.00
Belavia 36.36 36.36 0.00
Bhutan Airlines 40.00 60.00 -20.00
Biman Bangladesh Airlines 30.30 27.27 3.03
Binter Canarias 44.44 33.33 11.11
Blu-express 0.00 100.00 -100.00
Blue Air 15.62 70.83 -55.21
Blue Islands 20.00 65.00 -45.00
Blue Panorama Airlines 0.00 95.65 -95.65
Blue1 0.00 100.00 -100.00
Bluebird Airways 20.00 80.00 -60.00
Boliviana de Aviacion 13.33 53.33 -40.00
BoraJet 0.00 100.00 -100.00
Boutique Air 15.62 84.38 -68.75
Breeze Airways 18.92 73.65 -54.73
British Airways 18.86 61.71 -42.84
Brussels Airlines 11.43 75.36 -63.93
Buddha Air 8.33 75.00 -66.67
Bulgaria Air 30.00 45.00 -15.00
Buta Airways 12.50 62.50 -50.00
CSA Czech Airlines 13.54 78.12 -64.58
Camair-Co 0.00 100.00 -100.00
Cambodia Airways 0.00 50.00 -50.00
Cambodia Angkor Air 7.69 73.85 -66.15
Cambodia Bayon Airlines 0.00 100.00 -100.00
Canadian North 66.67 33.33 33.33
Canaryfly 16.67 50.00 -33.33
Cape Air 7.14 92.86 -85.71
Caribbean Airlines 17.50 65.00 -47.50
Cathay Dragon 60.00 20.00 40.00
Cathay Pacific Airways 37.08 42.02 -4.94
Cayman Airways 9.09 81.82 -72.73
Cebu Pacific 15.81 70.36 -54.55
CemAir 20.00 40.00 -20.00
Central Mountain Air 20.00 80.00 -60.00
China Airlines 25.78 44.53 -18.75
China Eastern Airlines 25.60 55.36 -29.76
China Southern Airlines 43.56 26.70 16.86
China United Airlines 0.00 100.00 -100.00
Citilink 18.33 40.00 -21.67
CityJet 34.48 51.72 -17.24
Coastal Aviation 50.00 25.00 25.00
Cobalt 35.71 50.00 -14.29
Comair 13.89 52.78 -38.89
Condor Airlines 15.97 74.79 -58.82
Contour Airlines 0.00 100.00 -100.00
Copa Airlines 12.32 74.64 -62.32
Corendon Airlines 13.51 78.38 -64.86
Corsair 0.00 100.00 -100.00
Croatia Airlines 15.79 57.89 -42.11
Cubana Airlines 7.14 73.81 -66.67
Cyprus Airways 0.00 77.78 -77.78
Danish Air Transport 66.67 33.33 33.33
Darwin Airline 25.00 50.00 -25.00
Delta Air Lines 19.93 70.35 -50.42
Dimonim Air 0.00 0.00 0.00
Discover Airlines 33.33 66.67 -33.33
Dragonair 37.50 31.25 6.25
Druk Air 62.50 12.50 50.00
Dynamic International Airways 0.00 100.00 -100.00
EVA Air 45.95 31.76 14.19
EWA Air 0.00 100.00 -100.00
Eastar Jet 30.77 46.15 -15.38
Eastern Airlines 0.00 100.00 -100.00
Eastern Airways 37.04 59.26 -22.22
Easyfly 28.57 42.86 -14.29
Edelweiss Air 43.33 40.00 3.33
Egyptair 14.17 71.65 -57.48
El Al Israel Airlines 13.43 70.15 -56.72
Ellinair 63.64 27.27 36.36
Emirates 25.40 55.85 -30.45
Ernest Airlines 25.00 75.00 -50.00
Estonian Air 42.86 0.00 42.86
Ethiopian Airlines 15.66 64.46 -48.80
Etihad Airways 15.04 72.37 -57.33
Europe Airpost 100.00 0.00 100.00
Eurowings 8.42 80.00 -71.58
FLYONE 6.25 93.75 -87.50
FMI Air 100.00 0.00 100.00
Far Eastern Air Transport 0.00 100.00 -100.00
Felix Airways 0.00 0.00 0.00
Fiji Airways 25.68 55.41 -29.73
Finnair 26.77 59.06 -32.28
Firefly 35.42 43.75 -8.33
Flair Airlines 13.76 79.92 -66.16
Fly540.com 0.00 83.33 -83.33
FlyArystan 50.00 33.33 16.67
FlySafair 29.03 60.22 -31.18
Flynas 0.00 92.11 -92.11
Freebird Airlines 27.27 54.55 -27.27
French Bee 3.70 92.59 -88.89
Frontier Airlines 6.88 90.34 -83.46
Fuji Dream Airlines 100.00 0.00 100.00
Garuda Indonesia 66.15 20.00 46.15
Georgian Airways 3.33 83.33 -80.00
Germania Airline 0.00 71.43 -71.43
Germanwings 25.86 44.83 -18.97
Go First 2.48 89.26 -86.78
GoAir 6.37 87.26 -80.89
Gol Transportes Aéreos 3.03 51.52 -48.48
Golden Myanmar Airlines 66.67 0.00 66.67
Grand Cru Airlines 100.00 0.00 100.00
Greater Bay Airlines 0.00 100.00 -100.00
Gulf Air 16.46 72.15 -55.70
HK Express 15.56 64.44 -48.89
HOP! 16.67 33.33 -16.67
Hainan Airlines 31.82 34.85 -3.03
Hawaiian Airlines 17.53 68.83 -51.30
Helvetic Airways 29.41 35.29 -5.88
Hi Fly 50.00 33.33 16.67
HiSky 28.57 42.86 -14.29
Himalaya Airlines 0.00 100.00 -100.00
Hong Kong Airlines 11.63 67.44 -55.81
Horizon Air 33.33 16.67 16.67
Hunnu Air 100.00 0.00 100.00
ITA Airways 7.14 89.29 -82.14
Iberia 20.54 62.35 -41.81
Iberia Express 7.84 78.43 -70.59
Icelandair 22.77 62.87 -40.10
IndiGo 35.38 49.54 -14.15
Insel Air 0.00 95.56 -95.56
InterSky 75.00 25.00 50.00
Intercaribbean Airways 14.29 85.71 -71.43
Interjet 4.96 91.49 -86.52
Iran Air 42.86 14.29 28.57
Iran Aseman Airlines 33.33 66.67 -33.33
Island Air 36.36 45.45 -9.09
Israir Airlines 0.00 66.67 -66.67
JC International Airlines 0.00 100.00 -100.00
Japan Airlines 43.02 36.05 6.98
Jazeera Airways 5.26 89.47 -84.21
Jazz 33.33 0.00 33.33
Jeju Air 5.26 68.42 -63.16
Jet Airways 18.93 60.27 -41.33
Jet2.com 49.37 32.28 17.09
JetSmart 18.18 81.82 -63.64
Jetairfly 16.67 66.67 -50.00
Jetblue Airways 11.33 87.08 -75.75
Jetstar Airways 12.92 72.67 -59.75
Jetstar Asia 13.74 66.41 -52.67
Jetstar Japan 5.41 94.59 -89.19
Jetstar Pacific 5.17 81.03 -75.86
JetsuiteX 100.00 0.00 100.00
Jin Air 50.00 28.57 21.43
Joon 0.00 100.00 -100.00
Jordan Aviation 100.00 0.00 100.00
Juneyao Air 10.00 65.00 -55.00
KD Air 0.00 100.00 -100.00
KLM Royal Dutch Airlines 30.86 51.74 -20.88
Kan Air 50.00 50.00 0.00
Kenya Airways 21.60 60.80 -39.20
Kish Airlines 0.00 0.00 0.00
Korean Air 50.83 29.17 21.67
Kulula 13.95 79.07 -65.12
Kuwait Airways 7.14 73.21 -66.07
LAM Mozambique 5.88 88.24 -82.35
LAN Airlines 36.19 36.19 0.00
LAN Colombia 0.00 50.00 -50.00
LAN Peru 0.00 100.00 -100.00
LATAM Airlines 5.92 87.50 -81.58
LC Perú 7.69 69.23 -61.54
LIAT 17.14 65.71 -48.57
LOT Polish Airlines 21.69 63.05 -41.36
La Compagnie 16.67 66.67 -50.00
Lao Airlines 50.00 16.67 33.33
Lao Skyway 35.71 17.86 17.86
Laudamotion 11.54 88.46 -76.92
Level 15.38 79.49 -64.10
Lion Air 3.85 80.77 -76.92
Loganair 41.18 47.06 -5.88
Lubeck Air 100.00 0.00 100.00
Lucky Air 0.00 100.00 -100.00
Lufthansa 25.65 53.15 -27.50
Luxair 31.82 45.45 -13.64
Lynx Air 17.42 77.18 -59.76
MAYAir 0.00 100.00 -100.00
MEGA Maldives Airlines 0.00 100.00 -100.00
MIAT Mongolian Airlines 33.33 50.00 -16.67
Mack Air 100.00 0.00 100.00
Madagasikara Airways 100.00 0.00 100.00
Mahan Air 33.33 33.33 0.00
Malawian Airlines 8.33 66.67 -58.33
Malaysia Airlines 24.30 53.43 -29.13
Maldivian 0.00 66.67 -66.67
Malindo Air 9.20 74.23 -65.03
Mandarin Airlines 0.00 0.00 0.00
Mango Airlines 14.08 80.28 -66.20
Mann Yadanarpon Airlines 50.00 0.00 50.00
Manta Air 100.00 0.00 100.00
Mauritania Airlines 0.00 100.00 -100.00
Maya Island Air 0.00 100.00 -100.00
Meridiana 32.50 45.00 -12.50
Middle East Airlines 25.00 65.00 -40.00
Mihin Lanka 0.00 60.00 -60.00
Mokulele Airlines 20.00 80.00 -60.00
Monarch Airlines 36.73 41.59 -4.87
Montenegro Airlines 16.67 50.00 -33.33
Motor Sich Airlines 33.33 33.33 0.00
Myanmar Airways 50.00 12.50 37.50
Myanmar National Airlines 50.00 12.50 37.50
NAM Air 7.69 53.85 -46.15
NIKI 45.45 27.27 18.18
Nature Air 6.25 87.50 -81.25
Nauru Airlines 100.00 0.00 100.00
Nepal Airlines 14.29 57.14 -42.86
Nile Air 0.00 0.00 0.00
Nok Air 24.55 56.36 -31.82
NokScoot 0.00 50.00 -50.00
NordStar 0.00 0.00 0.00
Nordavia 0.00 50.00 -50.00
Nordic Regional Airlines 0.00 100.00 -100.00
Nordica 50.00 0.00 50.00
Nordwind Airlines 50.00 0.00 50.00
Norse Atlantic Airways 10.26 89.74 -79.49
Norwegian 30.51 57.37 -26.86
Nouvelair 30.00 70.00 -40.00
Novoair 0.00 0.00 0.00
Okay Airways 0.00 100.00 -100.00
Olympic Air 25.64 56.41 -30.77
Oman Air 13.28 67.97 -54.69
Omni Air International 50.00 0.00 50.00
Onur Air 12.90 87.10 -74.19
Openskies 37.50 50.00 -12.50
Orient Thai Airlines 100.00 0.00 100.00
PAL Express 33.33 66.67 -33.33
PAWA Dominicana 0.00 50.00 -50.00
PLAY 35.22 47.17 -11.95
Pacific Airlines 9.09 81.82 -72.73
Pakistan Intl Airlines 6.90 70.69 -63.79
Pan Pacific Airlines 0.00 100.00 -100.00
Passaredo 0.00 100.00 -100.00
Passion Air 0.00 100.00 -100.00
Peach Aviation 24.14 67.24 -43.10
Pegasus Airlines 18.10 71.98 -53.88
PenAir 0.00 66.67 -66.67
Peruvian Airlines 0.00 93.75 -93.75
Petroleum Air Services 50.00 50.00 0.00
Philippine Airlines 21.76 63.82 -42.06
Pobeda Airlines 8.57 88.57 -80.00
Porter Airlines 17.04 79.82 -62.78
Precision Air 7.27 80.00 -72.73
Primera Air 0.00 100.00 -100.00
Privilege Style 60.00 40.00 20.00
Qantas Airways 33.43 46.22 -12.79
QantasLink 34.38 29.69 4.69
Qatar Airways 30.23 46.51 -16.28
Qazaq Air 100.00 0.00 100.00
Ravn Alaska 5.26 94.74 -89.47
Red Wings Airlines 0.00 100.00 -100.00
Regent Airways 12.50 75.00 -62.50
Regional Express 57.58 27.27 30.30
Rex Airlines 77.27 19.70 57.58
Rhein-Neckar Air 100.00 0.00 100.00
Rossiya Airlines 42.86 35.71 7.14
Royal Air Maroc 13.82 78.86 -65.04
Royal Brunei Airlines 57.69 24.36 33.33
Royal Jordanian Airlines 23.88 62.69 -38.81
Rwandair 26.09 65.22 -39.13
Ryanair 24.29 58.65 -34.36
S7 Siberia Airlines 31.25 37.50 -6.25
SA Express 23.53 76.47 -52.94
SAS Scandinavian 16.55 68.07 -51.52
SATA Air Azores 22.89 63.86 -40.96
SATA International 15.56 73.33 -57.78
SATENA 50.00 50.00 0.00
SCAT Airlines 0.00 25.00 -25.00
STARLUX Airlines 0.00 100.00 -100.00
SVG Air 0.00 100.00 -100.00
Safarilink 50.00 0.00 50.00
Safi Airways 0.00 100.00 -100.00
Salam Air 0.00 100.00 -100.00
Sansa Airlines 50.00 50.00 0.00
Santa Barbara Airlines 0.00 33.33 -33.33
Saudi Arabian Airlines 20.59 60.78 -40.20
Scoot 18.62 66.11 -47.49
Seaborne Airlines 6.67 93.33 -86.67
SereneAir 22.22 77.78 -55.56
Shaheen Air 33.33 22.22 11.11
Shandong Airlines 0.00 80.00 -80.00
Shanghai Airlines 0.00 78.57 -78.57
Shenzhen Airlines 0.00 85.71 -85.71
Sichuan Airlines 25.00 62.50 -37.50
SilkAir 22.39 46.27 -23.88
Silver Airways 6.96 90.51 -83.54
Singapore Airlines 40.05 40.82 -0.77
Sky Airline 14.63 78.05 -63.41
Sky Express Airlines 18.84 72.46 -53.62
SkyWest Airlines 25.00 33.33 -8.33
SkyWork Airlines 0.00 50.00 -50.00
Skybus 0.00 100.00 -100.00
Skymark Airlines 50.00 16.67 33.33
Skytrans Airlines 0.00 80.00 -80.00
Small Planet Airlines 47.06 38.24 8.82
SmartLynx Airlines 6.67 80.00 -73.33
SmartWings 8.33 70.83 -62.50
Smartavia 0.00 100.00 -100.00
Solomon Airlines 40.00 40.00 0.00
Somon Air 0.00 100.00 -100.00
South African Airways 20.51 62.39 -41.88
Southern Airways Express 0.00 100.00 -100.00
Southwest Airlines 23.55 70.42 -46.88
SpiceJet 19.27 67.71 -48.44
Spirit Airlines 11.44 84.05 -72.61
Spring Airlines 9.38 59.38 -50.00
SriLankan Airlines 26.45 59.35 -32.90
Sriwijaya Air 15.91 63.64 -47.73
Star Peru 8.33 75.00 -66.67
Sun Country Airlines 17.44 78.49 -61.05
Sun-Air 100.00 0.00 100.00
SunExpress 17.78 71.11 -53.33
Sunwing Airlines 10.16 79.95 -69.79
Super Air Jet 0.00 83.33 -83.33
Surinam Airways 10.00 70.00 -60.00
Swiss Intl Air Lines 27.44 54.88 -27.44
Swoop 15.17 79.40 -64.23
T’Way Air 18.75 68.75 -50.00
TAAG Angola Airlines 0.00 94.12 -94.12
TACA Airlines 33.33 33.33 0.00
TACV Cabo Verde Airlines 18.18 81.82 -63.64
TAG Airlines 18.18 81.82 -63.64
TAM Airlines 12.96 59.26 -46.30
TAME 6.67 86.67 -80.00
TAP Portugal 19.73 68.44 -48.71
TAR Aerolineas 28.57 71.43 -42.86
TAROM Romanian 40.70 39.53 1.16
TUI Airways 26.09 56.52 -30.43
TUIfly 4.35 52.17 -47.83
TUS Airways 50.00 25.00 25.00
Tailwind Airlines 0.00 75.00 -75.00
Tame Línea Aérea Del Ecuador 0.00 100.00 -100.00
Thai AirAsia 20.37 53.70 -33.33
Thai Airways 27.80 46.78 -18.98
Thai Lion Air 11.02 78.81 -67.80
Thai Smile Airways 53.98 24.43 29.55
Thomas Cook Airlines 27.56 55.56 -28.00
Thomas Cook Airlines Scandinavia 100.00 0.00 100.00
Thomson Airways 24.30 50.70 -26.41
Tianjin Airlines 25.00 75.00 -50.00
Tigerair 20.41 50.00 -29.59
Tigerair Australia 11.76 78.43 -66.67
Tigerair Taiwan 28.57 71.43 -42.86
Titan Airways 61.90 28.57 33.33
TransNusa 50.00 50.00 0.00
Transaero Airlines 6.25 62.50 -56.25
Transavia 13.61 74.56 -60.95
Trigana Air 0.00 0.00 0.00
Tropic Air Belize 66.67 33.33 33.33
Tunisair 14.29 60.71 -46.43
Turkish Airlines 16.33 70.32 -53.99
Turkmenistan Airlines 8.33 50.00 -41.67
UP by El Al 0.00 100.00 -100.00
US Airways 17.61 67.96 -50.35
US-Bangla Airlines 12.50 50.00 -37.50
Uganda Airlines 50.00 50.00 0.00
Ukraine International 17.32 66.48 -49.16
Ultra Air 50.00 0.00 50.00
United Airlines 9.01 84.53 -75.51
Ural Airlines 6.67 66.67 -60.00
Utair Aviation 0.00 50.00 -50.00
Uzbekistan Airways 6.25 56.25 -50.00
V Air 33.33 50.00 -16.67
VLM Airlines 50.00 16.67 33.33
Vanilla Air 36.36 54.55 -18.18
ViaAir 0.00 100.00 -100.00
VietJet Air 5.94 82.19 -76.26
Vietnam Airlines 24.23 48.85 -24.62
Virgin America 38.75 52.50 -13.75
Virgin Atlantic 26.84 54.24 -27.40
Virgin Australia 19.36 56.72 -37.36
Vistara 49.57 38.46 11.11
Viva Air 0.00 100.00 -100.00
VivaAerobús 4.08 89.80 -85.71
VivaColombia 6.67 90.00 -83.33
Volaris 5.22 91.79 -86.57
Volotea 38.37 46.12 -7.75
Voyage Air 0.00 100.00 -100.00
Vueling Airlines 10.51 79.69 -69.19
WOW air 15.04 75.49 -60.45
Wamos Air 50.00 50.00 0.00
WestJet Airlines 16.32 78.87 -62.55
Wideroe 21.43 71.43 -50.00
Winair 0.00 77.78 -77.78
Wingo 4.76 90.48 -85.71
Wings Air 4.35 73.91 -69.57
Wizz Air 12.99 76.15 -63.16
World2Fly 0.00 100.00 -100.00
XL Airways France 30.00 55.00 -25.00
Xiamen Airlines 6.90 79.31 -72.41
Yakutia Airlines 0.00 100.00 -100.00
Yangon Airways 0.00 0.00 0.00
Yeti Airlines 0.00 60.00 -60.00
ZIPAIR 12.50 82.50 -70.00
Zambia Airways 0.00 50.00 -50.00
airBaltic 16.79 67.88 -51.09
airblue 23.53 64.71 -41.18
bmi Regional 19.05 73.81 -54.76
easyJet 28.20 56.49 -28.29
euroAtlantic Airways 0.00 100.00 -100.00
fastjet 29.63 66.67 -37.04
flyadeal 5.88 94.12 -88.24
flybe 50.00 50.00 0.00
flybondi 0.00 100.00 -100.00
flydubai 15.38 76.92 -61.54

Plots:

1. CSI % by airline (top/bottom):

Here I will showcase the top 20 airlines according to the CSI

aggregates_by_airline <- df_cleaned %>%
  group_by(Airline_Name) %>%
  summarise(
    Avg_CSI      = mean(CSI_Percentage, na.rm = TRUE),
    Avg_Onboard  = mean(Onboard_Percentage, na.rm = TRUE),
    Avg_Ground   = mean(Ground_Percentage, na.rm = TRUE),
    .groups = "drop"
)
# use aggregates_by_airline from earlier
top20_csi <- aggregates_by_airline %>%
  arrange(desc(Avg_CSI)) %>%
  slice_head(n = 20)

ggplot(top20_csi, aes(x = reorder(Airline_Name, Avg_CSI), y = Avg_CSI)) +
  geom_col(fill = "steelblue") +
  coord_flip() +
  labs(x = "Airline",
       y = "Average CSI (%)",
       title = "Top 20 airlines by Customer Satisfaction Index")

2. Onboard vs ground satisfaction:

ggplot(aggregates_by_airline,
       aes(x = Avg_Onboard, y = Avg_Ground)) +
  geom_point(alpha = 0.6) +
  labs(x = "Onboard satisfaction (%)",
       y = "Ground & wifi satisfaction (%)",
       title = "Onboard vs ground experience by airline") +
  geom_hline(yintercept = mean(aggregates_by_airline$Avg_Ground), linetype = "dashed") +
  geom_vline(xintercept = mean(aggregates_by_airline$Avg_Onboard), linetype = "dashed")

3. Top 50 NPS per Airline:

The NPS bar plot for the top 20 airlines shows how strongly each airline’s customers would recommend it, based on the balance of promoters and detractors.

What the plot displays Each bar is one airline, ordered from highest to lowest NPS. The height of the bar (NPS) is computed as: Positive bars (above zero) mean that more customers are promoters than detractors; negative bars mean the opposite.

top20_nps <- nps_by_airline %>%
  arrange(desc(NPS)) %>%
  slice_head(n = 50)

ggplot(top20_nps,
       aes(x = reorder(Airline_Name, NPS), y = NPS)) +
  geom_col(fill = "darkgreen") +
  coord_flip() +
  labs(x = "Airline",
       y = "NPS (promoters − detractors, % points)",
       title = "Top 20 airlines by NPS")

4. Distribution of Customer satisfaction:

ggplot(df_cleaned, aes(x = CSI_Percentage)) +
  geom_histogram(binwidth = 5, fill = "skyblue", color = "white") +
  labs(x = "CSI (%)",
       y = "Number of passengers",
       title = "Distribution of customer satisfaction scores")

These results show that customer satisfaction varies widely by airline, with clear groups of strong, average, and weak performers when using your CSI and sub-indices in percent. Overall level and spread - Many airlines cluster roughly between 40–60% CSI, which indicates moderate satisfaction (customers neither very happy nor very unhappy on average). - A sizeable number achieve CSI above 70–80% (e.g. Air Costa 80%, Air North Yukon’s Airline 81.43%, Air Rarotonga 89.52%, Grand Cru Airlines 91.43%), which signals very strong perceived experience and loyalty potential. - At the low end, some carriers are below 35% CSI (e.g. AirConnect 14.29%, Openskies 14.29%, Andes Líneas Aéreas 23.57%), pointing to serious service or perception issues. Onboard vs ground experience Looking at CSI_Percentage against Onboard_Percentage and Ground_Percentage: - For many airlines, Onboard_Percentage is noticeably higher than Ground_Percentage, meaning passengers are relatively more satisfied with in‑flight service (seats, crew, food, inflight experience) than with ground or connectivity aspects (check‑in, boarding, wifi). - Examples: Cathay Pacific Airways (Onboard 70.48% vs Ground 31.51%), Emirates (65.92% vs 31.93%), Air Transat (54.31% vs 33.26%). - Some airlines have balanced or even better ground scores, which is rarer and can be positioned as a differentiator (e.g. QantasLink 55.47% onboard vs 61.25% ground, SkyWest Airlines 58.75% vs 65%). - High‑CSI airlines typically have both onboard and ground above ~60–65%; where one dimension lags, overall CSI drops, even if the other is strong. High-CSI airlines: strengths - Airlines like Air Costa, Air Rarotonga, Air Iceland Connect, BA CityFlyer, Druk Air, Garuda Indonesia, Grand Cru Airlines, JetsuiteX, Hunnu Air, Nauru Airlines, Rex Airlines, Rhein‑Neckar Air, Sun‑Air, etc. show CSI often above 75–80% with very high Onboard_Percentage (often 85–100%). - These carriers usually also have solid Ground_Percentage (often 60–70%), suggesting a consistently strong end‑to‑end experience (check‑in, punctuality, comfort, and staff interactions). - In a marketing context, they can be benchmark “best practice” examples and used in your report as proof that high satisfaction is achievable. Low-CSI airlines: weaknesses - Airlines in the 20–40% CSI range often show either: - Weak onboard and ground simultaneously (e.g. AirConnect 0% onboard, 50% ground; Openskies 8.75% onboard, 30% ground), or - Reasonable onboard but very weak ground, dragging CSI down (e.g. some long‑haul or low‑cost operators with good cabin but poor ground or wifi). - For these airlines, marketing and operations should focus on: - Fixing basic pain points first (delays, baggage, check‑in, call centres). - Clarifying service promises in campaigns so expectations and reality align, reducing dissatisfaction caused by “over‑promising”.