1 Studi Kasus

Tugas ini membahas hubungan penggunaan kelas online dengan kelulusan mahasiswa di sebuah kampus. Jalur masuk Reguler dan Beasiswa ikut diperhitungkan karena hubungan yang terlihat pada data gabungan bisa berbeda dengan hubungan pada masing-masing jalur. Untuk melihat perbedaannya, saya menghitung odds ratio (OR) marginal dan OR per jalur, lalu melakukan uji Breslow-Day dan Cochran-Mantel-Haenszel (CMH).

Variabel paparannya adalah penggunaan kelas online (Ya/Tidak), sedangkan outcome-nya adalah kelulusan (Lulus/Tidak Lulus). Jalur masuk (Reguler/Beasiswa) menjadi variabel stratifikasi atau kovariat. Data yang digunakan merupakan frekuensi simulasi dari soal, sehingga hasil analisis ini digunakan untuk latihan dan tidak mewakili kondisi kampus yang sebenarnya.

Odds kelulusan dihitung dengan membagi jumlah mahasiswa lulus dengan jumlah mahasiswa tidak lulus dalam kelompok yang sama. OR kemudian membandingkan odds kelompok pengguna kelas online dengan kelompok yang tidak menggunakan kelas online:

\[ OR = \frac{\text{odds lulus pada Online = Ya}} {\text{odds lulus pada Online = Tidak}} = \frac{a/b}{c/d} = \frac{ad}{bc}. \]

Pada tabel, pengguna kelas online ditempatkan di baris pertama dan mahasiswa lulus di kolom pertama. Jika \(OR>1\), odds kelulusan pengguna kelas online lebih tinggi. Jika \(OR<1\), odds-nya lebih rendah. Nilai OR ini merupakan perbandingan odds, sehingga tidak langsung menyatakan perbandingan probabilitas kelulusan. Taraf signifikansi yang digunakan adalah \(\alpha = 0,05\). Hubungan yang dibahas sebatas asosiasi.

2 Data dan Tabel Kontingensi Tiga Arah

Frekuensi pada soal dimasukkan ke dalam array \(2\times2\times2\) dengan urutan Online × Kelulusan × Jalur Masuk. Opsi byrow = TRUE digunakan agar susunan angka pada matriks mengikuti baris tabel di soal. Karena datanya sudah berbentuk frekuensi, analisis dapat dilakukan tanpa membuat satu baris data untuk setiap mahasiswa.

tab <- array(
  0, dim = c(2, 2, 2),
  dimnames = list(
    Online = c("Ya", "Tidak"),
    Kelulusan = c("Lulus", "Tidak Lulus"),
    Jalur = c("Reguler", "Beasiswa")
  )
)
tab[, , "Reguler"] <- matrix(
  c(90, 210, 30, 120), nrow = 2, byrow = TRUE
)
tab[, , "Beasiswa"] <- matrix(
  c(240, 60, 270, 90), nrow = 2, byrow = TRUE
)

stopifnot(
  identical(dim(tab), c(2L, 2L, 2L)),
  !anyNA(tab), all(is.finite(tab)), all(tab >= 0),
  all(tab == floor(tab)), all(tab > 0)
)

reguler <- tab[, , "Reguler"]
beasiswa <- tab[, , "Beasiswa"]
marginal <- apply(tab, c(1, 2), sum)
n_strata <- apply(tab, 3, sum)
n_total <- sum(tab)
stopifnot(sum(marginal) == n_total, sum(n_strata) == n_total)

2.1 Tabel Jalur Reguler

knitr::kable(tabel_tampil(reguler), caption = "Frekuensi mahasiswa jalur Reguler")
Frekuensi mahasiswa jalur Reguler
Online Lulus Tidak Lulus Total
Ya 90 210 300
Tidak 30 120 150

Jumlah mahasiswa jalur Reguler adalah 450 orang. Total setiap baris digunakan sebagai penyebut saat menghitung proporsi kelulusan pengguna dan bukan pengguna kelas online.

2.2 Tabel Jalur Beasiswa

knitr::kable(tabel_tampil(beasiswa), caption = "Frekuensi mahasiswa jalur Beasiswa")
Frekuensi mahasiswa jalur Beasiswa
Online Lulus Tidak Lulus Total
Ya 240 60 300
Tidak 270 90 360

Pada jalur Beasiswa terdapat 660 mahasiswa. Tabel ini digunakan untuk membandingkan mahasiswa pengguna dan bukan pengguna kelas online khusus pada jalur Beasiswa.

