Abstrak

Tenggelamnya kapal Titanic pada tahun 1912 menyisakan data penumpang yang banyak dipakai untuk latihan analisis data. Makalah ini mengeksplorasi data tersebut untuk mengetahui bagaimana jenis kelamin dan umur berkaitan dengan status keselamatan penumpang. Tahapan yang dilakukan meliputi pembersihan data, pemeriksaan distribusi dan normalitas umur, pengujian homogenitas varians, transformasi data, serta analisis status keselamatan menurut jenis kelamin, umur, dan kombinasi keduanya. Seluruh analisis dilakukan dengan bahasa R.

Kata kunci: Titanic, analisis data eksploratif, jenis kelamin, umur, keselamatan, R

1. Pendahuluan

1.1 Latar Belakang

Kapal RMS Titanic tenggelam pada 15 April 1912 setelah menabrak gunung es dalam pelayaran perdananya. Dari seluruh penumpang yang tercatat, hanya sebagian yang selamat. Peristiwa ini kemudian menjadi salah satu kasus yang paling sering dipakai dalam pembelajaran analisis data, karena datanya memuat variabel demografis dan status keselamatan yang jelas.

Pembagian sekoci yang terbatas memunculkan dugaan bahwa peluang selamat tidak sama untuk setiap penumpang. Kebiasaan mendahulukan perempuan dan anak-anak, misalnya, sering disebut dalam catatan sejarah. Dugaan ini perlu diperiksa langsung dari data agar tidak berhenti sebagai cerita, dan analisis data eksploratif (exploratory data analysis, EDA) adalah pendekatan yang tepat untuk tujuan itu.

1.2 Rumusan Masalah

  1. Bagaimana distribusi jenis kelamin penumpang Titanic?
  2. Bagaimana distribusi umur penumpang Titanic?
  3. Apakah terdapat perbedaan status keselamatan berdasarkan jenis kelamin?
  4. Apakah terdapat perbedaan status keselamatan berdasarkan umur?
  5. Bagaimana pola keselamatan berdasarkan kombinasi jenis kelamin dan kelompok umur?

1.3 Tujuan

Tujuan makalah ini adalah mengeksplorasi pola hubungan antara jenis kelamin dan umur dengan status keselamatan penumpang Titanic, serta menjawab kelima rumusan masalah di atas.

1.4 Batasan Masalah

Analisis hanya menggunakan empat variabel, yaitu PassengerId, Survived, Sex, dan Age. Variabel lain seperti kelas tiket (Pclass) dan harga tiket (Fare) tidak dianalisis terhadap keselamatan. Fare hanya dipakai pada bagian transformasi data numerik.

2. Data dan Metode

2.1 Sumber Data

Data yang digunakan adalah Titanic Dataset dari Kaggle (Elyamadad, n.d.). Data ini berasal dari berbagai sumber sejarah dan penelitian, lalu diperbaiki dan dilengkapi menggunakan Encyclopedia Titanica. Dataset tersimpan dalam bentuk tabel, dengan setiap baris mewakili satu penumpang. Jumlah observasinya 891 penumpang dengan 12 variabel.

Tabel berikut menjelaskan seluruh variabel pada dataset.

tabel_variabel <- data.frame(
  Variabel = c("PassengerId", "Survived", "Pclass", "Name", "Sex", "Age",
               "SibSp", "Parch", "Ticket", "Fare", "Cabin", "Embarked"),
  Keterangan = c("ID penumpang", "Status keselamatan (0 = tidak selamat, 1 = selamat)",
                 "Kelas tiket", "Nama penumpang", "Jenis kelamin", "Umur (tahun)",
                 "Jumlah saudara/pasangan yang ikut", "Jumlah orang tua/anak yang ikut",
                 "Nomor tiket", "Harga tiket", "Kode kabin", "Pelabuhan keberangkatan"),
  Jenis = c("Kualitatif", "Kualitatif", "Kualitatif", "Kualitatif", "Kualitatif",
            "Kuantitatif kontinu", "Kuantitatif diskrit", "Kuantitatif diskrit",
            "Kualitatif", "Kuantitatif kontinu", "Kualitatif", "Kualitatif"),
  Skala = c("Nominal", "Nominal", "Ordinal", "Nominal", "Nominal", "Rasio",
            "Rasio", "Rasio", "Nominal", "Rasio", "Nominal", "Nominal")
)

