UTS Pengantar Statistika

Ujian Tengah Semester

Fadli Nafsin

LinkedIn | GitHub | Email

Menempuh pendidikan di bidang Sains Data di Institut Teknologi Sains Bandung (ITSB), dengan ketertarikan pada Data Science, Data Analytics, dan pengembangan solusi berbasis data. Memiliki semangat untuk terus belajar, bereksplorasi, dan mengembangkan kemampuan di dunia teknologi dan data.

1 Petunjuk dan Ruang Lingkup

Dokumen ini memuat ringkasan materi Minggu 1–7 dan analisis eksploratif terhadap dataset 30 hari. Analisis pada Soal 2 dilakukan menggunakan R agar hasil tabel, ukuran statistik, dan visualisasi dapat diperbarui langsung dari dataset. Nilai ekstrem tetap dipertahankan pada analisis awal dan diperiksa berdasarkan konteks, bukan langsung dihapus.

2 Soal 1 – Ringkasan Materi Minggu 1–7

2.1 Minggu 1 – Konsep Dasar Statistika dan Data

Statistika merupakan ilmu yang mempelajari cara mengumpulkan, mengolah, menyajikan, menganalisis, dan menafsirkan data untuk membantu pengambilan keputusan. Statistika deskriptif menggambarkan data yang tersedia, sedangkan statistika inferensial menarik kesimpulan tentang populasi berdasarkan sampel. Populasi adalah seluruh objek yang menjadi perhatian, sementara sampel merupakan sebagian anggota populasi yang diamati. Parameter menggambarkan karakteristik populasi dan statistik menggambarkan karakteristik sampel. Variabel numerik berupa angka yang dapat dihitung, sedangkan variabel kategorik menunjukkan kelompok. Variabel independen berperan sebagai faktor penjelas, sementara variabel dependen menjadi hasil yang diamati. Contohnya, perusahaan menilai apakah kanal transaksi (independen) berkaitan dengan nilai transaksi (dependen). Konsep ini digunakan untuk menentukan tujuan analisis dan memahami batas kesimpulan dari data.

2.2 Minggu 2 – Jenis Data dan Skala Pengukuran

Data dibedakan menjadi kualitatif dan kuantitatif. Data kualitatif berupa kategori, seperti kanal Online dan Offline, sedangkan data kuantitatif berupa angka. Data kuantitatif diskrit merupakan hasil hitungan, misalnya jumlah transaksi, sementara data kontinu dapat diukur, seperti waktu proses. Sumber data dapat berupa data primer yang dikumpulkan langsung melalui survei atau pengamatan dan data sekunder yang berasal dari laporan atau basis data yang sudah tersedia. Skala pengukuran terdiri atas nominal (kategori tanpa urutan), ordinal (kategori berurutan), interval (jarak sama tanpa nol mutlak), dan rasio (jarak sama dengan nol mutlak). Dalam dataset, observasi adalah baris pengamatan dan variabel adalah kolom. Feature merupakan variabel masukan untuk analisis atau model, sedangkan target adalah variabel yang ingin diprediksi.

Skala Karakteristik Contoh
Nominal Kategori tanpa urutan Kanal transaksi
Ordinal Kategori memiliki urutan Tingkat kepuasan
Interval Jarak sama, tanpa nol mutlak Suhu Celsius
Rasio Jarak sama, memiliki nol mutlak Waktu proses, jumlah transaksi

2.3 Minggu 3 – Pengumpulan Data dan Sampling

Pengumpulan data dilakukan untuk memperoleh informasi yang sesuai dengan tujuan penelitian. Data primer dikumpulkan langsung, misalnya melalui survei atau wawancara, sedangkan data sekunder berasal dari sumber yang sudah tersedia, seperti laporan atau basis data. Sampling adalah proses memilih sebagian anggota populasi untuk diteliti. Metode probability sampling memberi peluang terpilih yang diketahui kepada anggota populasi, contohnya simple random sampling, systematic sampling, stratified sampling, dan cluster sampling. Non-probability sampling tidak memberikan peluang terpilih yang sama atau diketahui, contohnya convenience, purposive, quota, dan snowball sampling. Pemilihan metode harus mempertimbangkan tujuan, kerangka sampel, waktu, biaya, dan potensi bias. Sampel yang besar belum tentu mewakili populasi apabila proses pemilihannya tidak tepat.

Probability sampling Non-probability sampling
Peluang pemilihan dapat diketahui Peluang pemilihan tidak diketahui secara pasti
Mendukung generalisasi jika rancangan tepat Generalisasi lebih terbatas
Contoh: acak sederhana, stratifikasi Contoh: purposive, convenience
Jenis bias Penyebab utama
Sampling bias Sampel tidak mewakili populasi karena cara pemilihan
Response bias Responden menjawab tidak jujur atau tidak akurat
Measurement bias Alat atau prosedur pengukuran menghasilkan nilai yang keliru

Selain survei dan wawancara, data dapat dikumpulkan melalui observasi, yaitu mengamati dan mencatat kejadian tanpa memberikan perlakuan, serta eksperimen, yaitu memberikan perlakuan tertentu untuk melihat pengaruhnya. Contohnya, perusahaan layanan digital dapat mengamati catatan transaksi harian atau menguji perubahan alur layanan pada kelompok tertentu. Observasi digunakan ketika perusahaan ingin menggambarkan kondisi operasional yang berlangsung secara alami, sedangkan eksperimen digunakan ketika ingin menguji apakah suatu perubahan benar-benar memberikan pengaruh.

2.4 Minggu 4 – Penyajian dan Visualisasi Data

Penyajian data membantu pembaca melihat pola dan membandingkan informasi. Tabel distribusi frekuensi merangkum banyaknya data pada kategori atau kelas tertentu. Frekuensi relatif diperoleh dari frekuensi kelas dibagi jumlah seluruh data, sedangkan frekuensi kumulatif merupakan penjumlahan frekuensi secara bertahap. Untuk data numerik berkelompok, banyak kelas dapat diperkirakan dengan aturan Sturges, \(k = 1 + 3{,}322\log_{10}(n)\), lalu lebar kelas ditentukan dari rentang dibagi banyak kelas. Diagram batang dan lingkaran cocok untuk kategori, sedangkan histogram cocok untuk data numerik. Poligon frekuensi dan ogive juga dapat digunakan untuk menunjukkan bentuk distribusi dan frekuensi kumulatif. Visualisasi harus memiliki judul, label, skala yang wajar, serta tidak menyesatkan. Pemilihan grafik disesuaikan dengan jenis data dan tujuan analisis.

Bentuk penyajian Kegunaan utama
Diagram batang Membandingkan frekuensi kategori
Diagram lingkaran Menunjukkan proporsi kategori
Histogram Melihat bentuk distribusi numerik
Poligon frekuensi Membandingkan bentuk distribusi
Ogive Melihat frekuensi kumulatif
Stem-and-leaf Menampilkan pola sekaligus nilai data

Contoh singkat di R:

contoh_kategori <- c("Online", "Offline", "Online", "Online", "Offline")
freq <- table(contoh_kategori)
freq                         # frekuensi absolut
## contoh_kategori
## Offline  Online 
##       2       3
prop.table(freq)             # frekuensi relatif
## contoh_kategori
## Offline  Online 
##     0.4     0.6
cumsum(freq)                 # frekuensi kumulatif
## Offline  Online 
##       2       5
barplot(table(contoh_kategori), col = c("#78a9c5", "#e6ad65"),
        main = "Contoh Frekuensi Kanal", ylab = "Frekuensi")

x_stem <- c(12, 15, 21, 23, 25, 31, 38)
stem(x_stem)                 # stem-and-leaf
## 
##   The decimal point is 1 digit(s) to the right of the |
## 
##   1 | 25
##   2 | 135
##   3 | 18

2.5 Minggu 5 – Ukuran Pemusatan dan Sebaran

Ukuran pemusatan menjelaskan nilai yang mewakili pusat data. Mean adalah rata-rata, median adalah nilai tengah setelah data diurutkan, dan modus adalah nilai yang paling sering muncul. Ukuran sebaran menunjukkan variasi data. Rentang merupakan selisih nilai maksimum dan minimum, varians mengukur rata-rata kuadrat penyimpangan dari mean, dan standar deviasi merupakan akar varians. Koefisien variasi (CV) membandingkan standar deviasi terhadap mean dalam bentuk persentase sehingga berguna untuk membandingkan variasi relatif antarvariabel dengan mean positif. Kuartil membagi data terurut menjadi empat bagian, sedangkan IQR adalah selisih kuartil ketiga dan pertama. Contohnya, dua kanal dapat memiliki rata-rata transaksi serupa tetapi standar deviasi berbeda; kanal dengan standar deviasi lebih besar memiliki jumlah transaksi yang lebih bervariasi.