2.3 Tabel Marginal

knitr::kable(
  tabel_tampil(marginal),
  caption = "Frekuensi marginal setelah menjumlahkan kedua jalur masuk"
)
Frekuensi marginal setelah menjumlahkan kedua jalur masuk
Online Lulus Tidak Lulus Total
Ya 330 270 600
Tidak 300 210 510

Setelah kedua jalur digabungkan, jumlah mahasiswa menjadi 1110 orang. Tabel marginal hanya menunjukkan penggunaan kelas online dan kelulusan, sehingga perbedaan komposisi jalur masuk belum terlihat di sini.

2.4 Tabel Kontingensi Tiga Arah

frekuensi <- as.data.frame(as.table(tab), responseName = "Frekuensi")
frekuensi <- frekuensi[order(frekuensi$Jalur, frekuensi$Online,
                            frekuensi$Kelulusan), ]
knitr::kable(
  frekuensi, row.names = FALSE,
  caption = "Tabel tiga arah: Online × Kelulusan × Jalur Masuk"
)
Tabel tiga arah: Online <U+00D7> Kelulusan <U+00D7> Jalur Masuk
Online Kelulusan Jalur Frekuensi
Ya Lulus Reguler 90
Ya Tidak Lulus Reguler 210
Tidak Lulus Reguler 30
Tidak Tidak Lulus Reguler 120
Ya Lulus Beasiswa 240
Ya Tidak Lulus Beasiswa 60
Tidak Lulus Beasiswa 270
Tidak Tidak Lulus Beasiswa 90

Tabel tiga arah memuat delapan kombinasi kategori. Setiap mahasiswa diasumsikan masuk ke satu sel saja dan pengamatan antar mahasiswa dianggap independen. Asumsi independensi ini perlu dipenuhi oleh rancangan data, karena tabel frekuensi saja tidak cukup untuk memeriksanya. Semua sel pada data simulasi terisi dan tidak ada frekuensi yang hilang.

3 Odds Ratio Marginal

Untuk menghitung OR marginal, frekuensi Reguler dan Beasiswa dijumlahkan terlebih dahulu. Nilai \(a\), \(b\), \(c\), dan \(d\) diambil dari tabel gabungan tersebut.

a <- marginal["Ya", "Lulus"]
b <- marginal["Ya", "Tidak Lulus"]
c <- marginal["Tidak", "Lulus"]
d <- marginal["Tidak", "Tidak Lulus"]
OR_marginal <- (a * d) / (b * c)

knitr::kable(
  data.frame(a = a, b = b, c = c, d = d, OR = OR_marginal),
  digits = 3, caption = "Sel dan OR marginal"
)
Sel dan OR marginal
a b c d OR
330 270 300 210 0.856
stopifnot(isTRUE(all.equal(OR_marginal, or_manual(marginal))))

\[ OR_{\text{marginal}} = \frac{330\times210}{270\times300} = 0,856. \]

Hasilnya, odds kelulusan pengguna kelas online adalah 0,856 kali odds mahasiswa yang tidak menggunakan kelas online. Artinya, pada data gabungan, odds pengguna sekitar 14,44% lebih rendah. Hasil ini belum memperhitungkan jalur masuk dan hanya menunjukkan perbandingan deskriptif. Signifikansi hubungan belum dapat ditentukan dari nilai OR saja.

4 Odds Ratio Bersyarat

4.1 Jalur Masuk Reguler

knitr::kable(tabel_tampil(reguler), caption = "Tabel untuk OR bersyarat Reguler")
Tabel untuk OR bersyarat Reguler
Online Lulus Tidak Lulus Total
Ya 90 210 300
Tidak 30 120 150
a_r <- reguler["Ya", "Lulus"]
b_r <- reguler["Ya", "Tidak Lulus"]
c_r <- reguler["Tidak", "Lulus"]
d_r <- reguler["Tidak", "Tidak Lulus"]
OR_reguler <- (a_r * d_r) / (b_r * c_r)
knitr::kable(data.frame(OR_Reguler = OR_reguler), digits = 3)
OR_Reguler
1.714

\[ OR_{\text{Reguler}} = \frac{90\times120}{210\times30} = 1,714. \]

Untuk mahasiswa Reguler, odds kelulusan pengguna kelas online sebesar 1,714 kali odds bukan pengguna, atau sekitar 71,43% lebih tinggi. Nilai ini berada di atas satu, sedangkan OR marginal berada di bawah satu. Jadi, arah hubungan pada jalur Reguler berbeda dengan hasil gabungan.