kable(tabel_variabel, caption = "Tabel 1. Deskripsi variabel dataset Titanic")
Tabel 1. Deskripsi variabel dataset Titanic
Variabel Keterangan Jenis Skala
PassengerId ID penumpang Kualitatif Nominal
Survived Status keselamatan (0 = tidak selamat, 1 = selamat) Kualitatif Nominal
Pclass Kelas tiket Kualitatif Ordinal
Name Nama penumpang Kualitatif Nominal
Sex Jenis kelamin Kualitatif Nominal
Age Umur (tahun) Kuantitatif kontinu Rasio
SibSp Jumlah saudara/pasangan yang ikut Kuantitatif diskrit Rasio
Parch Jumlah orang tua/anak yang ikut Kuantitatif diskrit Rasio
Ticket Nomor tiket Kualitatif Nominal
Fare Harga tiket Kuantitatif kontinu Rasio
Cabin Kode kabin Kualitatif Nominal
Embarked Pelabuhan keberangkatan Kualitatif Nominal

2.2 Metode Analisis

Analisis dilakukan dengan bahasa R, menggunakan paket dplyr, tidyr, dan ggplot2 (bagian dari ekosistem tidyverse) untuk pengolahan dan visualisasi data serta fungsi dasar R untuk uji homogenitas. Langkah-langkahnya adalah sebagai berikut.

  1. Persiapan data: pemeriksaan data setelah cleaning, penanganan data hilang, integrasi data, dan encoding variabel kategorik.
  2. Eksplorasi distribusi: statistik deskriptif, histogram, density plot, dan Q-Q plot.
  3. Uji asumsi: uji Shapiro-Wilk untuk normalitas dan uji Levene untuk homogenitas varians.
  4. Analisis keselamatan: tabulasi silang, grafik proporsi, uji Chi-Square, dan uji Wilcoxon.
  5. Transformasi data numerik: normalisasi, standarisasi, dan transformasi non-linear sebagai eksplorasi lanjutan.

Seluruh pengujian menggunakan taraf signifikansi 5% (\(\alpha = 0{,}05\)).

3. Persiapan Data

3.1 Membaca Data

File Excel dibaca dengan paket readxl. Pastikan file berada di folder yang sama dengan file .Rmd ini.

titanic_raw <- read_excel("data set titanic  ensiklopedia sudah cleaning.xlsx")
glimpse(titanic_raw)
## Rows: 891
## Columns: 12
## $ PassengerId <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,…
## $ Survived    <dbl> 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1…
## $ Pclass      <dbl> 3, 1, 3, 1, 3, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 2, 3, 3…
## $ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
## $ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
## $ Age         <dbl> 22, 38, 26, 35, 35, 29, 54, 2, 27, 14, 4, 58, 20, 39, 14, …
## $ SibSp       <dbl> 1, 1, 0, 1, 0, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 0, 1, 0…
## $ Parch       <dbl> 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0…
## $ Ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
## $ Fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 8.4583, 51.8625,…
## $ Cabin       <chr> NA, "C85", NA, "C123", NA, NA, "E46", NA, NA, NA, "G6", "C…
## $ Embarked    <chr> "S", "C", "S", "S", "S", "Q", "S", "S", "S", "C", "S", "S"…

3.2 Data Setelah Cleaning

Pada data mentah Kaggle ditemukan tiga masalah kualitas data. Pertama, data hilang pada Age (177 data), Cabin (687 data), dan Embarked (2 data). Kedua, nilai Fare sebesar 512,3292 muncul tiga kali pada baris 259, 680, dan 738, sehingga tampak sebagai pencilan. Ketiga, penulisan Ticket tidak konsisten karena bercampur huruf, angka, dan spasi.

File Excel yang digunakan sudah melalui proses cleaning, yaitu data Age yang hilang dilengkapi dengan Encyclopedia Titanica. Dari 12 variabel yang ada, analisis ini hanya memakai variabel PassengerId, Survived, Sex, dan Age, sehingga masalah pada Cabin, Embarked, Fare, dan Ticket tidak memengaruhi hasil.

titanic <- titanic_raw %>%
  select(PassengerId, Survived, Sex, Age)

head(titanic)

Jumlah data hilang pada data setelah cleaning adalah sebagai berikut.

missing_cleaning <- colSums(is.na(titanic))

kable(data.frame(Variabel = names(missing_cleaning),
                 Jumlah_Missing = as.integer(missing_cleaning)),
      caption = "Tabel 2. Jumlah data hilang pada data setelah cleaning")
Tabel 2. Jumlah data hilang pada data setelah cleaning
Variabel Jumlah_Missing
PassengerId 0
Survived 0
Sex 0
Age 3