Nilai ekstrem dapat menarik mean ke arah nilai tersebut dan memperbesar standar deviasi, sedangkan median cenderung lebih tahan terhadap pengaruhnya. Mean dan standar deviasi lebih sesuai untuk data yang relatif simetris, sementara median dan IQR lebih informatif ketika distribusi miring atau memiliki nilai ekstrem.

\[ \bar{x}=\frac{\sum x_i}{n},\qquad s^2=\frac{\sum (x_i-\bar{x})^2}{n-1},\qquad s=\sqrt{s^2} \]

\[ CV=\frac{s}{\bar{x}}\times100\%,\qquad IQR=Q_3-Q_1 \]

Contoh singkat di R:

x_contoh <- c(12, 14, 15, 15, 19)
w_contoh <- c(1, 1, 2, 2, 1)
c(mean = mean(x_contoh), weighted_mean = weighted.mean(x_contoh, w_contoh),
  median = median(x_contoh), sd = sd(x_contoh), range = diff(range(x_contoh)))
##          mean weighted_mean        median            sd         range 
##      15.00000      15.00000      15.00000       2.54951       7.00000

2.6 Minggu 6 – Distribusi Data dan Outlier

Ukuran posisi menunjukkan letak suatu nilai dalam data yang telah diurutkan. Kuartil membagi data menjadi empat bagian, desil menjadi sepuluh bagian, dan persentil menjadi seratus bagian. Median merupakan kuartil kedua atau persentil ke-50. IQR dihitung dari selisih kuartil ketiga dan pertama, sehingga menggambarkan sebaran 50% data tengah. Outlier dapat ditandai dengan batas bawah \(Q_1-1{,}5(IQR)\) dan batas atas \(Q_3+1{,}5(IQR)\). Cara lain adalah z-score, yaitu jarak suatu nilai dari mean dalam satuan standar deviasi; nilai dengan \(|z|>3\) sering diperiksa sebagai nilai ekstrem. Distribusi dapat simetris atau miring ke kanan maupun kiri. Boxplot merangkum median, kuartil, dan nilai yang berpotensi ekstrem. Outlier tidak langsung dihapus karena dapat berasal dari kesalahan pencatatan atau kejadian nyata yang perlu dijelaskan.

\[ IQR=Q_3-Q_1,\qquad z_i=\frac{x_i-\bar{x}}{s} \] \[ B_{bawah}=Q_1-1{,}5(IQR),\qquad B_{atas}=Q_3+1{,}5(IQR) \]

Contoh singkat di R:

x_posisi <- c(10, 12, 13, 14, 15, 16, 18, 40)
quantile(x_posisi, probs = c(0.1, 0.25, 0.5, 0.75, 0.9))
##   10%   25%   50%   75%   90% 
## 11.40 12.75 14.50 16.50 24.60
IQR(x_posisi)
## [1] 3.75
z_score <- as.numeric(scale(x_posisi))
z_score                                              # z-score tiap data
## [1] -0.76210308 -0.55186775 -0.44675008 -0.34163242 -0.23651475 -0.13139708
## [7]  0.07883825  2.39142691
c(mean = mean(x_posisi), median = median(x_posisi))  # bandingkan mean vs median
##   mean median 
##  17.25  14.50
boxplot(x_posisi, main = "Boxplot Contoh Data", ylab = "Nilai")

Pada distribusi simetris, mean dan median biasanya berdekatan. Pada distribusi right-skewed (miring ke kanan), ekor distribusi memanjang ke nilai besar sehingga mean umumnya lebih tinggi daripada median. Sebaliknya, pada distribusi left-skewed (miring ke kiri), ekor memanjang ke nilai kecil sehingga mean umumnya lebih rendah daripada median. Karena itu, perbandingan mean dan median dapat membantu mengenali kemencengan distribusi, tetapi bentuk histogram dan boxplot tetap perlu diperiksa.

Perbandingan metode IQR dan z-score dalam mendeteksi outlier:

Aspek Metode IQR Metode z-score
Dasar Kuartil (Q1, Q3) Mean dan standar deviasi
Batas Q1 − 1,5·IQR dan Q3 + 1,5·IQR |z| > 2 atau |z| > 3
Pengaruh nilai ekstrem Lebih kebal Ikut ditarik oleh nilai ekstrem
Cocok untuk Distribusi miring Distribusi mendekati simetris

2.7 Minggu 7 – Exploratory Data Analysis (EDA)

Exploratory Data Analysis (EDA) merupakan proses mengeksplorasi data untuk memahami struktur, kualitas, pola, hubungan, dan kemungkinan anomali sebelum membuat kesimpulan. Tahapannya meliputi pemeriksaan kualitas data, analisis univariat, perbandingan kelompok, analisis bivariat atau multivariat, pemeriksaan outlier, dan penyusunan insight. Standardisasi z-score mengubah nilai berdasarkan mean dan standar deviasi sehingga menunjukkan posisi relatif suatu pengamatan. Dalam membandingkan kelompok, center dapat dilihat melalui mean atau median, spread melalui range atau standar deviasi, dan distribution melalui bentuk sebaran. Contohnya, waktu proses dapat dibandingkan antara kanal Online dan Offline untuk melihat perbedaan pusat, variasi, dan pola. EDA membantu menemukan pattern, anomaly, outlier, serta insight yang relevan. Namun, hubungan antarvariabel tidak otomatis membuktikan sebab-akibat; kesimpulan harus didukung tabel, grafik, dan konteks data.

\[ z_i=\frac{x_i-\bar{x}}{s} \]

Contoh singkat di R:

contoh_eda <- data.frame(
  kanal = c("Online", "Online", "Offline", "Offline"),
  waktu = c(12, 15, 18, 22)
)
aggregate(waktu ~ kanal, data = contoh_eda,
          FUN = function(x) c(mean = mean(x), median = median(x), sd = sd(x)))
contoh_eda$z_waktu <- as.numeric(scale(contoh_eda$waktu))
boxplot(waktu ~ kanal, data = contoh_eda,
        xlab = "Kanal", ylab = "Waktu proses (menit)",
        main = "Perbandingan Waktu Proses")

2.8 Ringkasan Rumus

Ukuran Rumus Keterangan
Mean \(\bar{x}=\sum x_i/n\) Rata-rata data
Weighted mean \(\bar{x}_w=\sum w_ix_i/\sum w_i\) Rata-rata berbobot
Varians sampel \(s^2=\sum(x_i-\bar{x})^2/(n-1)\) Sebaran kuadrat
Standar deviasi \(s=\sqrt{s^2}\) Sebaran dalam satuan asli
Koefisien variasi \(CV=(s/\bar{x})\times100\%\) Sebaran relatif
IQR \(Q_3-Q_1\) Rentang 50% data tengah
Batas outlier \(Q_1-1{,}5IQR;\ Q_3+1{,}5IQR\) Batas bawah dan atas
Z-score \((x_i-\bar{x})/s\) Posisi relatif nilai

2.9 Keterkaitan Materi Minggu 1–7 dengan Studi Kasus

Materi Minggu 1–3 menjadi dasar untuk memahami tujuan analisis, jenis variabel, skala pengukuran, sumber data, dan kualitas proses pengumpulan data. Materi Minggu 4 digunakan untuk menyajikan frekuensi serta pola melalui tabel dan grafik. Materi Minggu 5 membantu merangkum pusat dan variasi setiap variabel. Materi Minggu 6 digunakan untuk memahami posisi data dan menandai nilai yang tidak biasa, sedangkan Minggu 7 menjadi alur kerja untuk menggabungkan pemeriksaan tersebut menjadi insight. Dengan demikian, analisis dataset transaksi pada Soal 2 dilakukan secara bertahap dan tetap mempertahankan konteks setiap pengamatan.

3 Soal 2 – Studi Kasus Exploratory Data Analysis

3.1 2.1 Data Understanding dan Data Quality

3.1.1 Import data

Letakkan file Dataset_EDA_30_Observasi.xlsx pada folder yang sama dengan file R Markdown ini sebelum melakukan Knit.

df <- read_excel("Dataset_EDA_30_Observasi.xlsx", sheet = "Data") %>%
  mutate(Tanggal = as.Date(Tanggal))

head(df, 10)

3.1.2 Struktur dan dimensi data