4.2 Jalur Masuk Beasiswa

knitr::kable(tabel_tampil(beasiswa), caption = "Tabel untuk OR bersyarat Beasiswa")
Tabel untuk OR bersyarat Beasiswa
Online Lulus Tidak Lulus Total
Ya 240 60 300
Tidak 270 90 360
a_b <- beasiswa["Ya", "Lulus"]
b_b <- beasiswa["Ya", "Tidak Lulus"]
c_b <- beasiswa["Tidak", "Lulus"]
d_b <- beasiswa["Tidak", "Tidak Lulus"]
OR_beasiswa <- (a_b * d_b) / (b_b * c_b)
knitr::kable(data.frame(OR_Beasiswa = OR_beasiswa), digits = 3)
OR_Beasiswa
1.333

\[ OR_{\text{Beasiswa}} = \frac{240\times90}{60\times270} = 1,333. \]

OR pada jalur Beasiswa sebesar 1,333. Odds kelulusan pengguna kelas online sekitar 33,33% lebih tinggi daripada bukan pengguna. Sama seperti jalur Reguler, OR Beasiswa juga berada di atas satu. Kedua nilai OR ini menunjukkan arah dan besar hubungan dalam masing-masing jalur, tetapi belum menyatakan bahwa hubungan pada setiap jalur signifikan karena uji per jalur tidak dilakukan.

4.3 Ringkasan Odds Ratio

OR_strata <- apply(tab, 3, or_manual)
stopifnot(isTRUE(all.equal(
  unname(OR_strata), c(OR_reguler, OR_beasiswa)
)))
nilai_or <- c(Marginal = OR_marginal, OR_strata)
ringkasan_or <- data.frame(
  Analisis = names(nilai_or),
  `Odds Ratio` = unname(nilai_or),
  Interpretasi = ifelse(
    nilai_or > 1, "Odds lulus pengguna online lebih tinggi",
    ifelse(nilai_or < 1, "Odds lulus pengguna online lebih rendah",
           "Odds lulus kedua kelompok sama")
  ), check.names = FALSE
)
knitr::kable(ringkasan_or, digits = 3, row.names = FALSE)
Analisis Odds Ratio Interpretasi
Marginal 0.856 Odds lulus pengguna online lebih rendah
Reguler 1.714 Odds lulus pengguna online lebih tinggi
Beasiswa 1.333 Odds lulus pengguna online lebih tinggi

5 Pemeriksaan Paradoks Simpson

5.1 Perbandingan Arah Hubungan dan Proporsi Kelulusan

Selain OR, proporsi kelulusan juga dibandingkan. Perhitungannya menggunakan jumlah mahasiswa lulus dibagi total mahasiswa pada kelompok yang sama. Untuk hasil per jalur, penyebutnya adalah total mahasiswa pada kombinasi penggunaan kelas online dan jalur masuk tersebut.

buat_proporsi <- function(x, nama) {
  data.frame(
    Analisis = nama, Online = rownames(x),
    Lulus = x[, "Lulus"], Total = rowSums(x),
    Proporsi = x[, "Lulus"] / rowSums(x),
    row.names = NULL
  )
}
proporsi <- rbind(
  buat_proporsi(marginal, "Marginal"),
  buat_proporsi(reguler, "Reguler"),
  buat_proporsi(beasiswa, "Beasiswa")
)
proporsi$Persentase <- persen(proporsi$Proporsi)
knitr::kable(proporsi, digits = 4, row.names = FALSE,
             caption = "Proporsi kelulusan marginal dan per jalur masuk")
Proporsi kelulusan marginal dan per jalur masuk
Analisis Online Lulus Total Proporsi Persentase
Marginal Ya 330 600 0.5500 55,00%
Marginal Tidak 300 510 0.5882 58,82%
Reguler Ya 90 300 0.3000 30,00%
Reguler Tidak 30 150 0.2000 20,00%
Beasiswa Ya 240 300 0.8000 80,00%
Beasiswa Tidak 270 360 0.7500 75,00%
p_m <- marginal[, "Lulus"] / rowSums(marginal)
p_r <- reguler[, "Lulus"] / rowSums(reguler)
p_b <- beasiswa[, "Lulus"] / rowSums(beasiswa)
simpson <- (OR_marginal < 1 && all(OR_strata > 1)) ||
  (OR_marginal > 1 && all(OR_strata < 1))
knitr::kable(data.frame(`Pembalikan arah / Paradoks Simpson` = simpson,
                        check.names = FALSE))