3.3 Penanganan Data Hilang yang Tersisa

Jika masih ada data Age yang hilang setelah cleaning, nilainya diisi dengan median, karena median tidak terpengaruh nilai ekstrem.

median_age <- median(titanic$Age, na.rm = TRUE)

titanic <- titanic %>%
  mutate(Age = ifelse(is.na(Age), median_age, Age))

kable(data.frame(Variabel = names(titanic),
                 Jumlah_Missing = as.integer(colSums(is.na(titanic)))),
      caption = "Tabel 3. Jumlah data hilang setelah imputasi median")
Tabel 3. Jumlah data hilang setelah imputasi median
Variabel Jumlah_Missing
PassengerId 0
Survived 0
Sex 0
Age 0

Setelah imputasi dengan median sebesar 28 tahun, tidak ada lagi data hilang. Dataset akhir terdiri atas 891 observasi dan 4 variabel.

3.4 Integrasi Data

Data karakteristik penumpang (Sex, Age) dan data keselamatan (Survived) digabungkan menggunakan PassengerId sebagai kunci dengan fungsi left_join().

data_karakteristik <- titanic %>% select(PassengerId, Sex, Age)
data_keselamatan   <- titanic %>% select(PassengerId, Survived)

data_gabungan <- data_karakteristik %>%
  left_join(data_keselamatan, by = "PassengerId")

head(data_gabungan)

3.5 Transformasi Data Kategorik

Variabel Sex berbentuk teks (male dan female) sehingga perlu diubah menjadi angka agar mudah dipakai pada pemodelan. Dua cara dicoba. Cara pertama adalah label encoding (1 = male, 0 = female). Cara kedua adalah one-hot encoding, yaitu setiap kategori dijadikan kolom indikator 0/1.

data_encoded <- data_gabungan %>%
  mutate(
    sex_kode   = ifelse(Sex == "male", 1, 0),
    Sex_male   = ifelse(Sex == "male", 1, 0),
    Sex_female = ifelse(Sex == "female", 1, 0)
  )

head(data_encoded, 8)

4. Hasil dan Pembahasan

4.1 Distribusi Jenis Kelamin

tabel_sex <- data_gabungan %>%
  count(Sex) %>%
  mutate(Persen = round(n / sum(n) * 100, 1))

kable(tabel_sex, caption = "Tabel 4. Jumlah penumpang menurut jenis kelamin")
Tabel 4. Jumlah penumpang menurut jenis kelamin
Sex n Persen
female 314 35.2
male 577 64.8
ggplot(tabel_sex, aes(x = Sex, y = n, fill = Sex)) +
  geom_col(width = 0.6) +
  geom_text(aes(label = paste0(n, " (", Persen, "%)")), vjust = -0.5) +
  scale_fill_manual(values = c(female = warna_female, male = warna_male)) +
  labs(title = "Gambar 1. Distribusi Jenis Kelamin Penumpang",
       x = "Jenis Kelamin", y = "Jumlah Penumpang") +
  theme(legend.position = "none") +
  ylim(0, max(tabel_sex$n) * 1.15)

Dari 891 penumpang, terdapat 577 laki-laki (64.8%) dan 314 perempuan (35.2%). Penumpang laki-laki jauh lebih banyak, sehingga perbandingan keselamatan antar jenis kelamin nanti perlu dibaca dalam bentuk proporsi, bukan jumlah mentah.

4.2 Distribusi Umur

statistik_age <- tibble(
  Statistik = c("Jumlah data", "Rata-rata", "Median", "Standar deviasi",
                "Minimum", "Maksimum"),
  Nilai = c(nrow(data_gabungan),
            round(mean(data_gabungan$Age), 2),
            median(data_gabungan$Age),
            round(sd(data_gabungan$Age), 2),
            min(data_gabungan$Age),
            max(data_gabungan$Age))
)

kable(statistik_age, caption = "Tabel 5. Statistik deskriptif umur penumpang")
Tabel 5. Statistik deskriptif umur penumpang
Statistik Nilai
Jumlah data 891.00
Rata-rata 29.61
Median 28.00
Standar deviasi 14.15
Minimum 0.42
Maksimum 80.00

Umur penumpang berkisar dari 0.42 hingga 80 tahun dengan rata-rata 29.61 tahun dan median 28 tahun. Rata-rata yang sedikit lebih besar dari median mengisyaratkan distribusi yang miring ke kanan. Hal ini terlihat pada histogram dan density plot berikut.