dim(df)
## [1] 30  6
names(df)
## [1] "Tanggal"                 "Kanal"                  
## [3] "Jenis_Layanan"           "Jumlah_Transaksi"       
## [5] "Waktu_Proses_Menit"      "Nilai_Transaksi_Juta_Rp"
str(df)
## tibble [30 × 6] (S3: tbl_df/tbl/data.frame)
##  $ Tanggal                : Date[1:30], format: "2026-01-01" "2026-01-02" ...
##  $ Kanal                  : chr [1:30] "Online" "Offline" "Online" "Offline" ...
##  $ Jenis_Layanan          : chr [1:30] "Reguler" "Reguler" "Reguler" "Express" ...
##  $ Jumlah_Transaksi       : num [1:30] 48 42 55 50 50 52 57 145 70 60 ...
##  $ Waktu_Proses_Menit     : num [1:30] 41.5 42.1 42.6 43.1 42.7 37.7 36.4 37 36.3 33.6 ...
##  $ Nilai_Transaksi_Juta_Rp: num [1:30] 2.26 2.69 2.44 2.17 2.44 2.63 2.58 3.16 3.03 3.13 ...

Dataset terdiri dari 30 baris pengamatan dan 6 variabel. Setiap baris mewakili satu hari pengamatan.

3.1.3 Tipe dan skala pengukuran

tabel_tipe <- tibble(
  Variabel = names(df),
  Jenis_data = c("Temporal", "Kualitatif", "Kualitatif",
                 "Kuantitatif diskrit", "Kuantitatif kontinu", "Kuantitatif kontinu"),
  Skala_pengukuran = c("Interval", "Nominal", "Nominal", "Rasio", "Rasio", "Rasio"),
  Alasan = c(
    "Tanggal memiliki jarak sama antarhari tetapi tidak memiliki nol mutlak.",
    "Online dan Offline merupakan kategori tanpa tingkatan.",
    "Reguler, Express, dan Premium merupakan kategori layanan (ubah ke ordinal jika kamu menganggap berurutan, beri alasan).",
    "Jumlah kejadian transaksi berupa hitungan dan memiliki nol mutlak.",
    "Durasi proses dapat memiliki nilai pecahan dan nol berarti tidak ada durasi.",
    "Nilai uang memiliki nol mutlak dan dapat dibandingkan secara rasio."
  )
)
tampil(tabel_tipe, caption = "Identifikasi jenis data dan skala pengukuran", booktabs = TRUE)
Identifikasi jenis data dan skala pengukuran
Variabel Jenis_data Skala_pengukuran Alasan
Tanggal Temporal Interval Tanggal memiliki jarak sama antarhari tetapi tidak memiliki nol mutlak.
Kanal Kualitatif Nominal Online dan Offline merupakan kategori tanpa tingkatan.
Jenis_Layanan Kualitatif Nominal Reguler, Express, dan Premium merupakan kategori layanan (ubah ke ordinal jika kamu menganggap berurutan, beri alasan).
Jumlah_Transaksi Kuantitatif diskrit Rasio Jumlah kejadian transaksi berupa hitungan dan memiliki nol mutlak.
Waktu_Proses_Menit Kuantitatif kontinu Rasio Durasi proses dapat memiliki nilai pecahan dan nol berarti tidak ada durasi.
Nilai_Transaksi_Juta_Rp Kuantitatif kontinu Rasio Nilai uang memiliki nol mutlak dan dapat dibandingkan secara rasio.

3.1.4 Pemeriksaan kualitas data

cek_kualitas <- tibble(
  Pemeriksaan = c("Jumlah baris", "Jumlah kolom", "Missing value",
                  "Baris duplikat", "Tanggal paling awal", "Tanggal paling akhir"),
  Hasil = c(
    nrow(df), ncol(df),
    sum(is.na(df)),
    sum(duplicated(df)),
    as.character(min(df$Tanggal, na.rm = TRUE)),
    as.character(max(df$Tanggal, na.rm = TRUE))
  )
)
tampil(cek_kualitas, caption = "Ringkasan pemeriksaan kualitas data")
Ringkasan pemeriksaan kualitas data
Pemeriksaan Hasil
Jumlah baris 30
Jumlah kolom 6
Missing value 0
Baris duplikat 0
Tanggal paling awal 2026-01-01
Tanggal paling akhir 2026-01-30
missing_kolom <- tibble(
  Variabel = names(df),
  Jumlah_missing = sapply(df, function(x) sum(is.na(x)))
)
tampil(missing_kolom, caption = "Missing value pada setiap variabel")
Missing value pada setiap variabel
Variabel Jumlah_missing
Tanggal 0
Kanal 0
Jenis_Layanan 0
Jumlah_Transaksi 0
Waktu_Proses_Menit 0
Nilai_Transaksi_Juta_Rp 0

Berdasarkan pemeriksaan tersebut, jumlah missing value adalah 0 dan jumlah baris duplikat adalah 0. Pemeriksaan ini menjadi dasar untuk menentukan kesiapan data sebelum analisis. Nilai ekstrem tidak dihapus pada tahap ini.

Berdasarkan pemeriksaan, dataset memiliki 30 baris dan 6 kolom, tidak terdapat missing value maupun baris duplikat. Variabel Tanggal telah diubah menjadi tipe Date, sedangkan Kanal dan Jenis_Layanan terbaca sebagai variabel kategorikal berbentuk karakter. Tiga variabel lainnya berupa numerik: Jumlah_Transaksi bertipe bilangan bulat, sedangkan Waktu_Proses_Menit dan Nilai_Transaksi_Juta_Rp bertipe numerik desimal. Dengan kondisi tersebut, dataset sudah dapat digunakan untuk analisis awal. Meskipun demikian, nilai ekstrem tetap perlu diperiksa pada tahap berikutnya dan tidak langsung dihapus.

3.2 2.2 Analisis Univariat

3.2.1 Distribusi frekuensi variabel kategorikal

buat_frekuensi <- function(x) {
  hasil <- as.data.frame(table(x), stringsAsFactors = FALSE)
  names(hasil) <- c("Kategori", "Frekuensi")
  hasil %>%
    mutate(
      Frekuensi_Relatif = Frekuensi / sum(Frekuensi),
      Persentase = percent(Frekuensi_Relatif, accuracy = 0.1),
      Frekuensi_Kumulatif = cumsum(Frekuensi)
    )
}

freq_kanal <- buat_frekuensi(df$Kanal)
freq_layanan <- buat_frekuensi(df$Jenis_Layanan)

tampil(freq_kanal, caption = "Distribusi frekuensi Kanal")
Distribusi frekuensi Kanal
Kategori Frekuensi Frekuensi_Relatif Persentase Frekuensi_Kumulatif
Offline 15 0.5 50.0% 15
Online 15 0.5 50.0% 30
tampil(freq_layanan, caption = "Distribusi frekuensi Jenis Layanan")
Distribusi frekuensi Jenis Layanan
Kategori Frekuensi Frekuensi_Relatif Persentase Frekuensi_Kumulatif
Express 10 0.3333333 33.3% 10
Premium 10 0.3333333 33.3% 20
Reguler 10 0.3333333 33.3% 30

Frekuensi kumulatif pada tabel kategori mengikuti urutan kategori yang ditampilkan. Karena kanal dan jenis layanan berskala nominal, frekuensi kumulatif tidak menunjukkan tingkatan alami antarkategori.

3.2.2 Statistik deskriptif variabel numerik

modus <- function(x) {
  x <- x[!is.na(x)]
  nilai <- unique(x)
  frek <- tabulate(match(x, nilai))
  nilai[frek == max(frek)]
}

variabel_numerik <- c("Jumlah_Transaksi", "Waktu_Proses_Menit",
                      "Nilai_Transaksi_Juta_Rp")

stat_deskriptif <- map_dfr(variabel_numerik, function(v) {
  x <- df[[v]]
  tibble(
    Variabel = v,
    Mean = mean(x, na.rm = TRUE),
    Median = median(x, na.rm = TRUE),
    Modus = paste(modus(x), collapse = ", "),
    Minimum = min(x, na.rm = TRUE),
    Maksimum = max(x, na.rm = TRUE),
    Rentang = diff(range(x, na.rm = TRUE)),
    Varians = var(x, na.rm = TRUE),
    Standar_Deviasi = sd(x, na.rm = TRUE),
    CV_persen = sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE) * 100
  )
})
tampil(stat_deskriptif, digits = 2,
      caption = "Statistik deskriptif variabel numerik")
Statistik deskriptif variabel numerik
Variabel Mean Median Modus Minimum Maksimum Rentang Varians Standar_Deviasi CV_persen
Jumlah_Transaksi 73.83 72.00 50, 71, 73, 87 12.00 145.0 133.00 599.45 24.48 33.16
Waktu_Proses_Menit 32.66 30.10 30.1, 26.6 3.50 88.0 84.50 181.32 13.47 41.23
Nilai_Transaksi_Juta_Rp 3.18 3.13 2.44, 3.13 0.12 9.8 9.68 2.09 1.45 45.46
# Jumlah kelas Sturges
k_sturges <- ceiling(1 + 3.322 * log10(nrow(df)))
k_sturges
## [1] 6
# Pembanding mean-median dan urutan CV
stat_deskriptif %>%
  mutate(Mean_minus_Median = Mean - Median) %>%
  select(Variabel, Mean, Median, Mean_minus_Median, CV_persen) %>%
  arrange(desc(CV_persen)) %>%
  tampil(digits = 2, caption = "Pembanding mean-median dan koefisien variasi")