Pembalikan arah / Paradoks Simpson
TRUE

Pada data gabungan, proporsi kelulusan pengguna kelas online adalah 55,00%, sedangkan bukan pengguna sebesar 58,82%. Pengguna kelas online terlihat memiliki proporsi kelulusan lebih rendah. Namun, hasilnya berubah ketika jalur masuk dipisahkan. Pada Reguler, proporsi pengguna adalah 30,00% dan bukan pengguna 20,00%. Pada Beasiswa, proporsinya masing-masing 80,00% dan 75,00%. Jadi, dalam kedua jalur, proporsi kelulusan pengguna justru lebih tinggi.

Dari perbandingan tersebut, terjadi Paradoks Simpson. OR marginal di bawah satu, sementara OR Reguler dan Beasiswa di atas satu. Perubahan arah ini juga terlihat dari proporsi kelulusan, bukan hanya dari perbedaan besar nilai OR.

5.2 Mekanisme Perbedaan Komposisi Jalur Masuk

jumlah_online_jalur <- apply(tab, c(1, 3), sum)
bobot_jalur <- jumlah_online_jalur / rowSums(jumlah_online_jalur)
knitr::kable(
  data.frame(Online = rownames(jumlah_online_jalur),
             jumlah_online_jalur, row.names = NULL),
  caption = "Jumlah mahasiswa setiap jalur menurut penggunaan kelas online"
)
Jumlah mahasiswa setiap jalur menurut penggunaan kelas online
Online Reguler Beasiswa
Ya 300 300
Tidak 150 360
knitr::kable(
  data.frame(Online = rownames(bobot_jalur),
             Reguler = persen(bobot_jalur[, "Reguler"]),
             Beasiswa = persen(bobot_jalur[, "Beasiswa"]),
             row.names = NULL),
  caption = "Komposisi jalur masuk dalam setiap kelompok Online"
)
Komposisi jalur masuk dalam setiap kelompok Online
Online Reguler Beasiswa
Ya 50,00% 50,00%
Tidak 29,41% 70,59%
# Proporsi marginal adalah rata-rata tertimbang proporsi per jalur.
p_tertimbang <- bobot_jalur[, "Reguler"] * p_r +
  bobot_jalur[, "Beasiswa"] * p_b
stopifnot(isTRUE(all.equal(p_tertimbang, p_m)))

Komposisi jalur masuk pada kedua kelompok ternyata berbeda. Mahasiswa Reguler mencakup 50,00% dari pengguna kelas online, tetapi hanya 29,41% dari bukan pengguna. Untuk Beasiswa, bagiannya sebesar 50,00% pada pengguna dan 70,59% pada bukan pengguna. Padahal, proporsi kelulusan mahasiswa Beasiswa jauh lebih tinggi daripada Reguler, baik pada pengguna maupun bukan pengguna.

Proporsi kelulusan gabungan dapat dihitung sebagai rata-rata tertimbang dari proporsi setiap jalur. Bobotnya mengikuti komposisi jalur masuk dalam masing-masing kelompok:

\[ \begin{aligned} P(\text{Lulus}\mid\text{Ya}) &= 0,5000\times0,3000 + 0,5000\times0,8000 \approx 0,5500,\\ P(\text{Lulus}\mid\text{Tidak}) &= 0,2941\times0,2000 + 0,7059\times0,7500 \approx 0,5882. \end{aligned} \]

Kelompok bukan pengguna lebih banyak diisi mahasiswa Beasiswa, yaitu jalur dengan proporsi kelulusan yang lebih tinggi. Hal ini membuat proporsi kelulusan gabungan bukan pengguna menjadi lebih tinggi, walaupun dalam setiap jalur proporsinya lebih rendah daripada pengguna. Karena itu, hasil marginal saja dapat memberi gambaran yang keliru tentang hubungan pada jalur masuk yang sama. Perbedaan komposisi ini menunjukkan perancuan secara statistik, tetapi belum membuktikan bahwa jalur masuk merupakan perancu dalam hubungan sebab-akibat.

6 Visualisasi Proporsi Kelulusan

Grafik berikut membandingkan proporsi kelulusan pengguna dan bukan pengguna kelas online pada setiap jalur. Sumbu proporsi menggunakan skala 0 sampai 100%. Nama jalur dan persentase ditulis pada batang agar perbedaannya tetap terbaca tanpa hanya mengandalkan warna. Jumlah mahasiswa setiap kelompok dapat dilihat pada tabel proporsi.