ggplot(data_gabungan, aes(x = Age)) +
  geom_histogram(binwidth = 4, fill = "steelblue", color = "white", alpha = 0.9) +
  labs(title = "Gambar 2. Histogram Umur Penumpang",
       x = "Umur (tahun)", y = "Jumlah Penumpang")

ggplot(data_gabungan, aes(x = Age)) +
  geom_density(fill = warna_utama, alpha = 0.3, color = warna_utama, linewidth = 1) +
  labs(title = "Gambar 3. Density Plot Umur Penumpang",
       x = "Umur (tahun)", y = "Density")

Mayoritas penumpang berada pada usia muda hingga dewasa, dengan puncak di sekitar 20 sampai 30 tahun, lalu jumlahnya menurun ke arah umur yang lebih tinggi. Terdapat pula kelompok kecil anak-anak pada umur sangat rendah. Bentuk distribusi tidak simetris sehingga menyimpang dari distribusi normal.

4.3 Uji Normalitas Umur

Untuk memastikan dugaan visual tersebut, digunakan Q-Q plot dan uji Shapiro-Wilk. Pada Q-Q plot, data yang berdistribusi normal akan mengikuti garis acuan.

ggplot(data_gabungan, aes(sample = Age)) +
  stat_qq(alpha = 0.7) +
  stat_qq_line(color = "red") +
  labs(title = "Gambar 4. Q-Q Plot Umur Penumpang",
       x = "Kuantil Teoretis", y = "Kuantil Sampel")

Titik-titik menyimpang dari garis acuan, terutama pada bagian ujung distribusi. Selanjutnya dilakukan uji Shapiro-Wilk dengan hipotesis:

  • H0: umur berdistribusi normal
  • H1: umur tidak berdistribusi normal
uji_shapiro <- shapiro.test(data_gabungan$Age)
uji_shapiro
## 
##  Shapiro-Wilk normality test
## 
## data:  data_gabungan$Age
## W = 0.97921, p-value = 5.866e-10

Statistik uji menghasilkan W = 0.9792 dengan p-value = 5.866e-10. Karena p-value < 0,05, H0 ditolak, sehingga umur penumpang tidak berdistribusi normal.

Hasil ini tidak berarti data buruk. Dalam EDA, ketidaknormalan justru informasi tentang karakter data. Data umur memang wajar tidak normal, dan konsekuensinya adalah pemilihan uji statistik yang tidak mensyaratkan normalitas, seperti uji Wilcoxon pada bagian 4.6.

4.4 Homogenitas Varians Umur Menurut Jenis Kelamin

Sebelum membandingkan kelompok, perlu dilihat apakah penyebaran umur laki-laki dan perempuan relatif sama.

ringkasan_sex <- data_gabungan %>%
  group_by(Sex) %>%
  summarise(
    Jumlah   = n(),
    Rata_rata = round(mean(Age), 1),
    Median   = median(Age),
    Varians  = round(var(Age), 0),
    .groups  = "drop"
  )

kable(ringkasan_sex, caption = "Tabel 6. Ringkasan umur menurut jenis kelamin")
Tabel 6. Ringkasan umur menurut jenis kelamin
Sex Jumlah Rata_rata Median Varians
female 314 27.9 27 196
male 577 30.5 28 201
ggplot(data_gabungan, aes(x = Sex, y = Age, fill = Sex)) +
  geom_boxplot(alpha = 0.9) +
  scale_fill_manual(values = c(female = warna_female, male = warna_male),
                    name = "Jenis Kelamin") +
  labs(title = "Gambar 5. Boxplot Umur Menurut Jenis Kelamin",
       x = "Jenis Kelamin", y = "Umur (tahun)")

Rata-rata umur laki-laki sedikit lebih tinggi daripada perempuan, sedangkan varians keduanya hampir sama. Kesamaan varians diuji dengan uji Levene:

  • H0: varians umur laki-laki dan perempuan sama (homogen)
  • H1: varians umur laki-laki dan perempuan berbeda
# Uji Levene (versi median) tanpa paket tambahan:
# ANOVA pada selisih absolut umur terhadap median masing-masing kelompok
data_levene <- data_gabungan %>%
  mutate(Selisih = abs(Age - ave(Age, Sex, FUN = median)))

uji_levene <- summary(aov(Selisih ~ factor(Sex), data = data_levene))
uji_levene
##              Df Sum Sq Mean Sq F value Pr(>F)
## factor(Sex)   1     20   20.19   0.241  0.624
## Residuals   889  74576   83.89

