Struktur Data

Struktur data digunakan untuk mengidentifikasi karakteristik awal dataset sebelum dilakukan analisis lebih lanjut. Pemahaman terhadap struktur data sangat penting karena membantu memastikan bahwa proses pembersihan data, pemilihan variabel, serta penerapan metode analisis statistik dilakukan secara tepat dan sesuai dengan jenis serta kondisi data yang digunakan.

Pada bagian ini, dataset Titanic-Dataset.csv dibaca dan dimasukkan ke dalam R sebagai objek df. Selanjutnya, fungsi head(df) digunakan untuk menampilkan enam baris pertama data. Langkah ini bertujuan untuk melihat gambaran awal dataset, termasuk struktur data, jenis variabel, serta contoh nilai yang terdapat pada setiap kolom sebelum dilakukan analisis lebih lanjut.

df <- read.csv("Titanic-Dataset.csv")
head(df)
##   PassengerId Survived Pclass
## 1           1        0      3
## 2           2        1      1
## 3           3        1      3
## 4           4        1      1
## 5           5        0      3
## 6           6        0      3
##                                                  Name    Sex Age SibSp Parch
## 1                             Braund, Mr. Owen Harris   male  22     1     0
## 2 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female  38     1     0
## 3                              Heikkinen, Miss. Laina female  26     0     0
## 4        Futrelle, Mrs. Jacques Heath (Lily May Peel) female  35     1     0
## 5                            Allen, Mr. William Henry   male  35     0     0
## 6                                    Moran, Mr. James   male  NA     0     0
##             Ticket    Fare Cabin Embarked
## 1        A/5 21171  7.2500              S
## 2         PC 17599 71.2833   C85        C
## 3 STON/O2. 3101282  7.9250              S
## 4           113803 53.1000  C123        S
## 5           373450  8.0500              S
## 6           330877  8.4583              Q

Fungsi dim() untuk mengetahui ukuran data secara singkat, yaitu jumlah baris dan kolom dalam bentuk (baris, kolom)

dim(df)
## [1] 891  12

Fungsi str() untuk menampilkan struktur internal suatu dataset, seperti jumlah baris dan kolom, serta tipe data setiap variabel

str(df)
## 'data.frame':    891 obs. of  12 variables:
##  $ PassengerId: int  1 2 3 4 5 6 7 8 9 10 ...
##  $ Survived   : int  0 1 1 1 0 0 0 0 1 1 ...
##  $ Pclass     : int  3 1 3 1 3 3 1 3 3 2 ...
##  $ Name       : chr  "Braund, Mr. Owen Harris" "Cumings, Mrs. John Bradley (Florence Briggs Thayer)" "Heikkinen, Miss. Laina" "Futrelle, Mrs. Jacques Heath (Lily May Peel)" ...
##  $ Sex        : chr  "male" "female" "female" "female" ...
##  $ Age        : num  22 38 26 35 35 NA 54 2 27 14 ...
##  $ SibSp      : int  1 1 0 1 0 0 0 3 0 1 ...
##  $ Parch      : int  0 0 0 0 0 0 0 1 2 0 ...
##  $ Ticket     : chr  "A/5 21171" "PC 17599" "STON/O2. 3101282" "113803" ...
##  $ Fare       : num  7.25 71.28 7.92 53.1 8.05 ...
##  $ Cabin      : chr  "" "C85" "" "C123" ...
##  $ Embarked   : chr  "S" "C" "S" "S" ...

Kode colSums(is.na(df)) digunakan untuk menghitung dan menampilkan jumlah nilai yang hilang (NA) pada setiap kolom di dalam data

