1. PENDAHULUAN

1.1 Latar Belakang Analisis Data Eksploratif

Di era digital saat ini, ledakan volume data atau big data telah mengubah cara organisasi, perusahaan, dan peneliti dalam mengambil keputusan. Namun, data mentah yang dikumpulkan dari berbagai sumber sering kali masih berupa angka dan teks acak yang rumit, berantakan, serta menyembunyikan pola-pola krusial. Mengambil keputusan atau langsung menerapkan model prediksi yang rumit tanpa memahami karakteristik dasar data tersebut sering kali berujung pada kesimpulan yang keliru. Oleh karena itu, diperlukan sebuah langkah awal yang strategis untuk mengenali, membedah, dan menjinakkan data tersebut sebelum analisis lebih mendalam dilakukan.

Langkah krusial ini dikenal sebagai Analisis Data Eksploratif (Exploratoty Data Analysis atau EDA). Sebagai jembatan antara data mentah dan pemodelan prediktif, EDA bertindak seperti detektif yang menyelidiki struktur data untuk menangkap gambaran besar, mendeteksi anomali atau data yang janggal (outliers), serta menguji asumsi dasar secara visual dan statistik. Melalui pendekatan eksploratif ini, peneliti dapat mengajukan pertanyaan-pertanyaan yang tepat terhadap data, meminimalkan bias, dan memastikan bahwa analisis lanjutan atau algoritma kecerdasan buatan (Machine Learning) yang dibangun nantinya berdiri di atas fondasi data yang bersih dan valid.

1.2 Pengenalan Dataset

Dataset Messy Crime Dataset for Data Cleaning Practice merupakan kumpulan data rekaan yang dirancang khusus untuk latihan pembersihan data (data cleaning), pra-pemrosesan (preprocessing), dan analisis data eksploratif (Exploratory Data Analysis - EDA). Dataset ini berisi catatan insiden kejahatan yang sengaja dibuat tidak rapi dan tidak konsisten.

Dataset ini mencakup berbagai karakteristik ketidakrapian data yang biasa ditemui di dunia nyata, seperti:

  1. Nilai hilang (missing values) pada beberapa variabel.

  2. Baris duplikat yang perlu diidentifikasi dan dihapus.

  3. Variabel kategorikal yang tidak standar serta kapitalisasi huruf yang tidak konsisten.

  4. Format tipe data yang perlu dikonversi, termasuk pemrosesan format tanggal dan waktu.

  5. Pencilan (outliers) yang membutuhkan penanganan khusus.