Uji menghasilkan F = 0.2407 dan p-value = 0.6238. Karena p-value > 0,05, H0 tidak ditolak, sehingga varians umur laki-laki dan perempuan dapat dianggap homogen.

4.5 Status Keselamatan Menurut Jenis Kelamin

Untuk analisis keselamatan, Survived diberi label dan umur dikelompokkan menjadi lima kategori.

data_analisis <- data_gabungan %>%
  mutate(
    Status = factor(Survived, levels = c(0, 1), labels = c("Tidak Selamat", "Selamat")),
    Kelompok_Umur = cut(Age,
                        breaks = c(0, 12, 17, 35, 60, Inf),
                        labels = c("Anak (0-12)", "Remaja (13-17)",
                                   "Dewasa Muda (18-35)", "Dewasa (36-60)",
                                   "Lansia (>60)"),
                        include.lowest = TRUE)
  )
tabel_survival_sex <- data_analisis %>%
  group_by(Sex) %>%
  summarise(
    Total = n(),
    Selamat = sum(Survived),
    Persen_Selamat = round(mean(Survived) * 100, 1),
    .groups = "drop"
  )

kable(tabel_survival_sex, caption = "Tabel 7. Tingkat keselamatan menurut jenis kelamin")
Tabel 7. Tingkat keselamatan menurut jenis kelamin
Sex Total Selamat Persen_Selamat
female 314 233 74.2
male 577 109 18.9
ggplot(data_analisis, aes(x = Sex, fill = Status)) +
  geom_bar(position = "fill", width = 0.6) +
  scale_y_continuous(labels = scales::percent) +
  scale_fill_manual(values = warna_status) +
  labs(title = "Gambar 6. Proporsi Keselamatan Menurut Jenis Kelamin",
       x = "Jenis Kelamin", y = "Proporsi", fill = "Status")

Hubungan antara jenis kelamin dan status keselamatan diuji dengan uji Chi-Square:

uji_chisq <- chisq.test(table(data_analisis$Sex, data_analisis$Survived))
uji_chisq
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  table(data_analisis$Sex, data_analisis$Survived)
## X-squared = 260.72, df = 1, p-value < 2.2e-16

Tingkat keselamatan perempuan mencapai 74.2%, sedangkan laki-laki hanya 18.9%. Dengan p-value 1.2e-58, terdapat hubungan yang signifikan antara jenis kelamin dan status keselamatan. Temuan ini sejalan dengan dugaan bahwa perempuan lebih diutamakan saat evakuasi.

4.6 Status Keselamatan Menurut Umur

ggplot(data_analisis, aes(x = Status, y = Age, fill = Status)) +
  geom_boxplot(alpha = 0.85) +
  scale_fill_manual(values = warna_status) +
  labs(title = "Gambar 7. Sebaran Umur Menurut Status Keselamatan",
       x = "Status", y = "Umur (tahun)") +
  theme(legend.position = "none")

Karena umur tidak berdistribusi normal (bagian 4.3), perbandingan umur antara penumpang yang selamat dan tidak selamat diuji dengan uji Wilcoxon (Mann-Whitney), yang tidak mensyaratkan normalitas.

uji_wilcox <- wilcox.test(Age ~ Survived, data = data_analisis)
uji_wilcox
## 
##  Wilcoxon rank sum test with continuity correction
## 
## data:  Age by Survived
## W = 97178, p-value = 0.3771
## alternative hypothesis: true location shift is not equal to 0

Dengan p-value 0.3771 (> 0,05), tidak terdapat perbedaan sebaran umur yang signifikan antara penumpang yang selamat dan tidak selamat. Artinya umur saja kurang menjelaskan keselamatan.

Pola per kelompok umur disajikan berikut ini.

tabel_umur <- data_analisis %>%
  group_by(Kelompok_Umur) %>%
  summarise(
    Total = n(),
    Selamat = sum(Survived),
    Persen_Selamat = round(mean(Survived) * 100, 1),
    .groups = "drop"
  )

kable(tabel_umur, caption = "Tabel 8. Tingkat keselamatan menurut kelompok umur")
Tabel 8. Tingkat keselamatan menurut kelompok umur
Kelompok_Umur Total Selamat Persen_Selamat
Anak (0-12) 79 44 55.7
Remaja (13-17) 51 22 43.1
Dewasa Muda (18-35) 495 177 35.8
Dewasa (36-60) 240 94 39.2
Lansia (>60) 26 5 19.2
ggplot(tabel_umur, aes(x = Kelompok_Umur, y = Persen_Selamat)) +
  geom_col(fill = warna_utama, width = 0.65) +
  geom_text(aes(label = paste0(Persen_Selamat, "%")), vjust = -0.5) +
  labs(title = "Gambar 8. Persentase Selamat Menurut Kelompok Umur",
       x = "Kelompok Umur", y = "Persentase Selamat (%)") +
  ylim(0, max(tabel_umur$Persen_Selamat) * 1.15) +
  theme(axis.text.x = element_text(angle = 15, hjust = 1))