colSums(is.na(df))
## PassengerId    Survived      Pclass        Name         Sex         Age 
##           0           0           0           0           0         177 
##       SibSp       Parch      Ticket        Fare       Cabin    Embarked 
##           0           0           0           0           0           0
data_selected <- df[, c("Age", "SibSp", "Parch", "Fare")]
str(data_selected)
## 'data.frame':    891 obs. of  4 variables:
##  $ Age  : num  22 38 26 35 35 NA 54 2 27 14 ...
##  $ SibSp: int  1 1 0 1 0 0 0 3 0 1 ...
##  $ Parch: int  0 0 0 0 0 0 0 1 2 0 ...
##  $ Fare : num  7.25 71.28 7.92 53.1 8.05 ...

Data Cleaning

Proses data cleaning dilakukan dengan memilih variabel Age, SibSp, Parch, dan Fare. Baris data yang mengandung nilai hilang (missing value) pada variabel-variabel tersebut dihapus menggunakan fungsi na.omit(). Setelah itu, setiap variabel diubah ke tipe numerik melalui lapply(as.numeric) agar seluruh data dapat diproses oleh metode statistik, seperti perhitungan korelasi, matriks varians–kovarians, serta analisis eigen. Diperoleh sebanyak 714 observasi yang lengkap dan siap digunakan untuk analisis lanjutan.

data_clean <- na.omit(data_selected)
data_clean <- data.frame(lapply(data_clean, as.numeric))
dim(data_clean)
## [1] 714   4
head(df)
##   PassengerId Survived Pclass
## 1           1        0      3
## 2           2        1      1
## 3           3        1      3
## 4           4        1      1
## 5           5        0      3
## 6           6        0      3
##                                                  Name    Sex Age SibSp Parch
## 1                             Braund, Mr. Owen Harris   male  22     1     0
## 2 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female  38     1     0
## 3                              Heikkinen, Miss. Laina female  26     0     0
## 4        Futrelle, Mrs. Jacques Heath (Lily May Peel) female  35     1     0
## 5                            Allen, Mr. William Henry   male  35     0     0
## 6                                    Moran, Mr. James   male  NA     0     0
##             Ticket    Fare Cabin Embarked
## 1        A/5 21171  7.2500              S
## 2         PC 17599 71.2833   C85        C
## 3 STON/O2. 3101282  7.9250              S
## 4           113803 53.1000  C123        S
## 5           373450  8.0500              S
## 6           330877  8.4583              Q

Data Distribusi dan Visualisasi

Visualisasi data dilakukan dengan menggunakan histogram guna melihat bentuk distribusi serta penyebaran nilai pada setiap variabel numerik yang dianalisis, yaitu Age, SibSp, Parch, dan Fare. Melalui grafik tersebut, karakteristik awal data dapat diamati sehingga memudahkan pemahaman sebelum dilakukan analisis statistik lanjutan.

par(mfrow = c(2, 2), mar = c(4, 4, 2, 1))

hist(data_clean$Age,
     main = "Distribution of Age",
     xlab = "Age",
     col = "lightblue")

hist(data_clean$SibSp,
     main = "Distribution of SibSp",
     xlab = "SibSp",
     col = "lightgreen")

hist(data_clean$Parch,
     main = "Distribution of Parch",
     xlab = "Parch",
     col = "lightpink")

hist(data_clean$Fare,
     main = "Distribution of Fare",
     xlab = "Fare",
     col = "khaki")

par(mfrow = c(1, 1))

Histogram Age memperlihatkan bahwa konsentrasi penumpang paling banyak berada pada kisaran usia sekitar 20–40 tahun, dengan puncak frekuensi pada kelompok dewasa muda. Bentuk sebarannya tidak simetris dan cenderung miring ke kanan (right-skewed), karena jumlah penumpang berusia lanjut jauh lebih sedikit dibandingkan usia produktif. Hal ini menunjukkan bahwa komposisi penumpang Titanic didominasi individu usia dewasa. Analisis distribusi usia ini penting untuk memahami karakteristik demografis penumpang sebelum dilakukan analisis lanjutan, misalnya pengaruh usia terhadap peluang keselamatan.