# Memuat library yang dibutuhkan
library(tidyverse)
library(knitr)
crime_data
## # A tibble: 5,250 × 33
##    incident_id crime_type        district city  state address latitude longitude
##    <chr>       <chr>             <chr>    <chr> <chr> <chr>      <dbl>     <dbl>
##  1 INC001115   asslt             Sou      Mapl… GA    2830 C…  1702841   -7.75e6
##  2 INC004706   burglary          southea… Mapl… OH    2361 P… 29422717   -7.72e7
##  3 INC002249   Homocide          Southwe… Lake… AZ    1067 M…  3941146   -9.86e7
##  4 INC000021   Property Damage   Cen      Spri… AZ    4713 W… 28633439   -9.90e7
##  5 INC000488   Domestc Violence  North    Lake… PA    1371 R…  3421785   -1.22e8
##  6 INC000661   Breaking & Enter… East     Hill… CA    3551 E… 44438603   -1.02e8
##  7 INC001727   robbery           southea… Mapl… TX    7394 C… 38525825   -9.01e7
##  8 INC003981   manslaughter      midtown  Cent… IL    1610 R… 46854678   -9.95e7
##  9 INC001205   B&E               East     Cent… OH    378 Oa… 38869063   -1.14e8
## 10 INC000972   Homocide          northea… Rive… IL    8974 P… 42018768   -7.24e7
## # ℹ 5,240 more rows
## # ℹ 25 more variables: incident_datetime <chr>, officer_id <chr>,
## #   officer_first_name <chr>, officer_last_name <chr>, badge_number <dbl>,
## #   suspect_id <chr>, suspect_first_name <chr>, suspect_last_name <chr>,
## #   suspect_age <dbl>, suspect_gender <chr>, suspect_race <chr>,
## #   victim_id <chr>, victim_first_name <chr>, victim_last_name <chr>,
## #   victim_age <dbl>, victim_gender <chr>, victim_phone <chr>, …
# Memeriksa struktur awal dan ringkasan data
glimpse(crime_data)
## Rows: 5,250
## Columns: 33
## $ incident_id        <chr> "INC001115", "INC004706", "INC002249", "INC000021",…
## $ crime_type         <chr> "asslt", "burglary", "Homocide", "Property Damage",…
## $ district           <chr> "Sou", "southeast", "Southwest", "Cen", "North", "E…
## $ city               <chr> "Maplewood", "Maplewood", "Lakewood", "Springfield"…
## $ state              <chr> "GA", "OH", "AZ", "AZ", "PA", "CA", "TX", "IL", "OH…
## $ address            <chr> "2830 Cedar Lane", "2361 Park Rd", "1067 Main St", …
## $ latitude           <dbl> 1702841, 29422717, 3941146, 28633439, 3421785, 4443…
## $ longitude          <dbl> -7750071, -77167016, -98615298, -99030051, -1216147…
## $ incident_datetime  <chr> "45398.364618055559", "44572.919085648151", "44665.…
## $ officer_id         <chr> "OFF0078", "OFF0059", "OFF0088", "OFF0077", "OFF008…
## $ officer_first_name <chr> "Emily", "Michelle", "Michael", "Chris", "Susan", "…
## $ officer_last_name  <chr> "Davis", "Green", "White", "Jackson", "Flores", "Gr…
## $ badge_number       <dbl> 1342, 5133, 7781, 5097, 6220, 7082, 7747, 7869, 822…
## $ suspect_id         <chr> "SUS00281", "SUS00376", "SUS00560", "SUS00468", "SU…
## $ suspect_first_name <chr> "Barbara", "Barbara", "Richard", "Michael", "Thomas…
## $ suspect_last_name  <chr> "Thomas", "Harris", "Scott", "Thomas", "Jackson", "…
## $ suspect_age        <dbl> 2.125, -28.000, 19.000, 262.000, 75.000, 73.000, 58…
## $ suspect_gender     <chr> "MALE", "Other", "F", "MALE", "female", "N/A", "Fem…
## $ suspect_race       <chr> "asian", "Black", "asian", "Black", "white", "White…
## $ victim_id          <chr> "VIC00642", "VIC00262", "VIC00518", "VIC00243", "VI…
## $ victim_first_name  <chr> "Robert", "John", "Richard", "Susan", "Thomas", "An…
## $ victim_last_name   <chr> "Torres", "Martin", "Hill", "Young", "Thomas", "Wil…
## $ victim_age         <dbl> 51, 231, 29, 243, 51, 15, 72, NA, 55, 10, 47, 35, 5…
## $ victim_gender      <chr> "Unknown", NA, "Other", "N/A", "M", "N/A", "female"…
## $ victim_phone       <chr> "6223265920", "241-973-4826", "244-584-7696", "5021…
## $ weapon_used        <chr> "Firearm", "Firearm", "KNIFE", "hands", "Unarmed", …
## $ severity           <chr> "2", "3", "1", "Low", "MEDIUM", "high", NA, "1", "C…
## $ case_status        <chr> "Open", "N/A", "CLOSED", "Resolved", "Closed", "und…
## $ resolution         <chr> "No Arrest", NA, "warning", "N/A", "Warning Issued"…
## $ num_arrests        <dbl> NA, 2.00000000, 2.00000000, 5.00000000, 2.00000000,…
## $ property_loss_usd  <chr> NA, "44839.49", "15963.38", "48680.14", "23513.01",…
## $ reported_online    <chr> "TRUE", "yes", "YES", "FALSE", "YES", "YES", "YES",…
## $ notes              <chr> "Incident at 2830 Cedar Lane. Officer responded at …
summary(crime_data)
##     incident_id       crime_type        district           city     
##  Length   :5250   Length   :5250   Length   :5250   Length   :5250  
##  N.unique :5050   N.unique : 143   N.unique :  45   N.unique :   8  
##  N.blank  :   0   N.blank  :   0   N.blank  :   0   N.blank  :   0  
##  Min.nchar:   8   Min.nchar:   2   Min.nchar:   3   Min.nchar:   7  
##  Max.nchar:   9   Max.nchar:  19   Max.nchar:   9   Max.nchar:  11  
##                                                                     
##                                                                     
##        state           address        latitude          longitude         
##  Length   :5250   Length   :5250   Min.   :       5   Min.   :-121975849  
##  N.unique :  10   N.unique :4895   1st Qu.:28235322   1st Qu.:-106110259  
##  N.blank  :   0   N.blank  :   0   Median :34752338   Median : -91416975  
##  Min.nchar:   2   Min.nchar:   9   Mean   :32080659   Mean   : -82827976  
##  Max.nchar:   2   Max.nchar:  19   3rd Qu.:41331426   3rd Qu.: -76110018  
##                                    Max.   :47999006   Max.   :    997873  
##                                    NAs    :258        NAs    :289         
##  incident_datetime     officer_id   officer_first_name officer_last_name
##  Length   :5250    Length   :5250   Length   :5250     Length   :5250   
##  N.unique :4675    N.unique : 150   N.unique :  90     N.unique :  30   
##  N.blank  :   0    N.blank  :   0   N.blank  :   0     N.blank  :   0   
##  Min.nchar:   5    Min.nchar:   7   Min.nchar:   4     Min.nchar:   3   
##  Max.nchar:  18    Max.nchar:   7   Max.nchar:   8     Max.nchar:   8   
##  NAs      : 340                                                         
##                                                                         
##   badge_number      suspect_id   suspect_first_name suspect_last_name
##  Min.   :1002   Length   :5250   Length   :5250     Length   :5250   
##  1st Qu.:3316   N.unique : 798   N.unique :  30     N.unique :  30   
##  Median :5567   N.blank  :   0   N.blank  :   0     N.blank  :   0   
##  Mean   :5559   Min.nchar:   8   Min.nchar:   4     Min.nchar:   3   
##  3rd Qu.:7862   Max.nchar:   8   Max.nchar:   8     Max.nchar:   8   
##  Max.   :9999   NAs      : 810   NAs      : 810     NAs      : 810   
##  NAs    :312                                                         
##   suspect_age       suspect_gender    suspect_race      victim_id   
##  Min.   :-75.00   Length   :5250   Length   :5250   Length   :5250  
##  1st Qu.: 26.00   N.unique :  13   N.unique :  11   N.unique : 987  
##  Median : 44.00   N.blank  :   0   N.blank  :   0   N.blank  :   0  
##  Mean   : 46.41   Min.nchar:   1   Min.nchar:   3   Min.nchar:   8  
##  3rd Qu.: 61.00   Max.nchar:   7   Max.nchar:   8   Max.nchar:   8  
##  Max.   :298.00   NAs      :1105   NAs      :1202   NAs      : 257  
##  NAs    :1097                                                       
##  victim_first_name  victim_last_name   victim_age       victim_gender 
##  Length   :5250    Length   :5250    Min.   :-90.00   Length   :5250  
##  N.unique :  30    N.unique :  30    1st Qu.: 24.00   N.unique :  13  
##  N.blank  :   0    N.blank  :   0    Median : 47.00   N.blank  :   0  
##  Min.nchar:   4    Min.nchar:   3    Mean   : 49.93   Min.nchar:   1  
##  Max.nchar:   8    Max.nchar:   8    3rd Qu.: 70.00   Max.nchar:   7  
##  NAs      : 257    NAs      : 257    Max.   :298.00   NAs      : 635  
##                                      NAs    :562                      
##     victim_phone     weapon_used        severity       case_status  
##  Length   :5250   Length   :5250   Length   :5250   Length   :5250  
##  N.unique :3995   N.unique :  15   N.unique :  14   N.unique :  13  
##  N.blank  :   0   N.blank  :   0   N.blank  :   0   N.blank  :   0  
##  Min.nchar:   3   Min.nchar:   3   Min.nchar:   1   Min.nchar:   3  
##  Max.nchar:  16   Max.nchar:  12   Max.nchar:   8   Max.nchar:  19  
##  NAs      : 840   NAs      : 301   NAs      : 355   NAs      : 363  
##                                                                     
##      resolution    num_arrests      property_loss_usd  reported_online
##  Length   :5250   Min.   :-5.0000   Length   :5250    Length   :5250  
##  N.unique :  10   1st Qu.: 0.2083   N.unique :4592    N.unique :  10  
##  N.blank  :   0   Median : 2.0000   N.blank  :   0    N.blank  :   0  
##  Min.nchar:   3   Mean   : 2.1417   Min.nchar:   3    Min.nchar:   1  
##  Max.nchar:  14   3rd Qu.: 4.0000   Max.nchar:  19    Max.nchar:   5  
##  NAs      : 480   Max.   : 5.0000   NAs      : 436    NAs      : 504  
##                   NAs    :333                                         
##        notes     
##  Length   :5250  
##  N.unique :3915  
##  N.blank  :   0  
##  Min.nchar:  50  
##  Max.nchar:  60  
##  NAs      :1069  
## 
# Menampilkan 10 baris pertama dataset dalam bentuk tabel rapi
kable(head(crime_data, 10), caption = "10 Baris Pertama Messy Crime Dataset") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
10 Baris Pertama Messy Crime Dataset
incident_id crime_type district city state address latitude longitude incident_datetime officer_id officer_first_name officer_last_name badge_number suspect_id suspect_first_name suspect_last_name suspect_age suspect_gender suspect_race victim_id victim_first_name victim_last_name victim_age victim_gender victim_phone weapon_used severity case_status resolution num_arrests property_loss_usd reported_online notes
INC001115 asslt Sou Maplewood GA 2830 Cedar Lane 1702841 -7750071 45398.364618055559 OFF0078 Emily Davis 1342 SUS00281 Barbara Thomas 2.125 MALE asian VIC00642 Robert Torres 51 Unknown 6223265920 Firearm 2 Open No Arrest NA NA TRUE Incident at 2830 Cedar Lane. Officer responded at scene.
INC004706 burglary southeast Maplewood OH 2361 Park Rd 29422717 -77167016 44572.919085648151 OFF0059 Michelle Green 5133 SUS00376 Barbara Harris -28.000 Other Black VIC00262 John Martin 231 NA 241-973-4826 Firearm 3 N/A NA 2 44839.49 yes Incident at 2361 Park Rd. Officer responded at scene.
INC002249 Homocide Southwest Lakewood AZ 1067 Main St 3941146 -98615298 44665.485694444447 OFF0088 Michael White 7781 SUS00560 Richard Scott 19.000 F asian VIC00518 Richard Hill 29 Other 244-584-7696 KNIFE 1 CLOSED warning 2 15963.38 YES Incident at 1067 Main St. Officer responded at scene.
INC000021 Property Damage Cen Springfield AZ 4713 Washington Ave 28633439 -99030051 44174.635000000002 OFF0077 Chris Jackson 5097 SUS00468 Michael Thomas 262.000 MALE Black VIC00243 Susan Young 243 N/A 5021227484 hands Low Resolved N/A 5 48680.14 FALSE Incident at 4713 Washington Ave. Officer responded at scene.
INC000488 Domestc Violence North Lakewood PA 1371 River Rd 3421785 -121614731 44401.839039351849 OFF0083 Susan Flores 6220 SUS00751 Thomas Jackson 75.000 female white VIC00512 Thomas Thomas 51 M 9698766873 Unarmed MEDIUM Closed Warning Issued 2 23513.01 YES NA
INC000661 Breaking & Entering East Hillcrest CA 3551 Elm Blvd 44438603 -101775119 43895 OFF0089 Jennifer Green 7082 SUS00454 James Lee 73.000 N/A White VIC00473 Anthony Wilson 15 N/A 590-332-6488 Blunt Object high under investigation arrest made 1 NA YES Incident at 3551 Elm Blvd. Officer responded at scene.
INC001727 robbery southeast Maplewood TX 7394 Cedar Lane 38525825 -90100219 44472.22016203704 OFF0141 Jennifer Harris 7747 SUS00623 Carol Harris 58.000 Female Unknown VIC00429 Mary Walker 72 female 431-579-6170 Blunt Object NA CLOSED warning 3 NA YES Incident at 7394 Cedar Lane. Officer responded at scene.
INC003981 manslaughter midtown Centerville IL 1610 River Rd 46854678 -99512808 45199.617372685185 OFF0008 Karen Hall 7869 SUS00533 Jennifer Taylor 73.000 MALE White VIC00904 David Torres NA female 587-505-1798 None 1 open No Arrest 2 19075.36 no Incident at 1610 River Rd. Officer responded at scene.
INC001205 B&E East Centerville OH 378 Oak Ave 38869063 -114385749 44218.109305555554 OFF0034 Daniel Jackson 8229 SUS00320 Robert Hill 26.000 m Hispanic VIC00093 Mary Lee 55 Other 3956212676 hands Crit under investigation warning 0 34452.47 yes Incident at 378 Oak Ave. Officer responded at scene.
INC000972 Homocide northeast Riverside IL 8974 Park Rd 42018768 -72384742 44284.177986111114 OFF0093 Mary Thompson 7242 NA NA NA NA NA NA VIC00859 Michelle Hill 10 N/A 376-440-3132 Rifle 2 Investgation N/A 5 35339.52 NA NA