Pembanding mean-median dan koefisien variasi
Variabel Mean Median Mean_minus_Median CV_persen
Nilai_Transaksi_Juta_Rp 3.18 3.13 0.05 45.46
Waktu_Proses_Menit 32.66 30.10 2.56 41.23
Jumlah_Transaksi 73.83 72.00 1.83 33.16

3.2.3 Diagram batang dan lingkaran

ggplot(df, aes(x = Kanal, fill = Kanal)) +
  geom_bar(width = 0.65, show.legend = FALSE) +
  geom_text(stat = "count", aes(label = after_stat(count)), vjust = -0.5) +
  scale_fill_manual(values = c("Online" = "#4C91B8", "Offline" = "#E6A15C")) +
  labs(title = "Frekuensi Transaksi Berdasarkan Kanal",
       x = "Kanal transaksi", y = "Jumlah pengamatan") +
  tema_uts

pie_data <- df %>% count(Jenis_Layanan) %>%
  mutate(label = paste0(Jenis_Layanan, "\n", percent(n / sum(n), accuracy = 0.1)))
ggplot(pie_data, aes(x = "", y = n, fill = Jenis_Layanan)) +
  geom_col(width = 1, color = "white") +
  coord_polar(theta = "y") +
  geom_text(aes(label = label), position = position_stack(vjust = 0.5),
            size = 3.5) +
  labs(title = "Proporsi Jenis Layanan", x = NULL, y = NULL, fill = "Layanan") +
  tema_uts + theme(axis.text = element_blank(), axis.ticks = element_blank(),
                   panel.grid = element_blank())

Distribusi kanal seimbang: Online berjumlah 15 hari (50%) dan Offline juga 15 hari (50%). Distribusi jenis layanan juga merata, yaitu Reguler 10 hari (33,3%), Express 10 hari (33,3%), dan Premium 10 hari (33,3%). Dengan demikian, tidak ada satu kanal atau jenis layanan yang memiliki frekuensi penggunaan paling tinggi; seluruh kategori memiliki jumlah pengamatan yang sama.

3.2.4 Histogram variabel numerik

Jumlah kelas histogram menggunakan pendekatan Sturges, yaitu \(k=1+3{,}322\log_{10}(n)\). Batas kelas disesuaikan otomatis oleh fungsi histogram. Untuk n = 30, aturan Sturges menghasilkan k = 6 kelas.

par(mfrow = c(3, 1), mar = c(4, 4, 3, 1))
for (v in variabel_numerik) {
  x <- df[[v]]
  hist(x, breaks = "Sturges", col = "#8DB7CC", border = "white",
       main = paste("Histogram", v),
       xlab = v, ylab = "Frekuensi")
}

par(mfrow = c(1, 1))

Jumlah transaksi memiliki distribusi yang relatif mendekati simetris, meskipun sedikit menceng ke kanan karena mean (73,83) sedikit lebih besar daripada median (72). Waktu proses dan nilai transaksi cenderung menceng ke kanan; mean waktu proses (32,66 menit) lebih tinggi daripada median (30,10 menit), sedangkan mean nilai transaksi (3,179 juta rupiah) sedikit lebih tinggi daripada median (3,13 juta rupiah). Nilai tinggi pada beberapa pengamatan ikut memperpanjang ekor kanan. Koefisien variasi tertinggi terdapat pada nilai transaksi, yaitu 45,46%, diikuti waktu proses 41,23% dan jumlah transaksi 33,16%. CV lebih tepat untuk membandingkan variasi relatif karena ketiga variabel memiliki satuan dan skala berbeda, sedangkan standar deviasi tetap menggunakan satuan asli masing-masing variabel.

3.2.5 Boxplot setiap variabel numerik

data_long <- df %>%
  select(all_of(variabel_numerik)) %>%
  pivot_longer(everything(), names_to = "Variabel", values_to = "Nilai")

ggplot(data_long, aes(x = "", y = Nilai)) +
  geom_boxplot(fill = "#8DB7CC", color = "#24536A", width = 0.45) +
  facet_wrap(~ Variabel, scales = "free_y", ncol = 1) +
  labs(title = "Boxplot Variabel Numerik", x = NULL, y = "Nilai") +
  tema_uts

df %>%
  mutate(Obs_ke = row_number()) %>%
  pivot_longer(all_of(variabel_numerik), names_to = "Variabel", values_to = "Nilai") %>%
  group_by(Variabel) %>%
  filter(Nilai == max(Nilai) | Nilai == min(Nilai)) %>%
  arrange(Variabel, Nilai) %>%
  tampil(digits = 2, caption = "Nilai minimum dan maksimum tiap variabel")
Nilai minimum dan maksimum tiap variabel
Tanggal Kanal Jenis_Layanan Obs_ke Variabel Nilai
2026-01-23 Online Express 23 Jumlah_Transaksi 12.00
2026-01-08 Online Express 8 Jumlah_Transaksi 145.00
2026-01-28 Offline Premium 28 Nilai_Transaksi_Juta_Rp 0.12
2026-01-17 Offline Premium 17 Nilai_Transaksi_Juta_Rp 9.80
2026-01-26 Online Express 26 Waktu_Proses_Menit 3.50
2026-01-12 Offline Express 12 Waktu_Proses_Menit 88.00

Boxplot menunjukkan nilai yang berada di luar batas IQR pada ketiga variabel numerik. Pada jumlah transaksi, nilai ekstrem terdapat pada observasi ke-8 (145 transaksi) dan ke-23 (12 transaksi). Pada waktu proses, nilai ekstrem terdapat pada observasi ke-12 (88 menit) dan ke-26 (3,5 menit). Pada nilai transaksi, nilai ekstrem terdapat pada observasi ke-17 (9,80 juta rupiah) dan ke-28 (0,12 juta rupiah). Titik-titik tersebut perlu diperiksa lebih lanjut karena dapat memengaruhi ringkasan statistik dan pola visual.

3.3 2.3 Analisis Bivariat

3.3.1 Ringkasan numerik berdasarkan kanal

ringkasan_kanal <- df %>%
  group_by(Kanal) %>%
  summarise(
    Jumlah_hari = n(),
    Rata_rata_transaksi = mean(Jumlah_Transaksi, na.rm = TRUE),
    Median_transaksi = median(Jumlah_Transaksi, na.rm = TRUE),
    Rata_rata_waktu = mean(Waktu_Proses_Menit, na.rm = TRUE),
    Rata_rata_nilai = mean(Nilai_Transaksi_Juta_Rp, na.rm = TRUE),
    .groups = "drop"
  )
tampil(ringkasan_kanal, digits = 2,
      caption = "Perbandingan ringkasan berdasarkan kanal")
Perbandingan ringkasan berdasarkan kanal
Kanal Jumlah_hari Rata_rata_transaksi Median_transaksi Rata_rata_waktu Rata_rata_nilai
Offline 15 74.80 74 34.72 3.33
Online 15 72.87 71 30.59 3.03
ringkasan_kanal_lengkap <- df %>%
  group_by(Kanal) %>%
  summarise(across(all_of(variabel_numerik),
                   list(Mean = mean, Median = median, SD = sd),
                   .names = "{.col}__{.fn}"), .groups = "drop") %>%
  pivot_longer(-Kanal, names_to = c("Variabel", "Statistik"),
               names_sep = "__", values_to = "Nilai") %>%
  pivot_wider(names_from = Statistik, values_from = Nilai)

tampil(ringkasan_kanal_lengkap, digits = 2,
      caption = "Mean, median, dan SD ketiga variabel berdasarkan kanal")
Mean, median, dan SD ketiga variabel berdasarkan kanal
Kanal Variabel Mean Median SD
Offline Jumlah_Transaksi 74.80 74.00 19.58
Offline Waktu_Proses_Menit 34.72 29.70 16.68
Offline Nilai_Transaksi_Juta_Rp 3.33 3.22 2.02
Online Jumlah_Transaksi 72.87 71.00 29.26
Online Waktu_Proses_Menit 30.59 31.80 9.40
Online Nilai_Transaksi_Juta_Rp 3.03 3.13 0.46

3.3.2 Rata-rata jumlah transaksi berdasarkan kanal