Variabel SibSp menunjukkan bahwa sebagian besar nilai berada pada 0 dan 1. Artinya, mayoritas penumpang melakukan perjalanan sendiri atau hanya bersama satu saudara/pasangan. Nilai yang lebih besar dari 1 muncul sangat jarang sehingga distribusinya sangat tidak seimbang dan condong ke kanan. Pemeriksaan distribusi ini bertujuan melihat pola perjalanan penumpang (sendiri atau berkeluarga) yang nantinya dapat dikaitkan dengan perilaku evakuasi maupun tingkat keselamatan.

Histogram Parch memperlihatkan pola yang hampir sama dengan SibSp. Sebagian besar penumpang memiliki nilai 0, yang berarti tidak membawa orang tua ataupun anak. Nilai di atas 1 hanya muncul pada sedikit observasi sehingga distribusinya juga right-skewed dan didominasi nilai kecil. Informasi ini membantu mengidentifikasi apakah keberadaan anggota keluarga (orang tua/anak) berpotensi memengaruhi variabel lain pada analisis multivariat.

Sementara itu, variabel Fare memiliki sebaran yang sangat tidak merata dengan kemencengan kanan yang kuat. Kebanyakan penumpang membayar tarif rendah, sedangkan hanya sebagian kecil yang membayar tiket sangat mahal hingga ratusan. Pola tersebut mencerminkan adanya perbedaan kelas kabin dan fasilitas yang signifikan di kapal. Analisis distribusi harga tiket diperlukan untuk mengetahui variasi ekonomi penumpang serta sebagai dasar pemeriksaan asumsi statistik (misalnya normalitas) sebelum dilakukan analisis korelasi atau pemodelan.

Correlation Matrix

Digunakan untuk mengukur kekuatan dan arah hubungan linier antarvariabel numerik yang dianalisis. Variabel yang diamati meliputi Age, SibSp, Parch, dan Fare. Data yang dipakai merupakan data hasil cleaning (tanpa missing value dan seluruh variabel sudah bertipe numerik), sehingga perhitungan korelasi dapat merepresentasikan hubungan yang lebih tepat.

cor_matrix <- cor(data_clean)
cor_matrix
##               Age      SibSp      Parch       Fare
## Age    1.00000000 -0.3082468 -0.1891193 0.09606669
## SibSp -0.30824676  1.0000000  0.3838199 0.13832879
## Parch -0.18911926  0.3838199  1.0000000 0.20511888
## Fare   0.09606669  0.1383288  0.2051189 1.00000000

Hasil perhitungan menunjukkan bahwa Age dan SibSp memiliki korelasi negatif sebesar −0,308. Artinya, semakin tinggi usia penumpang, kecenderungannya jumlah saudara atau pasangan yang ikut bepergian semakin sedikit. Besarnya hubungan ini tergolong lemah–sedang.

Hubungan paling kuat terlihat pada pasangan SibSp dan Parch dengan nilai korelasi positif sebesar 0,384. Hal ini mengindikasikan bahwa penumpang yang melakukan perjalanan bersama saudara atau pasangan umumnya juga membawa orang tua maupun anak, sehingga kedua variabel tersebut berkaitan dengan komposisi keluarga.

Sementara itu, korelasi antara Fare dengan variabel lainnya relatif kecil (mendekati nol). Dengan demikian, harga tiket tidak menunjukkan keterkaitan linier yang berarti terhadap usia maupun jumlah anggota keluarga, sehingga besar kemungkinan dipengaruhi oleh faktor lain seperti kelas kabin.

library(corrplot)
## corrplot 0.95 loaded
corrplot(
  cor_matrix,
  method = "color",
  type = "upper",
  addCoef.col = "black",
  number.cex = 0.9,
  tl.col = "black",
  tl.srt = 45
)

Variance-Covariance Matrix

Digunakan untuk mengetahui tingkat keragaman setiap variabel (variance) serta arah hubungan antarvariabel (covariance) dalam satuan data aslinya.