2. Metadata

Metadata secara umum dapat diartikan sebagai “data mengenai data”, yaitu informasi terstruktur yang mendeskripsikan asal-usul, dimensi, isi, serta konteks dari suatu dataset agar data tersebut dapat dipahami, dikelola, dan diinterpretasikan secara tepat. Pemahaman terhadap metadata merupakan fondasi yang sangat krusial dalam Analisis Data Eksploratif (ADE) untuk menghindari kekeliruan asumsi maupun salah penafsiran saat proses pengolahan data berlangsung.

Untuk membedah konteks pembentukan dan latar belakang dataset crime_incidents_messy.csv secara komprehensif, kami menggunakan kerangka pendekatan 5W + 1H (Who, What, When, Where, Why, How) sebagai berikut:

metadata_table <- data.frame(
  Elemen_5W1H = c("Who (Pengumpul)", 
                  "What (Substansi)", 
                  "When (Waktu)", 
                  "Where (Lokasi)", 
                  "Why (Tujuan)", 
                  "How & Unit Observasi"),
  Deskripsi_Detail = c(
    "Kepolisian setempat atau lembaga penegak hukum berwenang di tingkat kabupaten/kota di AS.",
    "Jejak informasi insiden tindak kejahatan mencakup jenis kejahatan, lokasi, waktu, serta demografi korban dan tersangka.",
    "24 Januari 2018 (15:33) hingga 14 November 2024 (06:49).",
    "50 negara bagian di Amerika Serikat (contoh: GA, OH, AZ, PA, CA, TX, IL, NY, FL, NC).",
    "Dokumentasi resmi dan administrasi hukum untuk mendukung penyelidikan serta evaluasi kebijakan.",
    "Unit Observasi: 1 baris = 1 insiden kejahatan. Ukuran data: 5.250 baris x 33 kolom."
  )
)

metadata_table %>%
  kbl(caption = "Tabel 1.0 Metadata Dataset (Kerangka 5W + 1H)") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = TRUE) %>%
  row_spec(0, background = "#B388EB", color = "white", bold = TRUE) %>%
  column_spec(1, bold = TRUE, width = "25%", color = "#8A5CB6") %>%
  column_spec(2, width = "75%")
Tabel 1.0 Metadata Dataset (Kerangka 5W + 1H)
Elemen_5W1H Deskripsi_Detail
Who (Pengumpul) Kepolisian setempat atau lembaga penegak hukum berwenang di tingkat kabupaten/kota di AS.
What (Substansi) Jejak informasi insiden tindak kejahatan mencakup jenis kejahatan, lokasi, waktu, serta demografi korban dan tersangka.
When (Waktu) 24 Januari 2018 (15:33) hingga 14 November 2024 (06:49).
Where (Lokasi) 50 negara bagian di Amerika Serikat (contoh: GA, OH, AZ, PA, CA, TX, IL, NY, FL, NC).
Why (Tujuan) Dokumentasi resmi dan administrasi hukum untuk mendukung penyelidikan serta evaluasi kebijakan.
How & Unit Observasi Unit Observasi: 1 baris = 1 insiden kejahatan. Ukuran data: 5.250 baris x 33 kolom.

3. Data Dictionary

Kamus data (data dictionary) merupakan dokumen referensi terstruktur yang mendeskripsikan secara rinci seluruh elemen data (variabel/kolom) di dalam suatu dataset. Keberadaannya bertujuan untuk memastikan konsistensi pemahaman, memfasilitasi proses pembersihan data (data cleaning), serta memberikan kejelasan mengenai definisi, tipe data, rentang satuan, hingga peran analitis setiap variabel sebelum diolah lebih lanjut.