ggplot(ringkasan_kanal, aes(x = Kanal, y = Rata_rata_transaksi, fill = Kanal)) +
  geom_col(width = 0.6, show.legend = FALSE) +
  geom_text(aes(label = round(Rata_rata_transaksi, 1)), vjust = -0.5) +
  scale_fill_manual(values = c("Online" = "#4C91B8", "Offline" = "#E6A15C")) +
  labs(title = "Rata-rata Jumlah Transaksi Berdasarkan Kanal",
       x = "Kanal", y = "Rata-rata transaksi per hari") +
  tema_uts

3.3.3 Waktu proses berdasarkan kanal

ggplot(df, aes(x = Kanal, y = Waktu_Proses_Menit, fill = Kanal)) +
  geom_boxplot(alpha = 0.85, show.legend = FALSE) +
  scale_fill_manual(values = c("Online" = "#4C91B8", "Offline" = "#E6A15C")) +
  labs(title = "Sebaran Waktu Proses Berdasarkan Kanal",
       x = "Kanal", y = "Waktu proses (menit)") +
  tema_uts

Rata-rata jumlah transaksi Online adalah 72,87 per hari, sedikit lebih rendah daripada Offline sebesar 74,80. Median transaksi juga menunjukkan pola yang sama, yaitu 71 untuk Online dan 74 untuk Offline. Namun, sebaran jumlah transaksi Online lebih besar (SD 29,26) dibandingkan Offline (SD 19,58). Untuk waktu proses, median Online sebesar 31,8 menit dan Offline 29,7 menit, tetapi rata-rata Offline lebih tinggi, yaitu 34,72 menit dibandingkan Online 30,59 menit. Standar deviasi waktu Offline juga lebih besar (16,68 menit) daripada Online (9,40 menit). Ini menunjukkan waktu proses Offline lebih bervariasi dan rata-ratanya terdorong naik oleh nilai tinggi, terutama 88 menit pada salah satu pengamatan.

3.3.4 Nilai transaksi berdasarkan jenis layanan

ggplot(df, aes(x = Jenis_Layanan, y = Nilai_Transaksi_Juta_Rp,
               fill = Jenis_Layanan)) +
  geom_boxplot(show.legend = FALSE, alpha = 0.85) +
  scale_fill_manual(values = c("Reguler" = "#8DB7CC",
                               "Express" = "#E6A15C",
                               "Premium" = "#8BB99B")) +
  labs(title = "Sebaran Nilai Transaksi Berdasarkan Jenis Layanan",
       x = "Jenis layanan", y = "Nilai transaksi (juta rupiah)") +
  tema_uts

Berdasarkan median, layanan Premium memiliki nilai transaksi relatif paling tinggi, yaitu 3,30 juta rupiah, dibandingkan Express sebesar 3,06 juta dan Reguler sebesar 2,935 juta. Rata-rata Premium juga paling tinggi, yaitu 3,605 juta rupiah. Namun, rata-rata tersebut dipengaruhi nilai ekstrem 9,80 juta rupiah pada observasi ke-17. Karena itu, median lebih mewakili nilai transaksi Premium yang tipikal dibandingkan mean pada data ini.

3.3.5 Hubungan jumlah transaksi dan nilai transaksi

ggplot(df, aes(x = Jumlah_Transaksi, y = Nilai_Transaksi_Juta_Rp,
               color = Jenis_Layanan)) +
  geom_point(size = 2.8, alpha = 0.85) +
  geom_smooth(aes(group = 1), method = "lm", se = TRUE,
              color = "#333333", linewidth = 0.8) +
  labs(title = "Hubungan Jumlah Transaksi dan Nilai Transaksi",
       x = "Jumlah transaksi", y = "Nilai transaksi (juta rupiah)",
       color = "Jenis layanan") +
  tema_uts

korelasi <- cor(df$Jumlah_Transaksi, df$Nilai_Transaksi_Juta_Rp,
                use = "complete.obs")
tibble(Hubungan = "Jumlah transaksi dan nilai transaksi",
       Korelasi_Pearson = korelasi)

Nilai korelasi Pearson sebesar 0.113 menunjukkan arah dan kekuatan hubungan linear pada dua variabel tersebut. Korelasi tidak membuktikan bahwa perubahan jumlah transaksi menyebabkan perubahan nilai transaksi.

3.3.6 Hubungan jumlah transaksi dan waktu proses

ggplot(df, aes(x = Jumlah_Transaksi, y = Waktu_Proses_Menit)) +
  geom_point(aes(color = Kanal), size = 2.8, alpha = 0.85) +
  geom_smooth(method = "lm", se = TRUE, color = "#333333", linewidth = 0.8) +
  labs(title = "Hubungan Jumlah Transaksi dan Waktu Proses",
       x = "Jumlah transaksi", y = "Waktu proses (menit)", color = "Kanal") +
  tema_uts

cor_tw <- cor(df$Jumlah_Transaksi, df$Waktu_Proses_Menit)
cor_tw
## [1] -0.3551632
# Observasi yang menyimpang dari garis tren (|residual standar| > 2)
m_tw <- lm(Waktu_Proses_Menit ~ Jumlah_Transaksi, data = df)
m_tn <- lm(Nilai_Transaksi_Juta_Rp ~ Jumlah_Transaksi, data = df)

menyimpang <- bind_rows(
  df %>% mutate(Obs_ke = row_number(), Hubungan = "Transaksi vs Waktu",
                Residual_std = rstandard(m_tw)),
  df %>% mutate(Obs_ke = row_number(), Hubungan = "Transaksi vs Nilai",
                Residual_std = rstandard(m_tn))
) %>%
  filter(abs(Residual_std) > 2) %>%
  select(Hubungan, Obs_ke, Tanggal, Kanal, Jenis_Layanan, Residual_std)

tampil(menyimpang, digits = 2, caption = "Observasi menyimpang dari pola hubungan")
Observasi menyimpang dari pola hubungan
Hubungan Obs_ke Tanggal Kanal Jenis_Layanan Residual_std
Transaksi vs Waktu 12 2026-01-12 Offline Express 4.29
Transaksi vs Nilai 17 2026-01-17 Offline Premium 4.61
Transaksi vs Nilai 28 2026-01-28 Offline Premium -2.27

Korelasi jumlah transaksi dengan nilai transaksi sebesar 0,113 menunjukkan hubungan positif yang sangat lemah. Sementara itu, korelasi jumlah transaksi dengan waktu proses sebesar -0,355 menunjukkan hubungan negatif yang lemah hingga sedang. Jadi, pada data ini jumlah transaksi yang lebih tinggi tidak selalu diikuti nilai transaksi yang lebih tinggi, dan cenderung berkaitan dengan waktu proses yang lebih rendah. Tabel observasi menyimpang menunjukkan observasi ke-12 pada hubungan transaksi-waktu, serta observasi ke-17 dan ke-28 pada hubungan transaksi-nilai. Pengamatan tersebut perlu ditinjau karena posisinya cukup jauh dari pola garis regresi.

3.4 2.4 Analisis Multivariat

3.4.1 Scatter plot multivariat

ggplot(df, aes(x = Jumlah_Transaksi, y = Nilai_Transaksi_Juta_Rp,
               color = Kanal, size = Waktu_Proses_Menit)) +
  geom_point(alpha = 0.7) +
  scale_color_manual(values = c("Online" = "#4C91B8", "Offline" = "#E6A15C")) +
  labs(title = "Jumlah vs Nilai Transaksi menurut Kanal dan Waktu Proses",
       x = "Jumlah transaksi", y = "Nilai transaksi (juta rupiah)",
       color = "Kanal", size = "Waktu proses (menit)") +
  tema_uts

df %>%
  group_by(Kanal) %>%
  summarise(Korelasi = cor(Jumlah_Transaksi, Nilai_Transaksi_Juta_Rp), .groups = "drop") %>%
  tampil(digits = 3, caption = "Korelasi jumlah dan nilai transaksi per kanal")
Korelasi jumlah dan nilai transaksi per kanal
Kanal Korelasi
Offline 0.107
Online 0.279

Korelasi jumlah transaksi dan nilai transaksi bernilai positif pada kedua kanal, tetapi kekuatannya berbeda. Pada kanal Online, korelasi sebesar 0,279, sedangkan pada Offline sebesar 0,107. Keduanya tergolong lemah, sehingga hubungan linear jumlah transaksi dengan nilai transaksi tidak kuat. Pola Online terlihat sedikit lebih erat dibandingkan Offline, tetapi selisih ini perlu dibaca secara hati-hati karena setiap kanal hanya memiliki 15 pengamatan.

3.4.2 Waktu proses menurut kombinasi layanan dan kanal

ggplot(df, aes(x = Jenis_Layanan, y = Waktu_Proses_Menit, fill = Kanal)) +
  geom_boxplot(position = position_dodge(width = 0.8), alpha = 0.85) +
  scale_fill_manual(values = c("Online" = "#4C91B8", "Offline" = "#E6A15C")) +
  labs(title = "Waktu Proses menurut Jenis Layanan dan Kanal",
       x = "Jenis layanan", y = "Waktu proses (menit)", fill = "Kanal") +
  tema_uts