Kelompok umur dengan tingkat keselamatan tertinggi adalah Anak (0-12) (55.7%), sedangkan yang terendah adalah Lansia (>60) (19.2%).

4.7 Kombinasi Jenis Kelamin dan Kelompok Umur

Pengaruh umur dan jenis kelamin mungkin saling terkait, sehingga keduanya dilihat bersamaan.

tabel_kombinasi <- data_analisis %>%
  group_by(Sex, Kelompok_Umur) %>%
  summarise(
    Total = n(),
    Selamat = sum(Survived),
    Persen_Selamat = round(mean(Survived) * 100, 1),
    .groups = "drop"
  )

kable(tabel_kombinasi, caption = "Tabel 9. Tingkat keselamatan menurut jenis kelamin dan kelompok umur")
Tabel 9. Tingkat keselamatan menurut jenis kelamin dan kelompok umur
Sex Kelompok_Umur Total Selamat Persen_Selamat
female Anak (0-12) 38 20 52.6
female Remaja (13-17) 25 20 80.0
female Dewasa Muda (18-35) 164 125 76.2
female Dewasa (36-60) 83 65 78.3
female Lansia (>60) 4 3 75.0
male Anak (0-12) 41 24 58.5
male Remaja (13-17) 26 2 7.7
male Dewasa Muda (18-35) 331 52 15.7
male Dewasa (36-60) 157 29 18.5
male Lansia (>60) 22 2 9.1
ggplot(tabel_kombinasi, aes(x = Kelompok_Umur, y = Persen_Selamat, fill = Sex)) +
  geom_col(position = position_dodge(width = 0.8), width = 0.7) +
  geom_text(aes(label = paste0(Persen_Selamat, "%")),
            position = position_dodge(width = 0.8), vjust = -0.4, size = 3.3) +
  scale_fill_manual(values = c(female = warna_female, male = warna_male),
                    name = "Jenis Kelamin") +
  labs(title = "Gambar 9. Persentase Selamat Menurut Jenis Kelamin dan Kelompok Umur",
       x = "Kelompok Umur", y = "Persentase Selamat (%)") +
  ylim(0, 105) +
  theme(axis.text.x = element_text(angle = 15, hjust = 1))

Grafik ini memperlihatkan apakah keunggulan keselamatan perempuan konsisten di setiap kelompok umur, dan apakah anak laki-laki memiliki peluang yang berbeda dari laki-laki dewasa. Kelompok dengan jumlah penumpang sedikit (lihat kolom Total pada Tabel 9) perlu ditafsirkan dengan hati-hati karena persentasenya mudah berubah.

4.8 Transformasi Data Numerik

Bagian ini adalah eksplorasi lanjutan untuk melihat bagaimana skala dan bentuk distribusi Age berubah setelah ditransformasi. Transformasi tidak mengubah kesimpulan analisis keselamatan di atas.

4.8.1 Normalisasi Min-Max dan Standarisasi Z-Score