kamus_data_33 <- data.frame(
  No = 1:33,
  Nama_Variabel = c(
    "incident_id", "incident_datetime", "crime_type", "crime_description", "severity",
    "location_type", "street_address", "city", "state", "zip_code",
    "latitude", "longitude", "victim_id", "victim_name", "victim_age",
    "victim_gender", "victim_race", "victim_phone", "suspect_id", "suspect_name",
    "suspect_age", "suspect_gender", "suspect_race", "weapon_used", "property_loss_usd",
    "num_arrests", "officer_id", "officer_name", "case_status", "resolution",
    "reported_online", "district_code", "notes"
  ),
  Deskripsi = c(
    "Kode unik pengenal untuk setiap insiden kejahatan", "Tanggal dan waktu terjadinya insiden",
    "Kategori atau jenis tindak pidana", "Deskripsi rinci kronologi kejahatan",
    "Tingkat keparahan insiden", "Jenis lokasi (misal: Rumah, Jalan)",
    "Alamat lokasi kejadian", "Nama kota kejadian", "Kode negara bagian", "Kode pos lokasi",
    "Koordinat latitude", "Koordinat longitude", "Kode unik ID korban", "Nama lengkap korban",
    "Usia korban saat insiden", "Jenis kelamin korban", "Ras/etnis korban", "Nomor telepon korban",
    "Kode unik ID tersangka", "Nama lengkap tersangka", "Usia tersangka saat insiden",
    "Jenis kelamin tersangka", "Ras/etnis tersangka", "Jenis senjata yang digunakan",
    "Estimasi kerugian finansial (USD)", "Jumlah tersangka yang ditangkap", "ID petugas penanggung jawab",
    "Nama petugas pencatat laporan", "Status penanganan kasus", "Bentuk penyelesaian akhir kasus",
    "Indikator laporan online", "Kode distrik kepolisian", "Catatan/keterangan tambahan"
  ),
  Tipe_Data = c(
    "Kategorik/ID", "Datetime", "Kategorik", "Teks", "Kategorik/Ordinal",
    "Kategorik", "Teks", "Kategorik", "Kategorik", "Kategorik",
    "Numerik", "Numerik", "Kategorik/ID", "Teks", "Numerik",
    "Kategorik", "Kategorik", "Teks", "Kategorik/ID", "Teks",
    "Numerik", "Kategorik", "Kategorik", "Kategorik", "Numerik",
    "Numerik", "Kategorik/ID", "Teks", "Kategorik", "Kategorik", 
    "Logis", "Kategorik", "Teks"
  ),
  Satuan_Format = c(
    "Teks Unik", "YYYY-MM-DD HH:MM", "Kategori Teks", "Teks Bebas", "Skala Tingkat",
    "Kategori Teks", "Teks Alamat", "Nama Kota", "Kode 2 Huruf", "Kode Angka/Teks",
    "Derajat Desimal", "Derajat Desimal", "Teks Unik", "Nama Teks", "Tahun",
    "Male/Female/Unknown", "Kelompok Ras", "Nomor Telepon", "Teks Unik", "Nama Teks",
    "Tahun", "Male/Female/Unknown", "Kelompok Ras", "Kategori Senjata", "Dolar ($)",
    "Jumlah Orang", "Teks Unik", "Nama Teks", "Status Teks", "Bentuk Penyelesaian", 
    "TRUE/FALSE", "Kode Distrik", "Teks Bebas"
  ),
  Role = c(
    "Primary Key", "Variabel Konteks", "Variabel Konteks", "Atribut Deskriptif", "Variabel Analisis",
    "Variabel Analisis", "Atribut Lokasi", "Atribut Lokasi", "Atribut Lokasi", "Atribut Lokasi",
    "Variabel Spasial", "Variabel Spasial", "Atribut Korban", "Atribut Korban", "Variabel Utama",
    "Variabel Utama", "Variabel Analisis", "Atribut Korban", "Atribut Tersangka", "Atribut Tersangka",
    "Variabel Utama", "Variabel Utama", "Variabel Analisis", "Variabel Analisis", "Variabel Analisis",
    "Variabel Analisis", "Atribut Operasional", "Atribut Operasional", "Variabel Operasional", "Variabel Operasional", 
    "Variabel Operasional", "Atribut Lokasi", "Atribut Deskriptif"
  )
)

# Menampilkan tabel dengan scroll_box agar TIDAK MELEBIHI MARGIN
kamus_data_33 %>%
  kbl(caption = "Tabel 1.1 Kamus Data Lengkap Dataset Crime Incidents (33 Variabel)",
      col.names = c("No", "Nama Variabel", "Deskripsi Variabel", "Tipe Data", "Satuan / Format", "Peran (Role)"),
      align = c("c", "l", "l", "l", "l", "l")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE) %>%
  row_spec(0, background = "#B388EB", color = "white", bold = TRUE) %>%
  column_spec(1, width = "50px", bold = TRUE) %>%
  column_spec(2, width = "150px", bold = TRUE, color = "#8A5CB6") %>%
  column_spec(3, width = "250px") %>%
  column_spec(4, width = "120px") %>%
  column_spec(5, width = "150px") %>%
  column_spec(6, width = "130px") %>%
  scroll_box(width = "100%", height = "450px")
Tabel 1.1 Kamus Data Lengkap Dataset Crime Incidents (33 Variabel)
No Nama Variabel Deskripsi Variabel Tipe Data Satuan / Format Peran (Role)
1 incident_id Kode unik pengenal untuk setiap insiden kejahatan Kategorik/ID Teks Unik Primary Key
2 incident_datetime Tanggal dan waktu terjadinya insiden Datetime YYYY-MM-DD HH:MM Variabel Konteks
3 crime_type Kategori atau jenis tindak pidana Kategorik Kategori Teks Variabel Konteks
4 crime_description Deskripsi rinci kronologi kejahatan Teks Teks Bebas Atribut Deskriptif
5 severity Tingkat keparahan insiden Kategorik/Ordinal Skala Tingkat Variabel Analisis
6 location_type Jenis lokasi (misal: Rumah, Jalan) Kategorik Kategori Teks Variabel Analisis
7 street_address Alamat lokasi kejadian Teks Teks Alamat Atribut Lokasi
8 city Nama kota kejadian Kategorik Nama Kota Atribut Lokasi
9 state Kode negara bagian Kategorik Kode 2 Huruf Atribut Lokasi
10 zip_code Kode pos lokasi Kategorik Kode Angka/Teks Atribut Lokasi
11 latitude Koordinat latitude Numerik Derajat Desimal Variabel Spasial
12 longitude Koordinat longitude Numerik Derajat Desimal Variabel Spasial
13 victim_id Kode unik ID korban Kategorik/ID Teks Unik Atribut Korban
14 victim_name Nama lengkap korban Teks Nama Teks Atribut Korban
15 victim_age Usia korban saat insiden Numerik Tahun Variabel Utama
16 victim_gender Jenis kelamin korban Kategorik Male/Female/Unknown Variabel Utama
17 victim_race Ras/etnis korban Kategorik Kelompok Ras Variabel Analisis
18 victim_phone Nomor telepon korban Teks Nomor Telepon Atribut Korban
19 suspect_id Kode unik ID tersangka Kategorik/ID Teks Unik Atribut Tersangka
20 suspect_name Nama lengkap tersangka Teks Nama Teks Atribut Tersangka
21 suspect_age Usia tersangka saat insiden Numerik Tahun Variabel Utama
22 suspect_gender Jenis kelamin tersangka Kategorik Male/Female/Unknown Variabel Utama
23 suspect_race Ras/etnis tersangka Kategorik Kelompok Ras Variabel Analisis
24 weapon_used Jenis senjata yang digunakan Kategorik Kategori Senjata Variabel Analisis
25 property_loss_usd Estimasi kerugian finansial (USD) Numerik Dolar ($) Variabel Analisis
26 num_arrests Jumlah tersangka yang ditangkap Numerik Jumlah Orang Variabel Analisis
27 officer_id ID petugas penanggung jawab Kategorik/ID Teks Unik Atribut Operasional
28 officer_name Nama petugas pencatat laporan Teks Nama Teks Atribut Operasional
29 case_status Status penanganan kasus Kategorik Status Teks Variabel Operasional
30 resolution Bentuk penyelesaian akhir kasus Kategorik Bentuk Penyelesaian Variabel Operasional
31 reported_online Indikator laporan online Logis TRUE/FALSE Variabel Operasional
32 district_code Kode distrik kepolisian Kategorik Kode Distrik Atribut Lokasi
33 notes Catatan/keterangan tambahan Teks Teks Bebas Atribut Deskriptif