cov_matrix <- cov(data_clean)
cov_matrix
##              Age      SibSp      Parch        Fare
## Age   211.019125 -4.1633339 -2.3441911   73.849030
## SibSp  -4.163334  0.8644973  0.3045128    6.806212
## Parch  -2.344191  0.3045128  0.7281027    9.262176
## Fare   73.849030  6.8062117  9.2621760 2800.413100

Berdasarkan hasil tersebut, variabel Fare memiliki varians paling besar, yang berarti harga tiket antarpenumpang memiliki tingkat perbedaan yang sangat tinggi. Kondisi ini sejalan dengan hasil visualisasi histogram yang memperlihatkan sebaran harga tiket yang sangat lebar.

Sebaliknya, variabel SibSp dan Parch memiliki varians yang relatif kecil. Hal ini menunjukkan bahwa jumlah saudara/pasangan serta orang tua/anak yang dibawa penumpang tidak banyak bervariasi dan sebagian besar berada pada nilai rendah.

Nilai di luar diagonal merupakan kovarians yang menunjukkan arah hubungan antarvariabel. Kovarians antara SibSp dan Parch bernilai positif, yang mengindikasikan bahwa penumpang yang membawa saudara atau pasangan cenderung juga membawa orang tua atau anak. Sementara itu, kovarians antara Age dan SibSp bernilai negatif, yang berarti semakin tinggi usia penumpang, semakin kecil jumlah saudara atau pasangan yang ikut bepergian.

Eigen Value

Eigen value dalam analisis multivariat, khususnya pada Principal Component Analysis (PCA), digunakan untuk menunjukkan seberapa besar variasi atau informasi data yang mampu dijelaskan oleh setiap komponen utama yang terbentuk dari penggabungan beberapa variabel. Nilai eigenvalue diperoleh dari matriks varians–kovarians (atau matriks korelasi) dan berfungsi sebagai dasar untuk menentukan komponen mana yang penting untuk dipertahankan. Semakin besar nilai eigenvalue, semakin besar pula keragaman data yang dapat dijelaskan oleh komponen tersebut, sedangkan eigenvalue yang kecil menunjukkan kontribusi informasi yang rendah.

eigen_result <- eigen(cov_matrix)
eigen_values <- eigen_result$values
eigen_values
## [1] 2802.5636587  209.0385659    0.9438783    0.4787214

Komponen PC1 memiliki eigenvalue paling besar (2802,56) dengan proporsi variansi 0,9301 atau sekitar 93,01%. Artinya, hampir seluruh keragaman data dari variabel Age, SibSp, Parch, dan Fare sudah dapat diringkas hanya oleh satu komponen saja. Dengan kata lain, satu kombinasi variabel baru (PC1) sudah mampu mewakili sebagian besar karakteristik data asli.

Komponen PC2 memiliki proporsi variansi 0,0694 (±6,94%). Ketika digabungkan dengan PC1, nilai kumulatifnya menjadi 0,9995 atau sekitar 99,95%. Ini berarti dua komponen pertama saja sudah hampir sepenuhnya mewakili informasi dalam dataset, sehingga penggunaan lebih dari dua komponen sebenarnya tidak terlalu diperlukan.

Sementara itu, PC3 dan PC4 hanya menambahkan variansi yang sangat kecil (kurang dari 0,05%). Kontribusinya terhadap penjelasan variasi data hampir tidak signifikan, sehingga kedua komponen ini biasanya diabaikan dalam analisis.

eigen_table <- data.frame(
  Komponen = paste0("PC", 1:length(eigen_result$values)),
  Eigen_Value = eigen_result$values,
  Proporsi_Variansi = eigen_result$values / sum(eigen_result$values),
  Kumulatif = cumsum(eigen_result$values / sum(eigen_result$values))
)
eigen_table[, -1] <- round(eigen_table[, -1], 4)