data_plot <- proporsi[proporsi$Analisis != "Marginal", ]
data_plot$Online <- factor(data_plot$Online, levels = c("Ya", "Tidak"))
data_plot$Jalur <- factor(data_plot$Analisis,
                          levels = c("Reguler", "Beasiswa"))
data_plot$Label <- paste(data_plot$Jalur, persen(data_plot$Proporsi, 1), sep = "\n")

plot_proporsi <- ggplot(
  data_plot, aes(x = Online, y = Proporsi, fill = Jalur)
) +
  geom_col(position = position_dodge(width = 0.8), width = 0.7,
           colour = "#333333", linewidth = 0.3) +
  geom_text(aes(label = Label),
            position = position_dodge(width = 0.8),
            vjust = -0.25, size = 3.5, colour = "#222222") +
  scale_fill_manual(values = c(Reguler = "#0072B2", Beasiswa = "#D55E00")) +
  scale_y_continuous(
    limits = c(0, 1), breaks = seq(0, 1, 0.2),
    labels = function(x) persen(x, 0),
    expand = expansion(mult = c(0, 0.02))
  ) +
  labs(
    title = "Proporsi kelulusan menurut penggunaan kelas online",
    subtitle = "Perbandingan dalam jalur masuk yang sama",
    x = "Penggunaan Kelas Online", y = "Proporsi Lulus",
    fill = "Jalur Masuk",
    caption = "Sumber: frekuensi simulasi pada soal. Batang menunjukkan proporsi deskriptif."
  ) +
  theme_minimal(base_size = 12) +
  theme(
    legend.position = "bottom",
    panel.grid.major.x = element_blank(),
    panel.grid.minor = element_blank(),
    plot.title = element_text(face = "bold"),
    plot.caption = element_text(hjust = 0)
  )

ggsave("output/proporsi_kelulusan.png", plot = plot_proporsi,
       width = 8, height = 5.2, units = "in", dpi = 300, bg = "white")
knitr::include_graphics("output/proporsi_kelulusan.png")

Grafik batang proporsi kelulusan: pada Reguler maupun Beasiswa, proporsi pengguna kelas online lebih tinggi daripada bukan pengguna; proporsi Beasiswa jauh lebih tinggi daripada Reguler.

Pada kedua jalur, batang kelompok pengguna kelas online lebih tinggi daripada bukan pengguna. Perbedaan tingkat kelulusan Reguler dan Beasiswa juga terlihat cukup besar. Grafik ini hanya menampilkan proporsi dari data simulasi, tanpa interval ketidakpastian. Untuk menguji hubungan setelah jalur masuk dikontrol, digunakan uji CMH.

7 Uji Breslow-Day

Meskipun OR Reguler dan Beasiswa sama-sama di atas satu, nilainya tidak persis sama. Uji Breslow-Day digunakan untuk memeriksa apakah perbedaan OR antarjalur tersebut signifikan. Hipotesisnya adalah:

  • \(H_0\): \(OR_{\text{Reguler}} = OR_{\text{Beasiswa}}\), yaitu OR hubungan penggunaan kelas online dengan kelulusan homogen antarjalur.
  • \(H_1\): \(OR_{\text{Reguler}} \ne OR_{\text{Beasiswa}}\), yaitu OR tidak homogen antarjalur.

Yang diuji di sini adalah kesamaan OR antarjalur, bukan apakah OR sama dengan satu. Perhitungan menggunakan Breslow-Day tanpa penyesuaian Tarone (correct = FALSE) dan estimasi Mantel-Haenszel sebagai OR bersama, sesuai dokumentasi DescTools.

bd <- DescTools::BreslowDayTest(tab, correct = FALSE)
hasil_bd <- data.frame(
  Statistik = unname(bd$statistic),
  df = unname(bd$parameter),
  `p-value` = bd$p.value,
  Keputusan = keputusan(bd$p.value), check.names = FALSE
)
knitr::kable(hasil_bd, digits = 4,
             caption = "Hasil uji homogenitas Breslow–Day")
Hasil uji homogenitas Breslow<U+2013>Day
Statistik df p-value Keputusan
0.6786 1 0.4101 Gagal menolak H0

7.1 Pemeriksaan Frekuensi Harapan dan Perhitungan Uji

Breslow-Day menggunakan pendekatan asimtotik, sehingga jumlah mahasiswa per jalur dan frekuensi harapannya perlu cukup besar. Frekuensi harapan dihitung dengan OR bersama dan total baris serta kolom yang tetap pada setiap jalur. Jika \(A_k\) adalah frekuensi harapan untuk sel pengguna kelas online yang lulus, persamaannya adalah:

\[ \widehat{OR}_{MH} = \frac{A_k(n_k-r_{1k}-c_{1k}+A_k)} {(r_{1k}-A_k)(c_{1k}-A_k)}, \]

Pada rumus tersebut, \(r_{1k}\) adalah jumlah pengguna kelas online, \(c_{1k}\) jumlah mahasiswa lulus, dan \(n_k\) total mahasiswa pada jalur ke-\(k\). Nilai \(A_k\) dicari secara numerik dalam batas frekuensi yang mungkin.

a_k <- tab["Ya", "Lulus", ]
b_k <- tab["Ya", "Tidak Lulus", ]
c_k <- tab["Tidak", "Lulus", ]
d_k <- tab["Tidak", "Tidak Lulus", ]
OR_MH_manual <- sum(a_k * d_k / n_strata) /
  sum(b_k * c_k / n_strata)

harapan_bd <- lapply(dimnames(tab)$Jalur, function(jalur) {
  x <- tab[, , jalur]
  n <- sum(x)
  r1 <- sum(x["Ya", ])
  c1 <- sum(x[, "Lulus"])
  batas <- c(max(0, r1 + c1 - n), min(r1, c1))
  akar <- uniroot(function(A) {
    A * (n - r1 - c1 + A) -
      OR_MH_manual * (r1 - A) * (c1 - A)
  }, interval = batas, tol = 1e-10)$root
  matrix(c(akar, r1 - akar, c1 - akar,
           n - r1 - c1 + akar), nrow = 2, byrow = TRUE,
         dimnames = dimnames(x))
})
names(harapan_bd) <- dimnames(tab)$Jalur
cek_harapan <- data.frame(
  Jalur = names(harapan_bd), n = unname(n_strata),
  `Minimum frekuensi harapan` = vapply(harapan_bd, min, numeric(1)),
  `Persentase sel harapan > 5` = vapply(
    harapan_bd, function(x) 100 * mean(x > 5), numeric(1)
  ), check.names = FALSE
)
knitr::kable(cek_harapan, digits = 3, row.names = FALSE,
             caption = "Kecukupan frekuensi harapan untuk Breslow–Day")
Kecukupan frekuensi harapan untuk Breslow<U+2013>Day
Jalur n Minimum frekuensi harapan Persentase sel harapan > 5
Reguler 450 32.707 100
Beasiswa 660 57.248 100
# Validasi statistik BD melalui rumus sel dan varians bersyarat.
A_hat <- vapply(harapan_bd, function(x) x["Ya", "Lulus"], numeric(1))
V_hat <- vapply(harapan_bd, function(x) 1 / sum(1 / x), numeric(1))
BD_manual <- sum((a_k - A_hat)^2 / V_hat)
stopifnot(isTRUE(all.equal(unname(bd$statistic),
                           unname(BD_manual), tolerance = 1e-6)))

Frekuensi harapan terkecil adalah 32,707, dan 100% sel memiliki frekuensi harapan lebih dari lima. Bersama dengan jumlah mahasiswa per jalur pada tabel, hasil ini menunjukkan bahwa frekuensi cukup untuk pendekatan asimtotik. Pemeriksaan ini tidak menilai independensi antar mahasiswa; asumsi tersebut tetap bergantung pada rancangan data.

Hasil uji memberikan \(\chi^2(1) = 0,6786\) dengan \(p = 0,4101\). Nilai p lebih besar atau sama dengan \(\alpha = 0,05\), sehingga \(H_0\) gagal ditolak. Artinya, perbedaan OR antarjalur tidak signifikan pada data ini. Hasil gagal menolak \(H_0\) bukan berarti kedua OR pasti sama. Namun, OR bersama dapat digunakan untuk merangkum hubungan, dengan tetap melihat hasil pada masing-masing jalur.

8 Uji Cochran-Mantel-Haenszel

Uji CMH menjawab apakah penggunaan kelas online berhubungan dengan kelulusan setelah jalur masuk dikontrol. Dengan asumsi OR antarjalur homogen, hipotesis yang digunakan adalah:

  • \(H_0\): tidak terdapat hubungan setelah mengontrol jalur masuk; \(OR_{\text{bersama}} = 1\).
  • \(H_1\): terdapat hubungan setelah mengontrol jalur masuk; \(OR_{\text{bersama}} \ne 1\).