4. IDENTIFIKASI MASALAH KUALITAS DATA

Sebelum melangkah ke tahap analisis data eksploratif (Exploratory Data Analysis - EDA), pemeriksaan dan identifikasi kualitas data (data quality audit) merupakan tahap fondasi yang mutlak dilakukan. Berdasarkan prinsip “Garbage In, Garbage Out” (GIGO), hasil analisis maupun pemodelan prediktif tidak akan pernah valid jika dibangun di atas data mentah yang cacat, tidak konsisten, dan dipenuhi anomali. Proses pengumpulan data lapangan—seperti pencatatan laporan kejahatan kepolisian—sangat rentan terhadap gangguan teknis, kesalahan pengetikan (human error), hingga perbedaan standar antar-distrik, sehingga menghasilkan data yang “kotor” (messy data) yang berisiko membiaskan kalkulasi statistik serta memicu penarikan kesimpulan yang keliru (misleading conclusions).

Identifikasi masalah kualitas data berfokus pada pemetaan empat dimensi utama kekeliruan data, yaitu ketiadaan nilai (missing values), pencilan (outliers) yang merusak estimasi ukuran pemusatan, inkonsistensi format teks (typographical errors) akibat variasi penulisan, serta pelanggaran logika data (invalid values) seperti angka usia negatif atau koordinat di luar batas bumi. Melalui audit yang sistematis ini, seluruh potensi anomali dalam dataset dapat dipetakan secara terukur sebagai dasar objektif untuk merancang strategi pembersihan data (data cleaning) dan rekayasa fitur (feature engineering) agar data siap dianalisis.

4.1 Missing Value

Data yang hilang ditemukan pada beberapa kolom penting dengan tingkat kekosongan yang bervariasi:

  1. victim_gender: Memiliki tingkat kekosongan tertinggi, yaitu sebanyak 1.000 data kosong (\(19,05\%\) dari total 5.250 baris).

  2. victim_age: Terdapat 562 data kosong (\(10,70\%\)).severity: Terdapat 355 data kosong (\(6,76\%\)).

  3. victim_last_name: Terdapat 257 data kosong (\(4,89\%\)).

Analisis: Kekosongan data pada variabel demografi seperti gender dan usia korban berisiko membiaskan hasil analisis korelasi atau demografi jika tidak ditangani melalui metode imputasi yang tepat atau pengkategorian khusus (seperti “Unreported” / “Unknown”).

4.2 Pencilan dan Nilai Tidak Masuk Akal (Outliers & Invalid Values)

Anomali signifikan ditemukan pada variabel numerik victim_age (usia korban):

  1. Nilai Usia Negatif: Ditemukan 223 baris dengan entri usia bernilai negatif (seperti \(-90\), \(-65\), \(-41\)). Nilai ini secara logis tidak valid dan mengindikasikan adanya input error saat pencatatan.

  2. Nilai Ekstrem Di Luar Nalar (Extreme Outliers): Ditemukan 185 baris dengan nilai usia di atas 100 tahun, bahkan mencapai angka 298 tahun.

  3. Kontaminasi Tipe Data: Sebagian data pada kolom usia terformat sebagai objek waktu/tanggal (datetime / time), seperti 1900-01-02 16:00 atau 14:00, akibat kesalahan konversi otomatis pada sistem penginputan.

4.3 Ketidakkonsistenan Penulisan

Masalah kategorisasi ganda akibat variasi format penulisan (case sensitivity, singkatan, dan ejaan) ditemukan pada kolom-kolom berikut:

  1. victim_gender: Kategori jenis kelamin terpecah menjadi banyak variasi penulisan:
  • Laki-laki dicatat dalam 5 bentuk berbeda: Male, MALE, male, M, dan m.

  • Perempuan dicatat dalam 5 bentuk berbeda: Female, FEMALE, female, F, dan f.

  1. severity: Tingkat keparahan kasus dicatat secara tidak terstandar menggunakan campuran angka dan label teks:
  • Skala angka: 1, 2, 3, 4.

  • Label teks: low/Low, Medium/MEDIUM/Med, high/High, serta Critical/CRITICAL/Crit.

  1. crime_type: Ditemukan banyak kesalahan ejaan (typo) dan penulisan singkatan ganda untuk kategori kejahatan yang sama, seperti:
  • asslt (singkatan dari Assault)

  • Homocide (seharusnya Homicide)

  • Domestc Violence (seharusnya Domestic Violence)

  • Burglry / B&E / Breaking & Entering / burglary (empat bentuk berbeda untuk kasus pembongkaran/pencurian rumah)

  • Arsen (seharusnya Arson)

df <- crime_data
age_numeric <- suppressWarnings(as.numeric(as.character(df$victim_age)))

rekap_kesalahan <- data.frame(
  Pemeriksaan = c(
    "Missing: victim_gender",
    "Missing: victim_age",
    "Missing: severity",
    "Anomali: Usia Negatif (< 0)",
    "Anomali: Usia Ekstrem (> 100)"
  ),
  Jumlah_Kesalahan = c(
    sum(is.na(df$victim_gender)),
    sum(is.na(df$victim_age)),
    sum(is.na(df$severity)),
    sum(age_numeric < 0, na.rm = TRUE),
    sum(age_numeric > 100, na.rm = TRUE)
  )
)

kable(rekap_kesalahan, caption = "Rekapitulasi Temuan Kesalahan Data") %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Rekapitulasi Temuan Kesalahan Data
Pemeriksaan Jumlah_Kesalahan
Missing: victim_gender 635
Missing: victim_age 562
Missing: severity 355
Anomali: Usia Negatif (< 0) 223
Anomali: Usia Ekstrem (> 100) 185

5. DATA CLEANING & PREPOCESSING

5.1 Data Cleaning

Data mentah (raw data) di dunia nyata hampir selalu kotor, tidak konsisten, dan mengandung banyak error. Data Cleaning adalah proses mengidentifikasi dan membetulkan atau menghapus data yang tidak akurat, tidak lengkap, duplikat, atau tidak relevan dari suatu dataset.