count(df, Kanal, Jenis_Layanan) %>%
  tampil(caption = "Jumlah observasi per kombinasi kanal dan layanan")
Jumlah observasi per kombinasi kanal dan layanan
Kanal Jenis_Layanan n
Offline Express 5
Offline Premium 5
Offline Reguler 5
Online Express 5
Online Premium 5
Online Reguler 5

Setiap kombinasi kanal dan jenis layanan terdiri atas 5 pengamatan, sehingga perbandingan perlu ditafsirkan secara hati-hati. Median waktu proses tertinggi terdapat pada kombinasi Offline-Express, yaitu 42,7 menit. Pada Online, median tertinggi terdapat pada layanan Reguler sebesar 36,3 menit, sedangkan Express 28,6 menit dan Premium 29,4 menit. Pada Offline, median Reguler 29,7 menit dan Premium 26,9 menit. Perbedaan ini menunjukkan bahwa waktu proses tidak hanya berkaitan dengan kanal, tetapi juga dapat berbeda menurut jenis layanan. Jumlah pengamatan yang terbatas membuat hasil ini lebih tepat dipandang sebagai indikasi awal.

3.4.3 Pola jumlah transaksi dan waktu proses dari waktu ke waktu

tren_long <- df %>%
  select(Tanggal, Jumlah_Transaksi, Waktu_Proses_Menit) %>%
  pivot_longer(-Tanggal, names_to = "Variabel", values_to = "Nilai")

ggplot(tren_long, aes(x = Tanggal, y = Nilai, color = Variabel)) +
  geom_line(linewidth = 0.8) +
  geom_point(size = 1.8) +
  geom_smooth(method = "lm", se = FALSE, linetype = "dashed", linewidth = 0.6) +
  facet_wrap(~ Variabel, scales = "free_y", ncol = 1) +
  scale_x_date(date_labels = "%d %b", date_breaks = "5 days") +
  labs(title = "Perubahan Jumlah Transaksi dan Waktu Proses",
       x = "Tanggal", y = "Nilai", color = "Variabel") +
  tema_uts + theme(axis.text.x = element_text(angle = 45, hjust = 1))

df_tren <- df %>% mutate(Hari_ke = as.numeric(Tanggal - min(Tanggal)) + 1)
m_trx <- lm(Jumlah_Transaksi ~ Hari_ke, data = df_tren)
m_wkt <- lm(Waktu_Proses_Menit ~ Hari_ke, data = df_tren)

tibble(
  Variabel = c("Jumlah_Transaksi", "Waktu_Proses_Menit"),
  Slope_per_hari = c(coef(m_trx)[2], coef(m_wkt)[2]),
  R2 = c(summary(m_trx)$r.squared, summary(m_wkt)$r.squared),
  p_value = c(summary(m_trx)$coefficients[2, 4], summary(m_wkt)$coefficients[2, 4])
) %>%
  tampil(digits = 4, caption = "Kecenderungan tren linear selama 30 hari")
Kecenderungan tren linear selama 30 hari
Variabel Slope_per_hari R2 p_value
Jumlah_Transaksi 1.4138 0.2584 0.0041
Waktu_Proses_Menit -0.9405 0.3781 0.0003

Selama periode pengamatan, jumlah transaksi menunjukkan kecenderungan meningkat dengan slope sekitar 1,414 transaksi per hari. Nilai R² sebesar 0,258 berarti tren linear menjelaskan sekitar 25,8% variasi jumlah transaksi, dan p-value 0,0041 menunjukkan tren tersebut signifikan secara statistik pada taraf 5%. Sebaliknya, waktu proses cenderung menurun dengan slope sekitar 0,941 menit per hari. R² sebesar 0,378 dan p-value 0,0003 menunjukkan tren penurunan linear yang signifikan pada taraf 5%. Meski demikian, pola ini menggambarkan periode 30 hari yang diamati dan belum cukup untuk memastikan bahwa tren akan terus berlanjut.

3.4.4 Hubungan beberapa variabel numerik

mat_korelasi <- cor(df %>% select(all_of(variabel_numerik)),
                    use = "pairwise.complete.obs")
korelasi_long <- as.data.frame(as.table(mat_korelasi)) %>%
  rename(Variabel_1 = Var1, Variabel_2 = Var2, Korelasi = Freq)

ggplot(korelasi_long, aes(x = Variabel_1, y = Variabel_2, fill = Korelasi)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(Korelasi, 2)), size = 4) +
  scale_fill_gradient2(low = "#C76D6D", mid = "white", high = "#4C91B8",
                       midpoint = 0, limits = c(-1, 1)) +
  labs(title = "Matriks Korelasi Variabel Numerik",
       x = NULL, y = NULL, fill = "Korelasi") +
  tema_uts + theme(axis.text.x = element_text(angle = 25, hjust = 1))

korelasi_long %>%
  filter(as.character(Variabel_1) < as.character(Variabel_2)) %>%
  arrange(desc(abs(Korelasi))) %>%
  tampil(digits = 3, caption = "Pasangan variabel diurutkan dari korelasi terkuat")
Pasangan variabel diurutkan dari korelasi terkuat
Variabel_1 Variabel_2 Korelasi
Jumlah_Transaksi Waktu_Proses_Menit -0.355
Nilai_Transaksi_Juta_Rp Waktu_Proses_Menit -0.204
Jumlah_Transaksi Nilai_Transaksi_Juta_Rp 0.113

Pasangan dengan korelasi absolut paling kuat adalah jumlah transaksi dan waktu proses, dengan nilai -0,355, sehingga arahnya negatif dan kekuatannya lemah hingga sedang. Hubungan waktu proses dengan nilai transaksi sebesar -0,204 juga negatif tetapi lebih lemah, sedangkan jumlah transaksi dengan nilai transaksi sebesar 0,113 positif sangat lemah. Korelasi hanya menunjukkan keeratan hubungan linear, bukan bukti bahwa satu variabel menyebabkan perubahan variabel lain. Faktor lain seperti jenis layanan, kanal, kapasitas operasional, atau perubahan dari waktu ke waktu dapat ikut memengaruhi pola tersebut.

3.4.5 Perbandingan kanal dan jenis layanan

ringkasan_kombinasi <- df %>%
  group_by(Kanal, Jenis_Layanan) %>%
  summarise(
    Jumlah_hari = n(),
    Rata_rata_transaksi = mean(Jumlah_Transaksi, na.rm = TRUE),
    Rata_rata_waktu = mean(Waktu_Proses_Menit, na.rm = TRUE),
    Rata_rata_nilai = mean(Nilai_Transaksi_Juta_Rp, na.rm = TRUE),
    .groups = "drop"
  )
tampil(ringkasan_kombinasi, digits = 2,
      caption = "Ringkasan gabungan kanal dan jenis layanan")
Ringkasan gabungan kanal dan jenis layanan
Kanal Jenis_Layanan Jumlah_hari Rata_rata_transaksi Rata_rata_waktu Rata_rata_nilai
Offline Express 5 65.4 46.30 2.78
Offline Premium 5 82.2 26.88 4.02
Offline Reguler 5 76.8 30.98 3.18
Online Express 5 80.2 25.16 3.25
Online Premium 5 76.6 29.56 3.19
Online Reguler 5 61.8 37.06 2.65
ggplot(ringkasan_kombinasi,
       aes(x = Jenis_Layanan, y = Kanal, fill = Rata_rata_transaksi)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(Rata_rata_transaksi, 1)), size = 4) +
  scale_fill_gradient(low = "#EAF2F5", high = "#286783") +
  labs(title = "Rata-rata Transaksi Menurut Kanal dan Layanan",
       x = "Jenis layanan", y = "Kanal",
       fill = "Rata-rata transaksi") +
  tema_uts

Analisis multivariat memperlihatkan beberapa variabel secara bersamaan. Grafik tren digunakan untuk membaca perubahan antarhari, matriks korelasi untuk melihat hubungan linear antarkuantitas numerik, dan tabel/heatmap gabungan untuk membandingkan kanal serta jenis layanan. Hasilnya perlu dibaca bersama ukuran ringkasan karena hubungan statistik tidak otomatis menunjukkan hubungan sebab-akibat.

3.5 2.5 Deteksi dan Evaluasi Outlier

Deteksi dilakukan menggunakan batas IQR dan z-score. Pengamatan dengan \(|z|>2\) ditandai sebagai nilai yang perlu diperhatikan, sedangkan \(|z|>3\) ditandai sebagai outlier ekstrem berdasarkan pedoman tugas. Batas IQR menggunakan 1,5 kali IQR.