Perhitungan menggunakan uji dua sisi dengan pendekatan asimtotik, koreksi kontinuitas (correct = TRUE), dan interval kepercayaan 95%. Pada CMH, opsi correct mengatur koreksi kontinuitas statistik uji, sedangkan pada Breslow-Day opsi tersebut mengatur penyesuaian Tarone. Jadi, arti opsi ini berbeda pada kedua fungsi. Statistik uji, derajat bebas, OR bersama, dan interval kepercayaan diambil dari hasil fungsi sebagaimana dijelaskan dalam dokumentasi R.

cmh <- mantelhaen.test(
  tab, alternative = "two.sided", correct = TRUE,
  exact = FALSE, conf.level = 0.95
)
OR_MH <- unname(cmh$estimate)
CI_MH <- unname(cmh$conf.int)
hasil_cmh <- data.frame(
  `Statistik CMH` = unname(cmh$statistic),
  df = unname(cmh$parameter),
  `p-value` = cmh$p.value,
  `Common OR MH` = OR_MH,
  `Batas bawah IK 95%` = CI_MH[1],
  `Batas atas IK 95%` = CI_MH[2],
  Keputusan = keputusan(cmh$p.value), check.names = FALSE
)
knitr::kable(hasil_cmh, digits = 4,
             caption = "Hasil CMH dengan koreksi kontinuitas")
Hasil CMH dengan koreksi kontinuitas
Statistik CMH df p-value Common OR MH Batas bawah IK 95% Batas atas IK 95% Keputusan
6.4622 1 0.011 1.4717 1.1012 1.9668 Tolak H0

8.1 Validasi Orientasi dan Statistik CMH

Untuk memeriksa hasil R, OR Mantel-Haenszel dihitung kembali dengan susunan sel yang sama:

\[ \widehat{OR}_{MH} = \frac{\sum_k a_k d_k/n_k}{\sum_k b_k c_k/n_k}. \]

stopifnot(
  identical(dimnames(tab)$Online, c("Ya", "Tidak")),
  identical(dimnames(tab)$Kelulusan, c("Lulus", "Tidak Lulus")),
  isTRUE(all.equal(OR_MH, unname(OR_MH_manual), tolerance = 1e-10)),
  CI_MH[1] < OR_MH, OR_MH < CI_MH[2]
)

# Di bawah H0 independensi bersyarat, a_k berdistribusi hipergeometrik.
r1_k <- a_k + b_k
c1_k <- a_k + c_k
E0_k <- r1_k * c1_k / n_strata
V0_k <- r1_k * (n_strata - r1_k) * c1_k *
  (n_strata - c1_k) / (n_strata^2 * (n_strata - 1))
CMH_manual <- max(0, abs(sum(a_k - E0_k)) - 0.5)^2 / sum(V0_k)
p_CMH_manual <- pchisq(CMH_manual, df = 1, lower.tail = FALSE)
stopifnot(
  isTRUE(all.equal(unname(cmh$statistic), unname(CMH_manual))),
  isTRUE(all.equal(cmh$p.value, unname(p_CMH_manual)))
)
knitr::kable(
  data.frame(`OR MH manual` = OR_MH_manual, `OR MH dari R` = OR_MH,
             `Orientasi sama` = isTRUE(all.equal(OR_MH, OR_MH_manual)),
             check.names = FALSE),
  digits = 4, row.names = FALSE,
  caption = "Validasi estimator OR bersama"
)
Validasi estimator OR bersama
OR MH manual OR MH dari R Orientasi sama
1.4717 1.4717 TRUE

Perhitungan manual dan hasil R sama-sama menghasilkan OR bersama sebesar 1,4717. Dengan susunan tabel yang digunakan, angka ini membandingkan odds lulus pengguna kelas online terhadap bukan pengguna. Hasil R sudah sesuai dengan definisi tersebut sehingga tidak perlu dibalik menjadi reciprocal.

Statistik CMH yang diperoleh adalah \(\chi^2(1) = 6,4622\) dengan \(p = 0,0110\). Karena nilai p lebih kecil \(\alpha\), \(H_0\) ditolak. Hasil ini menunjukkan bahwa, setelah jalur masuk dikontrol, terdapat hubungan yang signifikan antara penggunaan kelas online dan kelulusan berdasarkan model dan asumsi uji.

Common OR sebesar 1,472 memiliki IK 95% [1,101; 1,967]. Setelah jalur masuk dikontrol, odds kelulusan pengguna kelas online sekitar 47,17% lebih tinggi daripada bukan pengguna. Interval kepercayaannya tidak mencakup satu. Persentase tersebut menyatakan perbedaan odds, bukan kenaikan probabilitas kelulusan dengan persentase yang sama.