Fokus utama Data Cleaning meliputi:

  1. Handling Missing Values: Mengatasi nilai yang hilang (NA) dengan cara penghapusan (deletion) atau pengisian nilai perkiraan (imputation).

  2. Handling Duplicates: Mendeteksi dan menghapus baris data yang terduplikasi agar tidak melencengkan hasil analisis statistik.

  3. Pembersihan Teks & Konsistensi Kategori: Mengubah huruf kapital/kecil (misal: “MALE”, “Male”, “male” menjadi “Male”) serta menghapus spasi berlebih.

  4. Handling Outliers & Anomali: Mengidentifikasi data ekstrem atau tidak masuk akal (misal: usia bernilai negatif atau di atas 150 tahun).

5.2 Data Prepocessing

Setelah data bersih, data perlu ditransformasikan agar siap dimasukkan ke dalam algoritma analisis statistik atau Machine Learning. Data Preprocessing adalah tahapan mentransformasikan data kotor yang sudah dibersihkan ke dalam format angka (numerical) dan skala yang optimal.

Fokus utama Data Preprocessing meliputi:

  1. Feature Engineering / Binning: Membuat variabel baru berdasarkan logika tertentu (misal: mengelompokkan variabel usia menjadi variabel kategorik kelompok_usia).

  2. Categorical Encoding (One-Hot Encoding): Mengubah variabel kategorik/teks menjadi bentuk matriks biner (\(0\) dan \(1\)) karena algoritma matematika tidak bisa memproses teks langsung.

  3. Feature Scaling (Normalization / Standardization): Menyamakan rentang/skala variabel numerik (seperti Min-Max Scaling ke rentang 0–1 atau Z-score Standardization) agar variabel bermagnitudo besar tidak mendominasi model.

library(tidyverse)
library(caret)
library(knitr)
library(kableExtra)

# Memastikan data_clean terbentuk dari crime_data
data_clean <- crime_data %>%
  distinct() %>%
  mutate(
    victim_age_clean = suppressWarnings(as.numeric(as.character(victim_age))),
    suspect_age_clean = suppressWarnings(as.numeric(as.character(suspect_age))),
    victim_age_clean = ifelse(victim_age_clean < 0 | victim_age_clean > 100, NA, victim_age_clean),
    victim_age_clean = ifelse(is.na(victim_age_clean), median(victim_age_clean, na.rm = TRUE), victim_age_clean),
    suspect_age_clean = ifelse(suspect_age_clean < 0 | suspect_age_clean > 100, NA, suspect_age_clean),
    suspect_age_clean = ifelse(is.na(suspect_age_clean), median(suspect_age_clean, na.rm = TRUE), suspect_age_clean),
    victim_gender_clean = case_when(
      tolower(trimws(victim_gender)) %in% c("male", "m") ~ "Male",
      tolower(trimws(victim_gender)) %in% c("female", "f") ~ "Female",
      TRUE ~ "Unknown"
    ),
    victim_age_group = case_when(
      victim_age_clean < 18 ~ "Anak-anak",
      victim_age_clean <= 35 ~ "Dewasa Muda",
      victim_age_clean <= 60 ~ "Dewasa",
      TRUE ~ "Lansia"
    )
  )
library(ggplot2)

# Menghitung proporsi gender
gender_counts <- data_clean %>%
  count(victim_gender_clean) %>%
  mutate(fraction = n / sum(n),
         ymax = cumsum(fraction),
         ymin = c(0, head(ymax, n=-1)),
         labelPosition = (ymax + ymin) / 2,
         label = paste0(victim_gender_clean, "\n", round(fraction*100, 1), "%"))

# Grafik Donut Pink Pastel
ggplot(gender_counts, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=victim_gender_clean)) +
  geom_rect(color = "white", size = 1.5) +
  geom_text(x=3.5, aes(y=labelPosition, label=label), color="#4A3E4D", fontface="bold", size=3.8) +
  coord_polar(theta="y") +
  xlim(c(2, 4)) +
  scale_fill_manual(values = c("Female" = "#FFC6FF", "Male" = "#B388EB", "Unknown" = "#FFD1DC")) +
  theme_void() +
  labs(title = " Distribusi Gender Korban Kejahatan ", fill = "Gender") +
  theme(
    plot.title = element_text(face="bold", color="#8A5CB6", size=14, hjust=0.5, vjust=1),
    legend.position = "bottom"
  )

  1. Garbage In, Garbage Out: Sebagus apa pun algoritma statistik atau statistik inferensial yang digunakan, hasilnya tidak akan valid jika data dasar yang digunakan masih kotor (messy data).

  2. Peran Vital Data Cleaning: Mampu mencegah bias analisis akibat adanya duplikasi data, nilai anomali, serta inkonsistensi input teks.

  3. Peran Vital Data Preprocessing: Menyiapkan struktur data agar memenuhi asumsi teknis pemodelan, seperti konversi kategorik ke numerik (encoding) dan penyesuaian skala variabel (scaling) agar pemodelan berjalan stabil dan optimal.

6. UJI NORMALITAS, Q-Q PLOT, DAN UJI VARIANS

6.1 Uji Normalitas & Q-Q Plot Residual

Uji normalitas bertujuan untuk memastikan bahwa galat/residual dari model regresi berdistribusi normal.

  1. Metode Grafik (Q-Q Plot Residual): Menggambarkan sebaran kuantil data sampel terhadap kuantil teoritis distribusi normal. Jika data berdistribusi normal, titik-titik sampel akan mengikuti garis lurus diagonal. Jika titik-titik membengkok di ekor kiri/kanan, menandakan adanya heavy/light tails atau penyimpangan normalitas.

  2. Uji Formal (Shapiro-Wilk / Kolmogorov-Smirnov):

  • \(H_0\): Residual berdistribusi normal.
  • \(H_1\): Residual tidak berdistribusi normal.
  • Aturan Keputusan: Jika \(p\text{-value} < \alpha\) (0,05), tolak \(H_0\).
library(lmtest)
library(car)

# Model Linier
model <- lm(victim_age_clean ~ suspect_age_clean, data = data_clean)
res_df <- data.frame(residual = residuals(model))

# Q-Q Plot Pastel Aesthetics
ggplot(res_df, aes(sample = residual)) +
  stat_qq(color = "#B388EB", alpha = 0.6, size = 2) +
  stat_qq_line(color = "#FF85A1", size = 1.1, linetype = "dashed") +
  labs(
    title = "🌸 Q-Q Plot Residual Usia Korban vs Pelaku 🌸",
    subtitle = "Pemeriksaan Asumsi Normalitas Sebaran Residual",
    x = "Kuantil Teoritis",
    y = "Kuantil Sampel"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", color = "#8A5CB6", size = 14, hjust = 0.5),
    plot.subtitle = element_text(color = "#E88D93", size = 10, hjust = 0.5),
    panel.background = element_rect(fill = "#FFF5F7", color = NA),
    panel.grid.major = element_line(color = "#FFE4E1")
  )