tabel_iqr <- map_dfr(variabel_numerik, function(v) {
  x <- df[[v]]
  q1 <- as.numeric(quantile(x, 0.25, na.rm = TRUE))
  q3 <- as.numeric(quantile(x, 0.75, na.rm = TRUE))
  i <- q3 - q1
  tibble(Variabel = v, Q1 = q1, Q3 = q3, IQR = i,
         Batas_Bawah = q1 - 1.5 * i, Batas_Atas = q3 + 1.5 * i)
})
tampil(tabel_iqr, digits = 2, caption = "Perhitungan IQR dan batas outlier")
Perhitungan IQR dan batas outlier
Variabel Q1 Q3 IQR Batas_Bawah Batas_Atas
Jumlah_Transaksi 57.75 87.00 29.25 13.88 130.88
Waktu_Proses_Menit 26.68 36.90 10.22 11.34 52.24
Nilai_Transaksi_Juta_Rp 2.59 3.46 0.87 1.29 4.77
hasil_outlier <- map_dfr(variabel_numerik, function(v) {
  x <- df[[v]]
  q1 <- quantile(x, 0.25, na.rm = TRUE)
  q3 <- quantile(x, 0.75, na.rm = TRUE)
  iqr_x <- IQR(x, na.rm = TRUE)
  batas_bawah <- q1 - 1.5 * iqr_x
  batas_atas <- q3 + 1.5 * iqr_x
  z <- (x - mean(x, na.rm = TRUE)) / sd(x, na.rm = TRUE)

  tibble(
    Obs_ke = seq_along(x),
    Tanggal = df$Tanggal,
    Variabel = v,
    Nilai = x,
    Batas_IQR_Bawah = as.numeric(batas_bawah),
    Batas_IQR_Atas = as.numeric(batas_atas),
    Z_score = as.numeric(z),
    Outlier_IQR = x < batas_bawah | x > batas_atas,
    Perlu_diperhatikan_z = abs(z) > 2,
    Outlier_ekstrem_z = abs(z) > 3
  )
})

tabel_outlier <- hasil_outlier %>%
  filter(Outlier_IQR | Perlu_diperhatikan_z) %>%
  arrange(Variabel, Tanggal)

tampil(tabel_outlier, digits = 2,
      caption = "Pengamatan yang terdeteksi oleh IQR atau |z-score| > 2")
Pengamatan yang terdeteksi oleh IQR atau |z-score| > 2
Obs_ke Tanggal Variabel Nilai Batas_IQR_Bawah Batas_IQR_Atas Z_score Outlier_IQR Perlu_diperhatikan_z Outlier_ekstrem_z
8 2026-01-08 Jumlah_Transaksi 145.00 13.88 130.88 2.91 TRUE TRUE FALSE
23 2026-01-23 Jumlah_Transaksi 12.00 13.88 130.88 -2.53 TRUE TRUE FALSE
17 2026-01-17 Nilai_Transaksi_Juta_Rp 9.80 1.29 4.77 4.58 TRUE TRUE TRUE
28 2026-01-28 Nilai_Transaksi_Juta_Rp 0.12 1.29 4.77 -2.12 TRUE TRUE FALSE
12 2026-01-12 Waktu_Proses_Menit 88.00 11.34 52.24 4.11 TRUE TRUE TRUE
26 2026-01-26 Waktu_Proses_Menit 3.50 11.34 52.24 -2.17 TRUE TRUE FALSE
# Data lengkap pada hari yang terdeteksi (untuk menilai anomali operasional)
tgl_outlier <- hasil_outlier %>%
  filter(Outlier_IQR | Perlu_diperhatikan_z) %>%
  pull(Tanggal) %>%
  unique()

df %>%
  mutate(Obs_ke = row_number()) %>%
  filter(Tanggal %in% tgl_outlier) %>%
  tampil(digits = 2, caption = "Data lengkap pada hari yang terdeteksi outlier")
Data lengkap pada hari yang terdeteksi outlier
Tanggal Kanal Jenis_Layanan Jumlah_Transaksi Waktu_Proses_Menit Nilai_Transaksi_Juta_Rp Obs_ke
2026-01-08 Online Express 145 37.0 3.16 8
2026-01-12 Offline Express 67 88.0 2.51 12
2026-01-17 Offline Premium 74 27.8 9.80 17
2026-01-23 Online Express 12 26.6 3.58 23
2026-01-26 Online Express 100 3.5 3.69 26
2026-01-28 Offline Premium 96 19.2 0.12 28

3.5.1 Jumlah outlier per variabel

jumlah_outlier <- hasil_outlier %>%
  group_by(Variabel) %>%
  summarise(
    Jumlah_IQR = sum(Outlier_IQR, na.rm = TRUE),
    Jumlah_z_di_atas_2 = sum(Perlu_diperhatikan_z, na.rm = TRUE),
    Jumlah_z_di_atas_3 = sum(Outlier_ekstrem_z, na.rm = TRUE),
    .groups = "drop"
  )
tampil(jumlah_outlier, caption = "Jumlah penanda outlier berdasarkan metode")
Jumlah penanda outlier berdasarkan metode
Variabel Jumlah_IQR Jumlah_z_di_atas_2 Jumlah_z_di_atas_3
Jumlah_Transaksi 2 2 0
Nilai_Transaksi_Juta_Rp 2 2 1
Waktu_Proses_Menit 2 2 1

3.5.2 Boxplot untuk pemeriksaan visual

ggplot(data_long, aes(x = "", y = Nilai)) +
  geom_boxplot(fill = "#E6AD65", color = "#805A2B", outlier.color = "#B33A3A") +
  facet_wrap(~ Variabel, scales = "free_y", ncol = 1) +
  labs(title = "Pemeriksaan Visual Nilai Ekstrem",
       x = NULL, y = "Nilai") +
  tema_uts

# Data asli tidak diubah; hanya membandingkan ringkasan dengan dan tanpa outlier IQR
sensitivitas <- map_dfr(variabel_numerik, function(v) {
  d <- hasil_outlier %>% filter(Variabel == v)
  tibble(Variabel = v,
         Mean_semua = mean(d$Nilai),
         Mean_tanpa_outlier = mean(d$Nilai[!d$Outlier_IQR]),
         SD_semua = sd(d$Nilai),
         SD_tanpa_outlier = sd(d$Nilai[!d$Outlier_IQR]))
})
tampil(sensitivitas, digits = 2,
      caption = "Perbandingan mean dan SD dengan dan tanpa outlier IQR")
Perbandingan mean dan SD dengan dan tanpa outlier IQR
Variabel Mean_semua Mean_tanpa_outlier SD_semua SD_tanpa_outlier
Jumlah_Transaksi 73.83 73.50 24.48 17.74
Waktu_Proses_Menit 32.66 31.72 13.47 6.99
Nilai_Transaksi_Juta_Rp 3.18 3.05 1.45 0.51
df_tanpa <- df %>% filter(!(Tanggal %in% tgl_outlier))
c(korelasi_semua = cor(df$Jumlah_Transaksi, df$Nilai_Transaksi_Juta_Rp),
  korelasi_tanpa_outlier = cor(df_tanpa$Jumlah_Transaksi, df_tanpa$Nilai_Transaksi_Juta_Rp))
##         korelasi_semua korelasi_tanpa_outlier 
##              0.1127959              0.8882371

Metode IQR menemukan 2 outlier pada setiap variabel numerik. Hasilnya sama dengan penanda |z-score| > 2: jumlah transaksi pada observasi ke-8 (145; 8 Januari 2026) dan ke-23 (12; 23 Januari 2026), waktu proses pada observasi ke-12 (88 menit; 12 Januari 2026) dan ke-26 (3,5 menit; 26 Januari 2026), serta nilai transaksi pada observasi ke-17 (9,80 juta; 17 Januari 2026) dan ke-28 (0,12 juta; 28 Januari 2026). Namun, dengan batas lebih ketat |z| > 3, hanya waktu proses observasi ke-12 dan nilai transaksi observasi ke-17 yang tergolong ekstrem; jumlah transaksi tidak memiliki nilai dengan |z| > 3. Standardisasi z-score membantu membandingkan posisi relatif nilai dari variabel yang satuannya berbeda karena semuanya dinyatakan dalam satuan standar deviasi. Outlier adalah nilai yang tidak biasa secara statistik, sedangkan anomali operasional memerlukan bukti bahwa nilai tersebut mencerminkan kejadian atau masalah proses yang tidak wajar. Dataset belum menjelaskan penyebab keenam tanggal tersebut, sehingga belum dapat dipastikan sebagai anomali. Pengaruhnya terlihat pada standar deviasi: jumlah transaksi turun dari 24,48 menjadi 17,74 setelah dua outlier IQR pada variabel itu dikeluarkan; waktu proses turun dari 13,47 menjadi 6,99; dan nilai transaksi turun dari 1,45 menjadi 0,51. Mean juga berubah, misalnya mean waktu proses dari 32,66 menjadi 31,72 menit. Dalam uji sensitivitas kode, korelasi jumlah transaksi dan nilai transaksi berubah dari 0,113 menjadi 0,888 setelah seluruh tanggal yang ditandai pada salah satu variabel dikeluarkan. Perubahan ini menunjukkan bahwa pengamatan ekstrem dapat sangat memengaruhi hubungan yang terlihat, tetapi korelasi setelah penghapusan tersebut bukan hasil utama. Seluruh nilai ekstrem sebaiknya tetap dipertahankan pada analisis awal dan diberi tanda untuk diverifikasi dengan catatan transaksi sebelum keputusan penghapusan dibuat.