knitr::kable(
  eigen_table,
  caption = "Tabel Eigen Value "
)
Tabel Eigen Value
Komponen Eigen_Value Proporsi_Variansi Kumulatif
PC1 2802.5637 0.9301 0.9301
PC2 209.0386 0.0694 0.9995
PC3 0.9439 0.0003 0.9998
PC4 0.4787 0.0002 1.0000

Scree Plot, yaitu grafik yang menampilkan nilai eigenvalue untuk setiap komponen utama (PC1, PC2, PC3, PC4) pada hasil PCA. Grafik ini digunakan untuk menentukan berapa banyak komponen utama yang sebaiknya dipertahankan dalam analisis.

Pada grafik terlihat bahwa PC1 memiliki eigenvalue yang sangat tinggi, lalu terjadi penurunan yang sangat tajam ke PC2, dan setelah itu garis menjadi hampir datar pada PC3 dan PC4. Pola seperti ini disebut elbow (titik siku). Titik siku berada di sekitar komponen ke-2, yang berarti setelah PC2 penambahan komponen tidak lagi memberikan tambahan informasi yang berarti.

Garis putus-putus horizontal menunjukkan batas eigenvalue = 1 (aturan Kaiser). Komponen yang memiliki eigenvalue di atas garis ini dianggap penting. PC1 dan PC2 berada di atas batas (penting) PC3 dan PC4 berada di bawah batas (kurang penting). Artinya, dua komponen pertama saja sudah cukup untuk mewakili hampir seluruh informasi dalam data. Komponen ke-3 dan ke-4 hanya menambahkan variasi yang sangat kecil sehingga biasanya diabaikan. Jadi, dari 4 variabel awal, data dapat disederhanakan menjadi 2 komponen utama tanpa kehilangan informasi yang signifikan.

plot(
  eigen_result$values,
  type = "b",
  pch = 19,
  xlab = "Komponen Utama",
  ylab = "Eigen Value",
  main = "Scree Plot of Eigen Value"
)
# Garis Kaiser Criterion (eigen value > 1)
abline(h = 1, lty = 2)

Eigen Vector

Tabel eigen vector menunjukkan besarnya kontribusi masing-masing variabel dalam membentuk setiap komponen utama. Variabel dengan nilai absolut paling besar pada suatu komponen berarti memiliki pengaruh paling dominan terhadap komponen tersebut.

Pada PC1, nilai terbesar terdapat pada variabel Fare, sehingga komponen pertama terutama merepresentasikan variasi harga tiket. Artinya, perbedaan nilai pada PC1 sebagian besar dipengaruhi oleh besar kecilnya tarif yang dibayarkan penumpang.

Pada PC2, kontribusi terbesar berasal dari variabel Age. Hal ini menunjukkan bahwa komponen kedua menangkap variasi yang berkaitan dengan perbedaan usia penumpang, sehingga dimensi informasi yang dijelaskan PC2 berbeda dari PC1.

Sementara itu, PC3 dan PC4 lebih banyak dipengaruhi oleh variabel SibSp dan Parch. Kedua komponen ini menggambarkan variasi yang berkaitan dengan struktur keluarga penumpang, namun karena proporsi variansinya sangat kecil, informasi yang ditambahkan relatif terbatas. Oleh karena itu, komponen ketiga dan keempat umumnya tidak digunakan dalam interpretasi utama PC

eigen_vector_table <- eigen_result$vectors
rownames(eigen_vector_table) <- colnames(data_clean)
colnames(eigen_vector_table) <- paste0("PC", 1:ncol(eigen_vector_table))
knitr::kable(
  eigen_vector_table,
  caption = "Tabel Eigen Vector"
)
Tabel Eigen Vector
PC1 PC2 PC3 PC4
Age 0.0284776 0.9992994 -0.0240181 0.0035789
SibSp 0.0023863 -0.0209314 -0.7736933 0.6332099
Parch 0.0032808 -0.0125379 -0.6330881 -0.7739713
Fare 0.9995862 -0.0283783 0.0046092 0.0009267