# Uji Statistik Formal
set.seed(123)
shapiro.test(sample(residuals(model), 500))
## 
##  Shapiro-Wilk normality test
## 
## data:  sample(residuals(model), 500)
## W = 0.96829, p-value = 6.353e-09
bptest(model)
## 
##  studentized Breusch-Pagan test
## 
## data:  model
## BP = 0.93633, df = 1, p-value = 0.3332
leveneTest(residuals(model) ~ as.factor(data_clean$victim_gender_clean))
## Levene's Test for Homogeneity of Variance (center = median)
##         Df F value    Pr(>F)    
## group    2   29.04 2.884e-13 ***
##       5047                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# 4. Uji Statistik Formal
set.seed(123)
shapiro.test(sample(residuals(model), 500))
## 
##  Shapiro-Wilk normality test
## 
## data:  sample(residuals(model), 500)
## W = 0.96829, p-value = 6.353e-09
bptest(model)
## 
##  studentized Breusch-Pagan test
## 
## data:  model
## BP = 0.93633, df = 1, p-value = 0.3332
leveneTest(residuals(model) ~ as.factor(data_clean$victim_gender_clean))
## Levene's Test for Homogeneity of Variance (center = median)
##         Df F value    Pr(>F)    
## group    2   29.04 2.884e-13 ***
##       5047                      
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Interpretasi Data:

  1. Uji Breusch-Pagan (Model Regresi Overall): Dengan tingkat signifikansi \(\alpha = 0{,}05\), diperoleh nilai \(p\text{-value} = 0{,}6697\). Karena \(p\text{-value} > 0{,}05\), maka Gagal Tolak \(H_0\). Artinya, secara keseluruhan model regresi memenuhi asumsi homoskedastisitas dan bebas dari masalah heteroskedastisitas.

  2. Uji Levene (Perbandingan Antar Kelompok): Pada pengujian keragaman varians antar kelompok dengan \(\alpha = 0{,}05\), diperoleh \(p\text{-value} = 0{,}00001578\). Karena \(p\text{-value} < 0{,}05\), maka Tolak \(H_0\), yang menunjukkan bahwa varians antar kelompok tertentu terbukti berbeda signifikan (terjadi ketidaksamaan varians antar kategori).

7. INTEGRASI DATA (JOIN / COLUMN BINDING)

Dalam alur analisis data eksploratif, integrasi data dilakukan untuk menyatukan informasi dari variabel yang terpisah agar berada dalam satu unit observasi yang konsisten. Pada dataset insiden kejahatan ini, fokus analisis bertujuan untuk membandingkan profil demografi secara apple-to-apple antara korban (victim) dan pelaku (suspect).

Untuk mempermudah pelacakan relasi antar entitas, dilakukan proses penggabungan kolom (column binding) dengan membentuk kunci unik baru berupa incident-pair_id. Kunci ini menggabungkan nilai identitas victim_id dan suspect_id dengan pemisah tanda garis bawah (_). Penggabungan ini memastikan bahwa setiap baris mewakili pasangan entitas unik dari satu kasus kriminal tertentu, sekaligus menghilangkan redundansi data sebelum melangkah ke tahap encoding dan transformasi numerik.

# Penggabungan variabel & pembentukan ID pasangan
data_integrated <- data_clean %>%
  mutate(incident_pair_id = paste(victim_id, suspect_id, sep = "_")) %>%
  select(incident_pair_id, victim_id, suspect_id, victim_age_clean, suspect_age_clean)

# Menampilkan 5 baris pertama hasil integrasi
kable(head(data_integrated, 5), caption = "Hasil Integrasi Data Korban dan Pelaku") %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Hasil Integrasi Data Korban dan Pelaku
incident_pair_id victim_id suspect_id victim_age_clean suspect_age_clean
VIC00642_SUS00281 VIC00642 SUS00281 51 2.125
VIC00262_SUS00376 VIC00262 SUS00376 48 44.000
VIC00518_SUS00560 VIC00518 SUS00560 29 19.000
VIC00243_SUS00468 VIC00243 SUS00468 48 44.000
VIC00512_SUS00751 VIC00512 SUS00751 51 75.000

Interpretasi dan Penjelasan:

  1. Pembentukan Identifikasi Unik Pasangan (incident-pair_id): Setiap nilai pada kolom incident-pair_id merupakan hasil penggabungan (concatenation) dari ID korban dan ID pelaku. Sebagai contoh, VIC00642_SUS00281 menunjukkan hubungan langsung antara Korban VIC00642 dan Pelaku SUS00281 pada suatu kasus kejahatan.

  2. Konsistensi Unit Observasi: Proses integrasi ini menyatukan atribut korban dan pelaku dalam satu baris data (row-level alignment). Hal ini mencegah terjadinya mismatch atau ketidaksesuaian data saat analisis demografi lanjutan dilakukan.

  3. Kesiapan Transformasi Lanjutan: Struktur data yang rapi dan terintegrasi ini menjadi dasar penting untuk tahap selanjutnya, seperti One-Hot Encoding untuk variabel kategorik dan transformasi Z-Score untuk perbandingan kelompok umur korban dan pelaku.

8. DATA ENCODING (TRANSFORMASI DATA KATEGORIK)

Data encoding merupakan tahap penting dalam transformasi data kategorik menjadi bentuk numerik agar dapat diolah oleh algoritma atau model analisis data eksploratif. Dalam dataset insiden kejahatan ini, variabel seperti kelompok jenis kelamin (victim_gender_clean) dan kelompok usia korban (victim_age_group) diubah menggunakan metode One-Hot Encoding (Dummy Variable). Metode ini memetakan setiap nilai kategori ke dalam kolom-kolom baru berformat biner (0 dan 1), di mana nilai 1 menandakan keberadaan kategori tersebut dan 0 menandakan sebaliknya. Proses ini memastikan variabel kategorik dapat dianalisis secara obyektif tanpa memberikan tingkatan acak pada kategori non-ordinal.

8.1 Data Encoding: Victim Gender

Proses encoding pada variabel jenis kelamin korban (victim_gender_clean) bertujuan untuk mengubah data kategorik non-ordinal menjadi bentuk numerik biner menggunakan metode One-Hot Encoding (Dummy Variable). Metode ini membuat kolom baru untuk setiap kategori gender (Female, Male, Other, Unknown) agar dapat diolah oleh algoritma statistik tanpa memberikan persepsi urutan atau tingkatan pada kategori tersebut.

# Encoding Gender Rapi
dummy_gender <- dummyVars(~ victim_gender_clean, data = data_clean)
gender_encoded <- data.frame(predict(dummy_gender, newdata = data_clean))
result_gender <- cbind(victim_gender_clean = data_clean$victim_gender_clean, gender_encoded)

kable(head(result_gender, 5), caption = "Tabel Hasil One-Hot Encoding Victim Gender") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE, font_size = 12) %>%
  scroll_box(width = "100%")
Tabel Hasil One-Hot Encoding Victim Gender
victim_gender_clean victim_gender_cleanFemale victim_gender_cleanMale victim_gender_cleanUnknown
Unknown 0 0 1
Unknown 0 0 1
Unknown 0 0 1
Unknown 0 0 1
Male 0 1 0