9 Interpretasi Hasil

Jika hanya melihat OR marginal sebesar 0,856, pengguna kelas online tampak memiliki odds kelulusan lebih rendah. Akan tetapi, OR Reguler sebesar 1,714 dan OR Beasiswa sebesar 1,333 menunjukkan hasil sebaliknya. Inilah Paradoks Simpson pada data ini. Perbedaan tersebut dapat dijelaskan dari komposisi mahasiswa: kelompok bukan pengguna memiliki bagian mahasiswa Beasiswa lebih besar, sedangkan kelulusan pada jalur Beasiswa lebih tinggi daripada Reguler di kedua kelompok penggunaan kelas online.

Breslow-Day menghasilkan \(p = 0,4101\), sehingga \(H_0\) gagal ditolak. Perbedaan OR antarjalur tidak signifikan dan hubungan dapat dirangkum dengan OR bersama, meskipun kesamaan OR tidak terbukti secara pasti. Pada uji CMH, nilai \(p = 0,0110\) menghasilkan keputusan menolak \(H_0\). Common OR sebesar 1,472, dengan IK 95% [1,101; 1,967], menunjukkan hubungan positif setelah jalur masuk dikontrol. Arah ini berbeda dengan hasil marginal.

Hasil analisis menunjukkan mengapa jalur masuk perlu diperhitungkan. Ketika dua jalur dengan tingkat kelulusan dan komposisi berbeda digabungkan, hubungan pada masing-masing jalur menjadi tertutup oleh perbedaan komposisi tersebut. Kesimpulan ini berlaku untuk data simulasi dengan asumsi independensi dan model OR bersama yang digunakan. Faktor lain, seperti prestasi awal dan intensitas penggunaan kelas online, tidak tersedia dalam data. Oleh sebab itu, hasil ini belum dapat digunakan untuk menjelaskan sebab-akibat atau menggambarkan keadaan kampus nyata.

10 Kesimpulan

Dari data gabungan, OR sebesar 0,856 menunjukkan odds kelulusan pengguna kelas online lebih rendah. Namun, setelah dipisahkan menurut jalur masuk, odds pengguna lebih tinggi pada Reguler (OR = 1,714) maupun Beasiswa (OR = 1,333). Pembalikan arah pada OR dan proporsi kelulusan ini menunjukkan adanya Paradoks Simpson. Penyebab perbedaan hasil gabungan adalah bagian mahasiswa Beasiswa yang lebih besar pada kelompok bukan pengguna, sementara kelulusan pada jalur Beasiswa lebih tinggi.

Berdasarkan Breslow-Day, homogenitas OR tidak ditolak karena \(p = 0,4101\). Artinya, belum ada bukti perbedaan OR yang signifikan antarjalur, bukan berarti kedua OR pasti identik. Uji CMH menghasilkan \(p = 0,0110\), sehingga terdapat hubungan yang signifikan setelah jalur masuk dikontrol. Common OR sebesar 1,472 dengan IK 95% [1,101; 1,967] berada di atas satu. Dengan demikian, penggunaan kelas online berasosiasi dengan odds kelulusan yang lebih tinggi setelah mengontrol jalur masuk.

Untuk kasus ini, analisis per jalur lebih informatif daripada hanya memakai tabel marginal karena perbandingan dilakukan pada jalur masuk yang sama dan komposisi mahasiswa tetap diperhitungkan. Hasil latihan dengan data simulasi ini menunjukkan asosiasi, sehingga tidak dapat disimpulkan bahwa kelas online menyebabkan mahasiswa lulus.

Catatan Reproduksibilitas

Tabel, angka dalam pembahasan, hasil uji, dan grafik dihitung dari data frekuensi yang sama. Kode juga memeriksa susunan OR dan mencocokkan hasil R dengan perhitungan ulang. Jika ada ketidaksesuaian, proses Knit akan berhenti. Versi R dan paket yang digunakan tercantum di bawah ini.

knitr::kable(
  data.frame(
    Perangkat = c("R", "DescTools", "ggplot2", "knitr", "rmarkdown"),
    Versi = c(as.character(getRversion()),
              vapply(c("DescTools", "ggplot2", "knitr", "rmarkdown"),
                     function(x) as.character(utils::packageVersion(x)),
                     character(1))),
    row.names = NULL
  )
)
Perangkat Versi
R 4.5.2
DescTools 0.99.60
ggplot2 4.0.3
knitr 1.51
rmarkdown 2.32