Data yang digunakan dalam analsis R ini didapatkan dari situs Kaggle, berisi data pemesanan penerbangan yang diperoleh dari situs web “Ease My Trip”. Selanjutnya, saya akan menganalisis pola harga tiket penerbangan dengan fokus pada identifikasi harga ekstrem (outlier) dan faktor-faktor yang memengaruhinya. Selanjutnya, sebaran harga juga akan diperiksa untuk memahami apakah distribusinya normal atau condong ke satu sisi (skewed), sehingga pendekatan analisis yang digunakan dapat lebih sesuai dengan karakteristik datanya.
# Memasukkan data ke data frame bernama data_penerbangan
data_penerbangan <- read.csv("D:/Documents/Downloads/archive/Clean_Dataset.csv",
colClasses = c("X" = "NULL"))
# Menampilkan beberapa data awal dari data_penerbangan
head(data_penerbangan)
## airline flight source_city departure_time stops arrival_time
## 1 SpiceJet SG-8709 Delhi Evening zero Night
## 2 SpiceJet SG-8157 Delhi Early_Morning zero Morning
## 3 AirAsia I5-764 Delhi Early_Morning zero Early_Morning
## 4 Vistara UK-995 Delhi Morning zero Afternoon
## 5 Vistara UK-963 Delhi Morning zero Morning
## 6 Vistara UK-945 Delhi Morning zero Afternoon
## destination_city class duration days_left price
## 1 Mumbai Economy 2.17 1 5953
## 2 Mumbai Economy 2.33 1 5953
## 3 Mumbai Economy 2.17 1 5956
## 4 Mumbai Economy 2.25 1 5955
## 5 Mumbai Economy 2.33 1 5955
## 6 Mumbai Economy 2.33 1 5955
str(data_penerbangan) # untuk melihat tipe data setiap variabel
## 'data.frame': 300153 obs. of 11 variables:
## $ airline : chr "SpiceJet" "SpiceJet" "AirAsia" "Vistara" ...
## $ flight : chr "SG-8709" "SG-8157" "I5-764" "UK-995" ...
## $ source_city : chr "Delhi" "Delhi" "Delhi" "Delhi" ...
## $ departure_time : chr "Evening" "Early_Morning" "Early_Morning" "Morning" ...
## $ stops : chr "zero" "zero" "zero" "zero" ...
## $ arrival_time : chr "Night" "Morning" "Early_Morning" "Afternoon" ...
## $ destination_city: chr "Mumbai" "Mumbai" "Mumbai" "Mumbai" ...
## $ class : chr "Economy" "Economy" "Economy" "Economy" ...
## $ duration : num 2.17 2.33 2.17 2.25 2.33 2.33 2.08 2.17 2.17 2.25 ...
## $ days_left : int 1 1 1 1 1 1 1 1 1 1 ...
## $ price : int 5953 5953 5956 5955 5955 5955 6060 6060 5954 5954 ...
sum(is.na(data_penerbangan)) # untuk mengecek apakah ada missing value pada tiap variabel
## [1] 0
library(dplyr) # Memasukkan library yang diperlukan
## Warning: package 'dplyr' was built under R version 4.4.2
##
## 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
# Menentukan ukuran pemusatan untuk masing-masing variabel
ukuran_pemusatan <- list(
airline = names(which.max(table(data_penerbangan$airline))), # Modus untuk data kategorik
flight = names(which.max(table(data_penerbangan$flight))), # Modus untuk data kategorik
source_city = names(which.max(table(data_penerbangan$source_city))), # Modus untuk data kategorik
departure_time = names(which.max(table(data_penerbangan$departure_time))), # Modus untuk data kategorik
stops = names(which.max(table(data_penerbangan$stops))), # Modus untuk data kategorik
arrival_time = names(which.max(table(data_penerbangan$arrival_time))), # Modus untuk data kategorik
destination_city = names(which.max(table(data_penerbangan$destination_city))), # Modus untuk data kategorik
class = names(which.max(table(data_penerbangan$class))), # Modus untuk data kategorik
duration = mean(data_penerbangan$duration, na.rm = TRUE), # Mean untuk data numerik
days_left = median(data_penerbangan$days_left, na.rm = TRUE), # Median untuk data integer
price = mean(data_penerbangan$price, na.rm = TRUE) # Mean untuk data numerik
)
# Menampilkan hasil ukuran pemusatan
print(ukuran_pemusatan)
## $airline
## [1] "Vistara"
##
## $flight
## [1] "UK-706"
##
## $source_city
## [1] "Delhi"
##
## $departure_time
## [1] "Morning"
##
## $stops
## [1] "one"
##
## $arrival_time
## [1] "Night"
##
## $destination_city
## [1] "Mumbai"
##
## $class
## [1] "Economy"
##
## $duration
## [1] 12.22102
##
## $days_left
## [1] 26
##
## $price
## [1] 20889.66
Berdasarkan hasil analisis ukuran pemusatan data di atas, mayoritas penerbangan dalam berasal dari Delhi dan menuju Mumbai, dengan maskapai yang paling sering dipakai adalah Vistara dengan nomor penerbangan yang paling umum adalah UK-706. Waktu keberangkatan yang paling sering terjadi adalah pagi hari, sementara waktu kedatangan yang dominan adalah malam hari. Sebagian besar penerbangan memiliki satu kali transit dan kelas penerbangan yang paling umum adalah ekonomi. Untuk variabel numerik, rata-rata durasi penerbangan adalah 12,22 jam, dengan jumlah hari tersisa sebelum keberangkatan memiliki nilai median 26 hari, serta harga tiket rata-rata sebesar 20.889,66 INR.
# Membuat histogram untuk mengecek distribusi sebaran Harga tiket
hist (data_penerbangan$price,
main = "Distribusi Harga Tiket",
xlab = "Harga (INR)",
col = 'skyblue')
Histogram “Distribusi Harga Tiket” di atas menunjukkan bahwa harga tiket pesawat memiliki distribusi right-skewed (menjulur ke kanan), di mana mayoritas harga tiket berada di kisaran 0 - 20.000 INR. Namun, terdapat beberapa kelompok harga yang lebih tinggi, bahkan hingga lebih dari 80.000 INR, yang kemungkinan besar merupakan outlier atau tiket kelas premium. Pola ini mengindikasikan adanya variasi harga yang cukup besar, yang mungkin dipengaruhi oleh beberapa faktor seperti maskapai, kelas penerbangan, jumlah hari sebelum keberangkatan, dan rute penerbangan.Selanjutnya akan diperiksa keberadaan nilai ekstrim pada kolom Harga di data_penerbangan.
# Load library yang diperlukan
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.4.2
# Boxplot dengan highlight pencilan
ggplot(data_penerbangan, aes(y = price)) +
geom_boxplot(fill = "lightgreen", outlier.color = "red", outlier.shape = 16, outlier.size = 3) +
labs(title = "Boxplot Harga Tiket", y = "Harga (INR)") +
theme_minimal()
Boxplot di atas menunjukkan “Distribusi Harga Tiket” dalam satuan INR. Dari visualisasi ini, terlihat bahwa mayoritas data harga tiket berada pada rentang yang relatif rendah, dengan median harga berada di bagian bawah kotak. Namun, terdapat banyak outlier di bagian atas (harga tinggi), yang menunjukkan adanya tiket dengan harga jauh lebih mahal dibandingkan mayoritas tiket lainnya. Hal ini dapat mengindikasikan bahwa sebagian kecil tiket dijual dengan harga premium atau terdapat variasi harga yang signifikan,
# Load library
library(moments)
# Hitung skewness dan kurtosis
skewness_value <- skewness(data_penerbangan$price, na.rm = TRUE)
kurtosis_value <- kurtosis(data_penerbangan$price, na.rm = TRUE)
# Print hasil
cat("Skewness:", skewness_value, "\n")
## Skewness: 1.061372
cat("Kurtosis:", kurtosis_value, "\n")
## Kurtosis: 2.603694
Berdasarkan nilai skewness sebesar 1.061372 > 0, distribusi harga tiket penerbangan menunjukkan kemenjuluran ke kanan (right-skewed), yang berarti mayoritas harga tiket cenderung berada di kisaran yang lebih rendah, sementara ada sejumlah kecil tiket dengan harga yang jauh lebih tinggi. Hal ini sejalan dengan visualisasi histogram sebelumnya, di mana sebagian besar tiket berkumpul di rentang harga rendah, tetapi terdapat ekor panjang ke arah harga yang lebih mahal. Sementara itu, nilai kurtosis 2.603694 < 3, menunjukkan bahwa distribusi harga tiket memiliki puncak yang lebih rendah dibandingkan distribusi normal (mesokurtik), tetapi tidak terlalu ekstrem. Kondisi ini mengindikasikan adanya variasi harga yang cukup besar.
#Membuat QQ plot untuk memeriksa apakah data mengikuti distribusi normal
qqnorm(data_penerbangan$price, main="QQ Plot Harga Tiket", col="blue")
qqline(data_penerbangan$price, col="red", lwd=2)
Berdasarkan QQ Plot Harga Tiket, terlihat bahwa distribusi harga tiket menyimpang secara signifikan dari distribusi normal. Pada bagian ekor kiri dan kanan, titik-titik data jauh dari garis referensi (garis merah), menunjukkan adanya skewness positif yang cukup kuat, sebagaimana juga terlihat pada histogram sebelumnya. Selain itu, terdapat banyak titik yang berada di luar pola garis normal, yang mengindikasikan keberadaan outlier pada harga tiket. Dengan demikian, pendekatan analisis yang lebih robust dapat dilakukan.
median_value <- median(data_penerbangan$price) # Menghitung median
mad_value <- median(abs(data_penerbangan$price - median_value)) # Menghitung MAD (Median Absolute Deviation)
z_robust <- 0.6745 * (data_penerbangan$price - median_value) / mad_value # Menghitung robust Z-score dengan faktor 0.6745
outliers <- data_penerbangan$price[abs(z_robust) > 3.5] # Menentukan pencilan (|z_robust| > 3.5)
head(outliers) # Menampilkan beberapa data pencilan
## [1] 29580 29160 29580 29580 31260 28058
summary(outliers) # Melihat ringkasan dari data Outliers
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 27828 45883 53743 53912 60508 123071
Harga tiket yang termasuk kategori outlier memiliki rentang yang cukup besar, mulai dari INR 27.828 hingga INR 123.071. Nah, selanjutnya saya tertarik untuk melihat variabel mana saja yang memiliki kontribusi terbesar terhadap harga tiket yang termasuk outliers (selanjutnya akan disebut sebagai tiket dengan harga mahal).
airline_mahal <- data_penerbangan[data_penerbangan$price >= min(outliers), "airline"]
table(airline_mahal) # Menghitung jumlah outlier per maskapai
## airline_mahal
## Air_India AirAsia GO_FIRST Indigo SpiceJet Vistara
## 30820 11 14 14 1 58603
source_city_mahal <- data_penerbangan[data_penerbangan$price >= min(outliers), "source_city"]
table(source_city_mahal) # Menghitung jumlah outlier per asal kota keberangkatan
## source_city_mahal
## Bangalore Chennai Delhi Hyderabad Kolkata Mumbai
## 15988 11939 17440 12225 13361 18510
departure_time_mahal <- data_penerbangan[data_penerbangan$price >= min(outliers), "departure_time"]
table(departure_time_mahal) # Menghitung jumlah outlier waktu berangkat
## departure_time_mahal
## Afternoon Early_Morning Evening Late_Night Morning
## 12042 19170 19907 120 21457
## Night
## 16767
stops_mahal <- data_penerbangan[data_penerbangan$price >= min(outliers), "stops"]
table(stops_mahal) # Menghitung jumlah outlier per jumlah pemberhentian
## stops_mahal
## one two_or_more zero
## 84208 1111 4144
arrival_time_mahal <- data_penerbangan[data_penerbangan$price >= min(outliers), "arrival_time"]
table(arrival_time_mahal) # Menghitung jumlah outlier per waktu tiba
## arrival_time_mahal
## Afternoon Early_Morning Evening Late_Night Morning
## 10398 3342 25690 1780 20441
## Night
## 27812
destination_city_mahal <- data_penerbangan[data_penerbangan$price >= min(outliers), "destination_city"]
table(destination_city_mahal) # Menghitung jumlah outlier per kota tujuan
## destination_city_mahal
## Bangalore Chennai Delhi Hyderabad Kolkata Mumbai
## 15783 12853 15545 12958 14647 17677
class_mahal <- data_penerbangan[data_penerbangan$price >= min(outliers), "class"]
table(class_mahal) # Menghitung jumlah outlier per kelas
## class_mahal
## Business Economy
## 89307 156
duration <- cut(data_penerbangan$duration,
breaks = seq(0, max(data_penerbangan$duration), by = 4),
include.lowest = TRUE, right = FALSE) # Mengelompokkan durasi terbang per 4 jam
duration_mahal <- duration[data_penerbangan$price >= min(outliers)]
table(duration_mahal) # Menghitung jumlah outlier per kelas
## duration_mahal
## [0,4) [4,8) [8,12) [12,16) [16,20) [20,24) [24,28) [28,32) [32,36) [36,40)
## 4169 11290 19047 24269 11306 9674 8547 1068 80 7
## [40,44) [44,48]
## 3 3
days_left <- cut(data_penerbangan$days_left,
breaks = seq(0, max(data_penerbangan$days_left), by = 7),
include.lowest = TRUE, right = FALSE)
days_left_mahal <- days_left[data_penerbangan$price >= min(outliers)]
table(days_left_mahal) # Menghitung jumlah outlier per hari sebelum keberangkatan
## days_left_mahal
## [0,7) [7,14) [14,21) [21,28) [28,35) [35,42) [42,49]
## 8359 13205 13218 13357 13380 13305 14639
Tiket penerbangan yang masuk kategori mahal didominasi oleh maskapai Vistara (58.603 tiket) dan Air India (30.820 tiket), dengan mayoritas berasal dari kelas bisnis (89.307 tiket). Tiket mahal lebih sering ditemukan pada penerbangan one-stop (84.208 tiket), dengan durasi 12-16 jam (24.269 tiket), serta paling banyak terjadi pada waktu keberangkatan pagi (21.457 tiket) dengan waktu kedatangan malam (27.812 tiket). Penerbangan dari dan menuju kota besar juga memengaruhi harga tiket, dengan Kota Mumbai sebagai kota keberangkatan (18.510 tiket) dan kota tujuan (17.677 tiket) jumlah tiket mahal terbanyak.