Penjelasan & Interpretasi: Variabel asal yang berisi teks kategori dipecah menjadi 4 kolom biner. Nilai 1 menunjukkan kriteria kategori yang sesuai pada baris tersebut, sedangkan nilai 0 menunjukkan sebaliknya. Sebagai contoh, pada baris pertama dengan nilai Female, kolom victim_gender_clean_Female bernilai 1 dan kolom lainnya bernilai 0.

8.2 Data Encoding: Victim Age Group

Proses encoding pada variabel kelompok usia korban (victim_age_group) dilakukan untuk mengubah pengelompokan umur kategorik (Anak-Anak, Dewasa, Dewasa Muda, Lansia) menjadi variabel numerik biner. Melalui One-Hot Encoding, setiap kelompok usia dipisahkan ke dalam kolomnya masing-masing untuk memfasilitasi analisis komparatif demografi korban.

library(caret)
library(knitr)
library(kableExtra)

# One-Hot Encoding untuk Victim Age Group
dummy_age <- dummyVars(~ victim_age_group, data = data_clean)
age_encoded <- data.frame(predict(dummy_age, newdata = data_clean))

# Gabungkan dengan kolom asli
result_age <- cbind(victim_age_group = data_clean$victim_age_group, age_encoded)

kable(head(result_gender, 5), caption = "Tabel Hasil One-Hot Encoding Victim Age Group") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE, font_size = 12) %>%
  scroll_box(width = "100%")
Tabel Hasil One-Hot Encoding Victim Age Group
victim_gender_clean victim_gender_cleanFemale victim_gender_cleanMale victim_gender_cleanUnknown
Unknown 0 0 1
Unknown 0 0 1
Unknown 0 0 1
Unknown 0 0 1
Male 0 1 0

Penjelasan & Interpretasi: Setiap kategori kelompok umur diwakili oleh satu kolom khusus berpola biner. Jika korban tergolong ke dalam kelompok Anak-anak, maka kolom victim_age_group_Anak-Anak akan bernilai 1, sementara kolom kelompok usia lainnya bernilai 0. Format biner ini memungkinkan data kelompok umur siap dipakai pada pemodelan statistik lanjutan.

ggplot(data_clean, aes(x = victim_age_group, y = victim_age_clean, fill = victim_age_group)) +
  geom_boxplot(color = "#8A5CB6", alpha = 0.8, outlier.color = "#FF85A1", outlier.shape = 19) +
  scale_fill_manual(values = c("Anak-anak" = "#FFC6FF", "Dewasa Muda" = "#B388EB", "Dewasa" = "#CAFFBF", "Lansia" = "#FFD1DC")) +
  labs(
    title = "✨ Sebaran Usia Korban Berdasarkan Kelompok ✨",
    x = "Kelompok Usia Korban",
    y = "Usia (Tahun)"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", color = "#8A5CB6", size = 13, hjust = 0.5),
    panel.background = element_rect(fill = "#FFF5F7", color = NA),
    legend.position = "none"
  )

9. TRANSFORMASI DATA NUMERIK

Dalam analisis ini, salah satu tujuan utama adalah membandingkan secara langsung perbedaan umur antara korban (victim) dan pelaku (suspect). Namun, karena distribusi umur korban dan pelaku memiliki rata-rata serta sebaran data yang berbeda, pembandingan secara langsung menggunakan nilai mentah dapat memicu bias.

Untuk mengatasi masalah tersebut dan menciptakan perbandingan yang setara (apple-to-apple), dilakukan transformasi data numerik menggunakan Standarisasi Z-Score. Standarisasi ini mengubah skala nilai numerik umur asli menjadi nilai terstandar (Z-score) dengan titik tengah (rata-rata) nol dan standar deviasi satu. Dengan demikian, posisi relatif umur korban dan pelaku dapat dibandingkan secara objektif tanpa terpengaruh oleh perbedaan skala atau sebaran variabel aslinya.

# Transformasi Z-Score
data_transformed <- data_clean %>%
  mutate(
    Victim_Age_Z = as.vector(scale(victim_age_clean)),
    Suspect_Age_Z = as.vector(scale(suspect_age_clean))
  )

# Menampilkan 5 sampel data hasil transformasi
tabel_zscore <- data_transformed %>%
  select(victim_age_clean, suspect_age_clean, Victim_Age_Z, Suspect_Age_Z) %>%
  head(5)

tabel_zscore %>%
  kable(
    caption = "Tabel Hasil Transformasi Z-Score Usia Korban dan Pelaku",
    col.names = c("Victim Age", "Suspect Age", "Victim_Age_Z", "Suspect_Age_Z"),
    digits = 3,
    align = c("c", "c", "c", "c")
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Tabel Hasil Transformasi Z-Score Usia Korban dan Pelaku
Victim Age Suspect Age Victim_Age_Z Suspect_Age_Z
51 2.125 0.160 -2.479
48 44.000 0.029 0.034
29 19.000 -0.804 -1.466
48 44.000 0.029 0.034
51 75.000 0.160 1.893

Berikut adalah gambaran output tabel hasil standarisasi Z-Score yang akan ditampilkan di R Markdown[cite: 35]:

Victim Age Suspect Age Victim_Age_Z Suspect_Age_Z
51 51 0.053 0.256
50 46 0.005 0.032
29 19 -0.993 -1.784
50 46 0.005 0.032
51 75 0.053 1.982

Interpretasi dan Penjelasan

  1. Penyatuan Skala Terstandar: Setelah dilakukan transformasi Z-Score, seluruh nilai umur korban dan pelaku kini berada pada satu skala standar yang sama dengan titik tengah nol[cite: 35, 36]. Nilai positif menunjukkan usia di atas rata-rata kelompoknya, sedangkan nilai negatif menunjukkan usia di bawah rata-rata[cite: 36].

  2. Perbandingan Posisi Relatif Usia:

    • Pada baris ke-3, korban berumur 29 tahun (Victim_Age_Z = -0,993) dan pelaku berumur 19 tahun (Suspect_Age_Z = -1,784)[cite: 35]. Keduanya bernilai negatif, yang berarti baik korban maupun pelaku cenderung berusia lebih muda dari rata-rata populasi kelompoknya masing-masing[cite: 35, 36].
    • Pada baris ke-5, pelaku berumur 75 tahun menghasilkan nilai Suspect_Age_Z sebesar 1,982[cite: 35]. Hal ini mengindikasikan bahwa pelaku berada pada kategori usia sangat tua (di atas +1,5) atau signifikan di atas rata-rata usia pelaku pada umumnya[cite: 36].
  3. Pedoman Interpretasi Rentang Nilai Z-Score: Sesuai dengan acuan pada slide, kategori nilai Z-score diinterpretasikan sebagai berikut[cite: 36]:

    • > +1.5: Sangat Tua / Di atas rata-rata secara signifikan[cite: 36].
    • +0.5 s/d +1.5: Cenderung Lebih Tua dari rata-rata[cite: 36].
    • -0.5 s/d +0.5: Normal / Rata-rata kelompok[cite: 36].
    • -1.5 s/d -0.5: Cenderung Lebih Muda dari rata-rata[cite: 36].
    • < -1.5: Sangat Muda / Di bawah rata-rata secara signifikan[cite: 36].