Outlier tidak langsung dihapus karena dapat mencerminkan kejadian operasional yang nyata. Pengamatan perlu ditinjau dengan melihat tanggal, variabel, dan konteks proses. Nilai yang sangat berbeda dapat berasal dari lonjakan transaksi, keterlambatan proses, atau kesalahan pencatatan; dataset ini sendiri belum memberikan bukti penyebabnya. Karena itu, hasil deteksi merupakan penanda untuk pemeriksaan lebih lanjut, bukan bukti bahwa data pasti salah.

3.6 2.6 Insight Bisnis dan Rekomendasi Strategis

3.6.1 Ringkasan temuan utama

kanal_tertinggi <- ringkasan_kanal %>% slice_max(Rata_rata_transaksi, n = 1, with_ties = FALSE)
kanal_waktu_terendah <- ringkasan_kanal %>% slice_min(Rata_rata_waktu, n = 1, with_ties = FALSE)
layanan_nilai_tertinggi <- ringkasan_kombinasi %>%
  slice_max(Rata_rata_nilai, n = 1, with_ties = FALSE)

cat(
  "Kanal dengan rata-rata transaksi tertinggi adalah", kanal_tertinggi$Kanal,
  "dengan rata-rata", round(kanal_tertinggi$Rata_rata_transaksi, 2),
  "transaksi per hari.\n\n",
  "Kanal dengan rata-rata waktu proses terendah adalah", kanal_waktu_terendah$Kanal,
  "dengan rata-rata", round(kanal_waktu_terendah$Rata_rata_waktu, 2),
  "menit.\n\n",
  "Kombinasi kanal dan layanan dengan rata-rata nilai transaksi tertinggi adalah",
  paste(layanan_nilai_tertinggi$Kanal,
        layanan_nilai_tertinggi$Jenis_Layanan, sep = " - "),
  "dengan rata-rata", round(layanan_nilai_tertinggi$Rata_rata_nilai, 2),
  "juta rupiah."
)

Kanal dengan rata-rata transaksi tertinggi adalah Offline dengan rata-rata 74.8 transaksi per hari.

Kanal dengan rata-rata waktu proses terendah adalah Online dengan rata-rata 30.59 menit.

Kombinasi kanal dan layanan dengan rata-rata nilai transaksi tertinggi adalah Offline - Premium dengan rata-rata 4.02 juta rupiah.

kpi_kanal <- df %>%
  group_by(Kanal) %>%
  summarise(
    Hari = n(),
    Total_transaksi = sum(Jumlah_Transaksi),
    Rata_rata_transaksi = mean(Jumlah_Transaksi),
    Rata_rata_nilai = mean(Nilai_Transaksi_Juta_Rp),
    Rata_rata_waktu = mean(Waktu_Proses_Menit),
    CV_waktu_persen = sd(Waktu_Proses_Menit) / mean(Waktu_Proses_Menit) * 100,
    .groups = "drop"
  )
tampil(kpi_kanal, digits = 2, caption = "Indikator kinerja per kanal")
Indikator kinerja per kanal
Kanal Hari Total_transaksi Rata_rata_transaksi Rata_rata_nilai Rata_rata_waktu CV_waktu_persen
Offline 15 1122 74.80 3.33 34.72 48.04
Online 15 1093 72.87 3.03 30.59 30.71

Selama 30 hari pengamatan, tercatat 2.215 transaksi atau rata-rata 73,83 transaksi per hari. Rata-rata nilai transaksi harian adalah 3,179 juta rupiah, sedangkan rata-rata waktu proses 32,66 menit. Jika dilihat dari volume, kanal Offline menunjukkan angka lebih tinggi: rata-rata 74,80 transaksi per hari dan rata-rata nilai transaksi 3,328 juta rupiah, dibandingkan Online sebesar 72,87 transaksi dan 3,030 juta rupiah. Namun, Online memiliki waktu proses rata-rata lebih rendah (30,59 menit dibandingkan 34,72 menit) dan variasi waktu yang lebih kecil (SD 9,40 dibandingkan 16,68 menit). Jadi, tidak ada satu kanal yang unggul pada semua indikator: Offline lebih tinggi dari sisi volume dan rata-rata nilai, sedangkan Online lebih baik dari sisi kecepatan dan kestabilan waktu proses. Peningkatan jumlah transaksi tidak otomatis berarti kinerja meningkat karena nilai transaksi dan efisiensi proses juga perlu diperhatikan; korelasi jumlah transaksi dengan nilai transaksi pada keseluruhan data hanya 0,113. Waktu proses yang terlalu tinggi berpotensi menimbulkan antrean, memperlambat penyelesaian layanan, meningkatkan beban operasional, dan menurunkan pengalaman pelanggan.

Berdasarkan tabel dan grafik, kinerja tidak cukup dinilai dari jumlah transaksi saja. Jumlah transaksi yang tinggi belum tentu menunjukkan proses paling efisien atau nilai transaksi terbesar. Waktu proses, nilai transaksi, jenis layanan, serta konsistensi hasil juga perlu dipertimbangkan. Nilai ekstrem yang ditemukan perlu ditelusuri lebih lanjut sebelum digunakan sebagai dasar keputusan operasional.

3.6.2 Rekomendasi strategis

  1. Evaluasi efisiensi kanal Offline. Rata-rata waktu proses Offline mencapai 34,72 menit dengan standar deviasi 16,68 menit, lebih tinggi dan lebih bervariasi daripada Online (30,59 menit; SD 9,40 menit). Periksa alur kerja Offline, terutama pengamatan 12 Januari 2026 yang mencatat waktu proses 88 menit.
  2. Tinjau proses layanan Express pada kanal Offline. Kombinasi Offline-Express memiliki median waktu proses 42,7 menit dari 5 pengamatan. Perusahaan dapat meninjau tahapan layanan dan kapasitas petugas pada kombinasi ini sebelum menetapkan perubahan prosedur.
  3. Verifikasi transaksi bernilai ekstrem. Periksa kembali nilai 9,80 juta rupiah pada 17 Januari 2026 dan 0,12 juta rupiah pada 28 Januari 2026 melalui catatan transaksi asli. Nilai tersebut jangan langsung dihapus karena belum ada bukti bahwa keduanya merupakan kesalahan.
  4. Gunakan indikator kinerja secara bersamaan. Pantau jumlah transaksi, nilai transaksi, dan waktu proses. Offline memiliki rata-rata transaksi lebih tinggi (74,80 dibandingkan 72,87), tetapi Online memiliki waktu proses yang lebih rendah; karena itu, keputusan tidak sebaiknya hanya berfokus pada volume.
  5. Pantau tren secara berkala. Dalam 30 hari ini jumlah transaksi menunjukkan tren naik sekitar 1,414 transaksi per hari, sedangkan waktu proses turun sekitar 0,941 menit per hari. Perbarui analisis pada periode berikutnya untuk memeriksa apakah kecenderungan tersebut tetap konsisten.

3.7 2.7 Kualitas dan Reproduksibilitas Analisis

Seluruh proses impor, pengolahan, perhitungan statistik, dan visualisasi pada Soal 2 dilakukan menggunakan R. Kode disusun dalam beberapa bagian agar dapat dijalankan ulang. Untuk menghasilkan dokumen HTML, pastikan file Excel berada pada folder yang sama dengan file .Rmd, kemudian pilih Knit di RStudio. Jika muncul pesan paket belum tersedia, instal paket yang disebutkan pada pesan tersebut melalui Console.

4 Daftar Pustaka

Anderson, D. R., Sweeney, D. J., Williams, T. A., Camm, J. D., & Cochran, J. J. (2021). Statistics for Business & Economics. Cengage.

Diez, D. M., Barr, C. D., & Çetinkaya-Rundel, M. (2019). OpenIntro Statistics (4th ed.). OpenIntro.

Materi perkuliahan Pengantar Statistika SDT-1305, Minggu 1–7.