Normalisasi Min-Max mengubah umur ke rentang 0 sampai 1 dengan rumus \(x' = \dfrac{x - x_{min}}{x_{max} - x_{min}}\). Standarisasi Z-Score menyatakan posisi relatif umur terhadap rata-rata dengan rumus \(z = \dfrac{x - \bar{x}}{s}\).

data_trans <- data_gabungan %>%
  mutate(
    Age_MinMax = (Age - min(Age)) / (max(Age) - min(Age)),
    Age_Z      = as.numeric(scale(Age))
  )

head(data_trans %>% select(PassengerId, Age, Age_MinMax, Age_Z))
data_trans %>%
  summarise(Min_MinMax = min(Age_MinMax), Max_MinMax = max(Age_MinMax),
            Mean_Z = mean(Age_Z), SD_Z = sd(Age_Z)) %>%
  kable(digits = 4, caption = "Tabel 10. Ringkasan hasil Min-Max dan Z-Score")
Tabel 10. Ringkasan hasil Min-Max dan Z-Score
Min_MinMax Max_MinMax Mean_Z SD_Z
0 1 0 1

Setelah Min-Max, nilai minimum menjadi 0 dan maksimum menjadi 1, dengan urutan data tetap terjaga. Hasil Z-Score memiliki rata-rata mendekati 0 dan standar deviasi 1. Nilai Z positif berarti umur di atas rata-rata dan negatif berarti di bawah rata-rata.

4.8.2 Transformasi Invers

Transformasi invers tidak aman jika ada nilai 0, sehingga dicek terlebih dahulu.

tibble(
  min_val    = min(data_trans$Age),
  jumlah_nol = sum(data_trans$Age == 0)
) %>% kable(caption = "Tabel 11. Pemeriksaan nilai nol pada Age")
Tabel 11. Pemeriksaan nilai nol pada Age
min_val jumlah_nol
0.42 0

Tidak ada Age bernilai 0, sehingga transformasi invers dapat dilakukan. Namun, umur yang sangat kecil (misalnya 0,42 tahun) tetap menghasilkan nilai invers yang sangat besar.

data_trans <- data_trans %>%
  mutate(
    Age_Inv_Sq    = 1 / (Age^2),
    Age_Inv_Cubic = 1 / (Age^3)
  )

data_trans %>%
  summarise(Min = min(Age_Inv_Sq), Max = max(Age_Inv_Sq),
            Mean = mean(Age_Inv_Sq), SD = sd(Age_Inv_Sq)) %>%
  kable(digits = 6, caption = "Tabel 12. Ringkasan Invers Square (1/x^2)")
Tabel 12. Ringkasan Invers Square (1/x^2)
Min Max Mean SD
0.000156 5.668934 0.032139 0.250727
head(data_trans %>% select(PassengerId, Age, Age_Inv_Sq, Age_Inv_Cubic))

Semakin besar umur, semakin kecil nilai hasil transformasinya. Inverse Cubic berubah lebih tajam daripada Inverse Square, terutama pada umur rendah.

4.8.3 Transformasi Logaritma, Akar Kuadrat, dan Akar Pangkat Tiga

Ketiga transformasi ini diterapkan pada Age dan Fare. Karena Fare memiliki nilai 0, logaritma dihitung dengan log1p(), yaitu \(\log(1 + x)\), agar tidak menghasilkan -Inf.

data_all <- data_trans %>%
  left_join(titanic_raw %>% select(PassengerId, Fare), by = "PassengerId") %>%
  mutate(
    Age_Log   = log1p(Age),
    Age_Sqrt  = sqrt(Age),
    Age_Cbrt  = Age^(1/3),
    Fare_Log  = log1p(Fare),
    Fare_Sqrt = sqrt(Fare),
    Fare_Cbrt = Fare^(1/3)
  )

perbandingan <- tibble(
  Transformasi = c("Sebelum transformasi", "Logaritma", "Akar kuadrat", "Akar pangkat tiga"),
  Rata2_Age  = c(mean(data_all$Age), mean(data_all$Age_Log),
                 mean(data_all$Age_Sqrt), mean(data_all$Age_Cbrt)),
  SD_Age     = c(sd(data_all$Age), sd(data_all$Age_Log),
                 sd(data_all$Age_Sqrt), sd(data_all$Age_Cbrt)),
  Rata2_Fare = c(mean(data_all$Fare), mean(data_all$Fare_Log),
                 mean(data_all$Fare_Sqrt), mean(data_all$Fare_Cbrt)),
  SD_Fare    = c(sd(data_all$Fare), sd(data_all$Fare_Log),
                 sd(data_all$Fare_Sqrt), sd(data_all$Fare_Cbrt))
)

kable(perbandingan, digits = 3, caption = "Tabel 13. Perbandingan hasil transformasi")
Tabel 13. Perbandingan hasil transformasi
Transformasi Rata2_Age SD_Age Rata2_Fare SD_Fare
Sebelum transformasi 29.605 14.153 32.204 49.693
Logaritma 3.269 0.651 2.962 0.969
Akar kuadrat 5.250 1.432 4.851 2.946
Akar pangkat tiga 2.990 0.587 2.766 1.072
data_all %>%
  select(Age, Age_Log, Age_Sqrt, Age_Cbrt) %>%
  pivot_longer(everything(), names_to = "Transformasi", values_to = "Nilai") %>%
  mutate(Transformasi = factor(Transformasi,
                               levels = c("Age", "Age_Log", "Age_Sqrt", "Age_Cbrt"),
                               labels = c("Asli", "Logaritma", "Akar Kuadrat",
                                          "Akar Pangkat Tiga"))) %>%
  ggplot(aes(x = Nilai)) +
  geom_histogram(bins = 25, fill = warna_utama, color = "white", alpha = 0.85) +
  facet_wrap(~ Transformasi, scales = "free") +
  labs(title = "Gambar 10. Distribusi Umur Setelah Berbagai Transformasi",
       x = "Nilai", y = "Frekuensi")

Pada Age, akar pangkat tiga menghasilkan standar deviasi terkecil, sedangkan pada Fare transformasi logaritma yang terkecil. Namun standar deviasi bukan satu-satunya ukuran. Bentuk distribusi pada histogram dan tujuan analisis juga harus dipertimbangkan, dan transformasi tidak selalu membuat data berdistribusi normal.

5. Kesimpulan dan Saran

5.1 Kesimpulan

  1. Distribusi jenis kelamin. Penumpang laki-laki (577 orang) lebih banyak daripada perempuan (314 orang).
  2. Distribusi umur. Umur terkonsentrasi pada usia muda hingga dewasa dan menyebar ke umur yang lebih tinggi. Berdasarkan Q-Q plot dan uji Shapiro-Wilk, umur tidak berdistribusi normal, sedangkan varians umur antara laki-laki dan perempuan dapat dianggap homogen.
  3. Keselamatan menurut jenis kelamin. Perempuan memiliki tingkat keselamatan (74.2%) yang jauh lebih tinggi daripada laki-laki (18.9%).
  4. Keselamatan menurut umur. Tingkat keselamatan bervariasi antar kelompok umur, dengan nilai tertinggi pada kelompok Anak (0-12).
  5. Kombinasi jenis kelamin dan umur. Pola keselamatan menurut umur tidak sama untuk laki-laki dan perempuan, sehingga kedua variabel sebaiknya dilihat bersamaan.
  6. Transformasi data. Pemilihan transformasi bergantung pada tujuan analisis dan karakteristik data.

5.2 Keterbatasan

  • Analisis hanya memakai Sex dan Age. Kelas tiket (Pclass) dan variabel lain kemungkinan juga berpengaruh dan dapat menjadi pengacau (confounder).
  • Data Age yang hilang diisi dengan median, yang dapat mengurangi variasi data asli.
  • Analisis bersifat eksploratif sehingga menunjukkan keterkaitan, bukan hubungan sebab-akibat.

5.3 Saran

Penelitian selanjutnya dapat menambahkan variabel Pclass, Fare, dan ukuran keluarga (SibSp + Parch), lalu membangun model prediksi seperti regresi logistik untuk mengukur pengaruh tiap variabel terhadap peluang selamat.

Daftar Pustaka

Lampiran: Informasi Sesi R

sessionInfo()
## R version 4.5.3 (2026-03-11 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 10 x64 (build 19045)
## 
## Matrix products: default
##   LAPACK version 3.12.1
## 
## locale:
## [1] LC_COLLATE=English_Indonesia.utf8  LC_CTYPE=English_Indonesia.utf8   
## [3] LC_MONETARY=English_Indonesia.utf8 LC_NUMERIC=C                      
## [5] LC_TIME=English_Indonesia.utf8    
## 
## time zone: Asia/Jakarta
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] knitr_1.52     readxl_1.5.0.1 tidyr_1.3.2    ggplot2_4.0.3  dplyr_1.2.1   
## 
## loaded via a namespace (and not attached):
##  [1] gtable_0.3.6       jsonlite_2.0.0     compiler_4.5.3     tidyselect_1.2.1  
##  [5] jquerylib_0.1.4    scales_1.4.0       yaml_2.3.12        fastmap_1.2.0     
##  [9] R6_2.6.1           labeling_0.4.3     generics_0.1.4     tibble_3.3.1      
## [13] bslib_0.12.0       pillar_1.11.1      RColorBrewer_1.1-3 rlang_1.1.7       
## [17] cachem_1.1.0       xfun_0.61          sass_0.4.10        S7_0.2.2          
## [21] cli_3.6.5          withr_3.0.2        magrittr_2.0.4     digest_0.6.39     
## [25] grid_4.5.3         rstudioapi_0.19.0  lifecycle_1.0.5    vctrs_0.7.2       
## [29] evaluate_1.0.5     glue_1.8.0         farver_2.1.2       cellranger_1.1.0  
## [33] rmarkdown_2.32     purrr_1.2.2        tools_4.5.3        pkgconfig_2.0.3   
## [37] htmltools_0.5.9