1 Analisis Data Kategori

1.1 Definisi Analisis Data Kategori

1.1.1 Apa yang Dimaksud dengan Analisis Data Kategori?

Analisis Data Kategori (Categorical Data Analysis) adalah sekumpulan metode statistik yang dirancang khusus untuk menganalisis data yang diukur pada skala nominal atau ordinal, di mana setiap observasi dikelompokkan ke dalam kategori-kategori yang bersifat diskret dan tidak kontinu.

Berbeda dengan analisis data kontinu yang menggunakan mean, variansi, atau distribusi normal, analisis data kategori menggunakan frekuensi, proporsi, dan probabilitas sebagai dasar inferensi statistik. Metode-metode utama dalam analisis data kategori meliputi:

  • Tabel Kontingensi (Contingency Table): Menyusun data dua variabel kategori atau lebih secara bersama.
  • Uji Chi-Square: Menguji independensi antar variabel kategori.
  • Ukuran Asosiasi: Odds Ratio, Relative Risk, Phi Coefficient.
  • Regresi Logistik: Memodelkan peluang kejadian pada variabel respons biner.
  • Model Log-Linear: Menganalisis struktur dependensi pada tabel multidimensi.

1.1.2 Karakteristik Variabel Kategori

Variabel kategori memiliki karakteristik yang membedakannya dari variabel kontinu:

Karakteristik Penjelasan
Diskret Nilai hanya berupa kategori tertentu, tidak ada nilai di antara dua kategori
Tidak Terukur Secara Numerik Nilai tidak memiliki jarak (interval) yang bermakna secara matematis
Skala Nominal Kategori tidak memiliki urutan alami (contoh: jenis kelamin, agama)
Skala Ordinal Kategori memiliki urutan alami, tetapi jarak antar kategori tidak sama (contoh: tingkat pendidikan, tingkat kepuasan)
Ringkasan dengan Frekuensi Dideskripsikan dengan frekuensi dan proporsi, bukan rata-rata

1.1.3 Contoh Penerapan Analisis Data Kategori dalam Penelitian

Analisis data kategori digunakan secara luas di berbagai bidang keilmuan:

1. Bidang Kesehatan Masyarakat Meneliti apakah ada hubungan antara kebiasaan konsumsi gula berlebih (ya/tidak) dengan kejadian diabetes tipe 2 (ya/tidak) pada populasi dewasa.

2. Bidang Pendidikan Menganalisis apakah metode pembelajaran (daring/luring/hybrid) berpengaruh terhadap kelulusan tepat waktu (lulus tepat waktu/tidak) mahasiswa.

3. Bidang Sosiologi Menguji apakah terdapat hubungan antara tingkat pendidikan ibu (SD/SMP/SMA/Perguruan Tinggi) dengan status gizi balita (normal/stunting/wasting).

4. Bidang Ekonomi Memeriksa asosiasi antara kepemilikan kartu kredit (ya/tidak) dengan keputusan membeli secara impulsif (ya/tidak) pada konsumen ritel.


1.2 Tabel Kontingensi

1.2.1 Definisi Tabel Kontingensi

Tabel Kontingensi (Contingency Table atau Cross-tabulation Table) adalah suatu tabel yang merangkum distribusi frekuensi bersama dari dua atau lebih variabel kategori secara simultan. Tabel ini memperlihatkan bagaimana observasi tersebar di setiap kombinasi kategori dari variabel-variabel yang diamati.

Tabel kontingensi yang melibatkan dua variabel dengan masing-masing \(r\) baris dan \(c\) kolom disebut tabel kontingensi \(r \times c\). Kasus paling sederhana adalah tabel \(2 \times 2\) yang melibatkan dua variabel biner.

1.2.2 Struktur Tabel Kontingensi

Secara umum, struktur tabel kontingensi \(r \times c\) adalah sebagai berikut:

\(Y = 1\) \(Y = 2\) \(\cdots\) \(Y = c\) Total Baris
\(X = 1\) \(n_{11}\) \(n_{12}\) \(\cdots\) \(n_{1c}\) \(n_{1\bullet}\)
\(X = 2\) \(n_{21}\) \(n_{22}\) \(\cdots\) \(n_{2c}\) \(n_{2\bullet}\)
\(\vdots\) \(\vdots\) \(\vdots\) \(\ddots\) \(\vdots\) \(\vdots\)
\(X = r\) \(n_{r1}\) \(n_{r2}\) \(\cdots\) \(n_{rc}\) \(n_{r\bullet}\)
Total Kolom \(n_{\bullet 1}\) \(n_{\bullet 2}\) \(\cdots\) \(n_{\bullet c}\) \(n\)

Keterangan:

  • \(n_{ij}\): frekuensi observasi pada baris ke-\(i\) dan kolom ke-\(j\)
  • \(n_{i\bullet} = \sum_j n_{ij}\): total marginal baris ke-\(i\)
  • \(n_{\bullet j} = \sum_i n_{ij}\): total marginal kolom ke-\(j\)
  • \(n = \sum_i \sum_j n_{ij}\): total keseluruhan observasi

1.2.3 Konsep Joint Distribution

Distribusi Bersama (Joint Distribution) menggambarkan probabilitas bahwa dua variabel secara bersamaan mengambil nilai-nilai tertentu.

Secara formal, joint probability didefinisikan sebagai:

\[\pi_{ij} = P(X = i, Y = j)\]

Ditaksir dari data sampel sebagai:

\[\hat{\pi}_{ij} = \frac{n_{ij}}{n}\]

dengan syarat:

\[\sum_{i=1}^{r} \sum_{j=1}^{c} \pi_{ij} = 1\]

Joint distribution memberikan gambaran lengkap tentang sebaran bersama dua variabel kategori dalam suatu populasi.

1.2.4 Konsep Marginal Distribution

Distribusi Marginal (Marginal Distribution) adalah distribusi probabilitas untuk satu variabel, diperoleh dengan menjumlahkan (memarjinalkan) probabilitas bersama atas semua nilai variabel lainnya.

Marginal distribution untuk baris (variabel X):

\[\pi_{i\bullet} = P(X = i) = \sum_{j=1}^{c} \pi_{ij}\]

Marginal distribution untuk kolom (variabel Y):

\[\pi_{\bullet j} = P(Y = j) = \sum_{i=1}^{r} \pi_{ij}\]

Distribusi marginal memberikan informasi tentang distribusi masing-masing variabel secara terpisah, tanpa memperhatikan variabel lainnya.

1.2.5 Konsep Conditional Probability

Probabilitas Bersyarat (Conditional Probability) adalah probabilitas suatu kejadian terjadi, dengan syarat bahwa kejadian lain telah diketahui terjadi.

Probabilitas bersyarat Y = j diberikan X = i:

\[P(Y = j \mid X = i) = \frac{P(X = i, Y = j)}{P(X = i)} = \frac{\pi_{ij}}{\pi_{i\bullet}}\]

Probabilitas bersyarat X = i diberikan Y = j:

\[P(X = i \mid Y = j) = \frac{\pi_{ij}}{\pi_{\bullet j}}\]

Jika \(P(Y = j \mid X = i) = P(Y = j)\) untuk semua \(i\) dan \(j\), maka variabel \(X\) dan \(Y\) dikatakan independen (saling bebas).

1.2.6 Contoh Tabel Kontingensi 2×2

Misalkan sebuah penelitian mengamati hubungan antara kebiasaan membaca buku (Rutin/Tidak Rutin) dan kemampuan berpikir kritis (Tinggi/Rendah) pada 200 mahasiswa:

# Membuat tabel kontingensi 2x2
tabel_buku <- matrix(c(80, 20, 40, 60),
                     nrow = 2, byrow = TRUE)
rownames(tabel_buku) <- c("Rutin Membaca", "Tidak Rutin")
colnames(tabel_buku) <- c("Berpikir Kritis Tinggi", "Berpikir Kritis Rendah")

# Tampilkan tabel frekuensi
cat("=== Tabel Kontingensi: Kebiasaan Membaca vs Berpikir Kritis ===\n\n")
#> === Tabel Kontingensi: Kebiasaan Membaca vs Berpikir Kritis ===
print(addmargins(tabel_buku))
#>               Berpikir Kritis Tinggi Berpikir Kritis Rendah Sum
#> Rutin Membaca                     80                     20 100
#> Tidak Rutin                       40                     60 100
#> Sum                              120                     80 200

Interpretasi distribusi:

n_total <- sum(tabel_buku)

cat("=== Joint Distribution (Proporsi Bersama) ===\n")
#> === Joint Distribution (Proporsi Bersama) ===
joint <- round(tabel_buku / n_total, 4)
print(addmargins(joint))
#>               Berpikir Kritis Tinggi Berpikir Kritis Rendah Sum
#> Rutin Membaca                    0.4                    0.1 0.5
#> Tidak Rutin                      0.2                    0.3 0.5
#> Sum                              0.6                    0.4 1.0
cat("\n=== Marginal Distribution Baris (P(X=i)) ===\n")
#> 
#> === Marginal Distribution Baris (P(X=i)) ===
marg_baris <- rowSums(tabel_buku) / n_total
print(round(marg_baris, 4))
#> Rutin Membaca   Tidak Rutin 
#>           0.5           0.5
cat("\n=== Marginal Distribution Kolom (P(Y=j)) ===\n")
#> 
#> === Marginal Distribution Kolom (P(Y=j)) ===
marg_kolom <- colSums(tabel_buku) / n_total
print(round(marg_kolom, 4))
#> Berpikir Kritis Tinggi Berpikir Kritis Rendah 
#>                    0.6                    0.4
cat("\n=== Conditional Probability P(Y | X) ===\n")
#> 
#> === Conditional Probability P(Y | X) ===
cond_prob <- round(prop.table(tabel_buku, margin = 1), 4)
print(cond_prob)
#>               Berpikir Kritis Tinggi Berpikir Kritis Rendah
#> Rutin Membaca                    0.8                    0.2
#> Tidak Rutin                      0.4                    0.6

1.3 Ukuran Asosiasi

1.3.1 Penjelasan Ukuran Asosiasi pada Tabel Kontingensi

Ukuran Asosiasi (Measures of Association) adalah statistik yang mengukur kekuatan dan arah hubungan antara dua variabel kategori. Ukuran ini sangat penting dalam epidemiologi, ilmu kesehatan, dan ilmu sosial untuk menginterpretasikan besarnya hubungan antar variabel.

Pada tabel kontingensi \(2 \times 2\), notasi sel adalah sebagai berikut:

Outcome (+) Outcome (−) Total
Exposed (+) \(a\) \(b\) \(a + b\)
Not Exposed (−) \(c\) \(d\) \(c + d\)
Total \(a + c\) \(b + d\) \(n\)

1.3.2 Rumus Matematis Ukuran Asosiasi

1.3.2.1 Odds

Odds adalah rasio antara peluang suatu kejadian terjadi dengan peluang kejadian tersebut tidak terjadi.

Odds untuk kelompok Exposed: \[\text{Odds}_{\text{exposed}} = \frac{a / (a+b)}{b / (a+b)} = \frac{a}{b}\]

Odds untuk kelompok Not Exposed: \[\text{Odds}_{\text{unexposed}} = \frac{c / (c+d)}{d / (c+d)} = \frac{c}{d}\]

Interpretasi: Odds = 3 berarti kejadian 3 kali lebih mungkin terjadi dibandingkan tidak terjadi.

1.3.2.2 Odds Ratio (OR)

Odds Ratio adalah rasio antara odds pada kelompok terpapar (exposed) dibandingkan dengan odds pada kelompok tidak terpapar (unexposed).

\[\text{OR} = \frac{\text{Odds}_{\text{exposed}}}{\text{Odds}_{\text{unexposed}}} = \frac{a/b}{c/d} = \frac{ad}{bc}\]

Interpretasi: - \(\text{OR} = 1\): Tidak ada asosiasi antara paparan dan outcome - \(\text{OR} > 1\): Paparan meningkatkan risiko outcome (faktor risiko) - \(\text{OR} < 1\): Paparan menurunkan risiko outcome (faktor protektif)

1.3.2.3 Relative Risk (RR)

Relative Risk (atau Risk Ratio) adalah rasio antara risiko (probabilitas) terjadinya outcome pada kelompok terpapar dibandingkan pada kelompok tidak terpapar.

\[\text{RR} = \frac{P(\text{Outcome} \mid \text{Exposed})}{P(\text{Outcome} \mid \text{Not Exposed})} = \frac{a/(a+b)}{c/(c+d)}\]

Interpretasi: - \(\text{RR} = 1\): Risiko sama di kedua kelompok - \(\text{RR} > 1\): Kelompok terpapar memiliki risiko lebih tinggi - \(\text{RR} < 1\): Kelompok terpapar memiliki risiko lebih rendah

Catatan: RR hanya dapat dihitung pada studi kohort atau cross-sectional. Pada studi case-control, gunakan OR sebagai pendekatan.


1.4 Contoh Perhitungan Manual

1.4.1 Studi Kasus: Paparan Polusi Udara dan Kejadian Asma pada Anak

Latar Belakang: Penelitian ini menginvestigasi apakah anak-anak yang tinggal di dekat kawasan industri (paparan polusi udara tinggi) memiliki risiko kejadian asma yang lebih besar dibandingkan anak-anak yang tinggal di kawasan perumahan (paparan rendah).

Desain: Studi kohort prospektif, n = 300 anak usia 6–12 tahun, observasi selama 2 tahun.

1.4.2 Membuat Tabel Kontingensi

Data yang diperoleh dari penelitian adalah sebagai berikut:

Asma (+) Asma (−) Total
Dekat Industri 75 75 150
Jauh dari Industri 30 120 150
Total 105 195 300

Sehingga: \(a = 75\), \(b = 75\), \(c = 30\), \(d = 120\), \(n = 300\)

1.4.3 Menghitung Peluang Bersyarat

Peluang Asma pada anak dekat industri:

\[P(\text{Asma} \mid \text{Dekat Industri}) = \frac{a}{a + b} = \frac{75}{75 + 75} = \frac{75}{150} = 0{,}50\]

Peluang Asma pada anak jauh dari industri:

\[P(\text{Asma} \mid \text{Jauh dari Industri}) = \frac{c}{c + d} = \frac{30}{30 + 120} = \frac{30}{150} = 0{,}20\]

1.4.4 Menghitung Odds

Odds Asma pada kelompok Dekat Industri:

\[\text{Odds}_{\text{dekat}} = \frac{a}{b} = \frac{75}{75} = 1{,}00\]

Artinya: Anak di dekat industri memiliki peluang asma sama besar dengan peluang tidak asma (1:1).

Odds Asma pada kelompok Jauh dari Industri:

\[\text{Odds}_{\text{jauh}} = \frac{c}{d} = \frac{30}{120} = 0{,}25\]

Artinya: Anak jauh dari industri, peluang asma 4 kali lebih kecil dari peluang tidak asma.

1.5 Menghitung Odds Ratio

\[\text{OR} = \frac{\text{Odds}_{\text{dekat}}}{\text{Odds}_{\text{jauh}}} = \frac{a/b}{c/d} = \frac{ad}{bc} = \frac{75 \times 120}{75 \times 30} = \frac{9000}{2250} = 4{,}00\]

Menghitung Relative Risk:

\[\text{RR} = \frac{a/(a+b)}{c/(c+d)} = \frac{75/150}{30/150} = \frac{0{,}50}{0{,}20} = 2{,}50\]

Kesimpulan Perhitungan Manual:

  • Peluang bersyarat: Anak dekat industri memiliki peluang asma 50%, sementara anak jauh dari industri hanya 20%.
  • Odds Ratio = 4,00: Anak yang tinggal dekat kawasan industri memiliki odds terkena asma 4 kali lebih besar dibandingkan anak yang jauh dari industri.
  • Relative Risk = 2,50: Risiko asma pada anak dekat industri 2,5 kali lebih tinggi dibandingkan anak jauh dari industri.

1.6 Analisis Menggunakan R

1.6.1 Membuat Tabel Kontingensi

# ============================================================
# DATA: Paparan Polusi Udara vs Kejadian Asma pada Anak
# ============================================================
data_asma <- matrix(c(75, 75, 30, 120),
                    nrow = 2,
                    byrow = TRUE)

rownames(data_asma) <- c("Dekat Industri", "Jauh dari Industri")
colnames(data_asma) <- c("Asma (+)", "Asma (-)")

cat("=== Tabel Kontingensi: Paparan Polusi vs Asma ===\n\n")
#> === Tabel Kontingensi: Paparan Polusi vs Asma ===
print(addmargins(data_asma))
#>                    Asma (+) Asma (-) Sum
#> Dekat Industri           75       75 150
#> Jauh dari Industri       30      120 150
#> Sum                     105      195 300

1.6.2 Menghitung Odds Ratio

# ----- Menghitung Odds -----
a <- data_asma[1, 1]  # Dekat Industri & Asma
b <- data_asma[1, 2]  # Dekat Industri & Tidak Asma
c_val <- data_asma[2, 1]  # Jauh dari Industri & Asma
d <- data_asma[2, 2]  # Jauh dari Industri & Tidak Asma

odds_dekat <- a / b
odds_jauh  <- c_val / d
OR_manual  <- (a * d) / (b * c_val)
RR_manual  <- (a / (a + b)) / (c_val / (c_val + d))

cat("=== Hasil Perhitungan Ukuran Asosiasi ===\n\n")
#> === Hasil Perhitungan Ukuran Asosiasi ===
cat(sprintf("Odds (Dekat Industri)      : %.4f\n", odds_dekat))
#> Odds (Dekat Industri)      : 1.0000
cat(sprintf("Odds (Jauh dari Industri)  : %.4f\n", odds_jauh))
#> Odds (Jauh dari Industri)  : 0.2500
cat(sprintf("Odds Ratio (OR)            : %.4f\n", OR_manual))
#> Odds Ratio (OR)            : 4.0000
cat(sprintf("Relative Risk (RR)         : %.4f\n", RR_manual))
#> Relative Risk (RR)         : 2.5000
# ----- Menggunakan fungsi fisher.test untuk OR & CI -----
cat("\n=== Odds Ratio dengan Confidence Interval (Fisher's Exact Test) ===\n\n")
#> 
#> === Odds Ratio dengan Confidence Interval (Fisher's Exact Test) ===
hasil_fisher <- fisher.test(data_asma)
print(hasil_fisher)
#> 
#>  Fisher's Exact Test for Count Data
#> 
#> data:  data_asma
#> p-value = 7.201e-08
#> alternative hypothesis: true odds ratio is not equal to 1
#> 95 percent confidence interval:
#>  2.329297 6.928419
#> sample estimates:
#> odds ratio 
#>   3.980505

1.6.3 Melakukan Uji Chi-Square

# ----- Uji Chi-Square -----
cat("=== Uji Chi-Square: Independensi Paparan Polusi vs Asma ===\n\n")
#> === Uji Chi-Square: Independensi Paparan Polusi vs Asma ===
hasil_chisq <- chisq.test(data_asma)
print(hasil_chisq)
#> 
#>  Pearson's Chi-squared test with Yates' continuity correction
#> 
#> data:  data_asma
#> X-squared = 28.366, df = 1, p-value = 1.004e-07
# ----- Frekuensi Harapan -----
cat("\n=== Frekuensi Harapan (Expected Frequencies) ===\n\n")
#> 
#> === Frekuensi Harapan (Expected Frequencies) ===
print(round(hasil_chisq$expected, 2))
#>                    Asma (+) Asma (-)
#> Dekat Industri         52.5     97.5
#> Jauh dari Industri     52.5     97.5

1.6.4 Visualisasi Data

par(mfrow = c(1, 2), mar = c(5, 4, 4, 2) + 0.1)

# --- Plot 1: Grouped Bar Chart ---
barplot(t(prop.table(data_asma, margin = 1)),
        beside = FALSE,
        col = c("#2e86c1", "#aed6f1"),
        main = "Proporsi Kejadian Asma\nBerdasarkan Kelompok Paparan",
        ylab = "Proporsi",
        ylim = c(0, 1.1),
        legend.text = colnames(data_asma),
        args.legend = list(x = "topright", bty = "n", cex = 0.9),
        border = "white")
box()

# --- Plot 2: Odds Ratio Plot ---
or_val <- OR_manual
ci_lower <- exp(log(or_val) - 1.96 * sqrt(1/a + 1/b + 1/c_val + 1/d))
ci_upper <- exp(log(or_val) + 1.96 * sqrt(1/a + 1/b + 1/c_val + 1/d))

plot(1, or_val,
     xlim = c(0.5, 1.5),
     ylim = c(0, 8),
     xaxt = "n",
     xlab = "",
     ylab = "Odds Ratio",
     main = "Odds Ratio dengan\n95% Confidence Interval",
     pch = 18, cex = 2.5, col = "#1a5276")

abline(h = 1, lty = 2, col = "red", lwd = 2)
segments(1, ci_lower, 1, ci_upper, col = "#1a5276", lwd = 2)
segments(0.95, ci_lower, 1.05, ci_lower, col = "#1a5276", lwd = 2)
segments(0.95, ci_upper, 1.05, ci_upper, col = "#1a5276", lwd = 2)

text(1, or_val + 0.4,
     labels = sprintf("OR = %.2f\n95%% CI: [%.2f, %.2f]", or_val, ci_lower, ci_upper),
     cex = 0.9, col = "#1a5276", font = 2)

par(mfrow = c(1, 1))

1.6.5 Ringkasan Output R

cat("============================================================\n")
#> ============================================================
cat("       RINGKASAN HASIL ANALISIS DATA KATEGORI\n")
#>        RINGKASAN HASIL ANALISIS DATA KATEGORI
cat("       Studi: Paparan Polusi Udara vs Asma Anak\n")
#>        Studi: Paparan Polusi Udara vs Asma Anak
cat("============================================================\n\n")
#> ============================================================
cat(sprintf("Jumlah Sampel Total         : %d anak\n", sum(data_asma)))
#> Jumlah Sampel Total         : 300 anak
cat(sprintf("Prevalensi Asma (Overall)   : %.1f%%\n",
            100 * sum(data_asma[, 1]) / sum(data_asma)))
#> Prevalensi Asma (Overall)   : 35.0%
cat(sprintf("Prevalensi - Dekat Industri : %.1f%%\n", 100 * a/(a+b)))
#> Prevalensi - Dekat Industri : 50.0%
cat(sprintf("Prevalensi - Jauh Industri  : %.1f%%\n\n", 100 * c_val/(c_val+d)))
#> Prevalensi - Jauh Industri  : 20.0%
cat(sprintf("Odds Ratio (OR)             : %.4f\n", OR_manual))
#> Odds Ratio (OR)             : 4.0000
cat(sprintf("95%% CI untuk OR             : [%.4f, %.4f]\n", ci_lower, ci_upper))
#> 95% CI untuk OR             : [2.3963, 6.6769]
cat(sprintf("Relative Risk (RR)          : %.4f\n\n", RR_manual))
#> Relative Risk (RR)          : 2.5000
cat(sprintf("Chi-Square Statistic (X²)   : %.4f\n", hasil_chisq$statistic))
#> Chi-Square Statistic (X²)   : 28.3663
cat(sprintf("Derajat Kebebasan (df)       : %d\n", hasil_chisq$parameter))
#> Derajat Kebebasan (df)       : 1
cat(sprintf("p-value                     : %.6f\n\n", hasil_chisq$p.value))
#> p-value                     : 0.000000
cat("============================================================\n")
#> ============================================================

1.7 Interpretasi Hasil

1.7.1 Interpretasi Statistik Deskriptif

Dari 300 anak yang diamati, terdapat 105 anak (35%) yang didiagnosis menderita asma. Proporsi asma pada anak yang tinggal dekat kawasan industri adalah 50% (75 dari 150 anak), jauh lebih tinggi dibandingkan anak yang tinggal jauh dari industri sebesar 20% (30 dari 150 anak).

1.7.2 Interpretasi Peluang Bersyarat

Probabilitas bersyarat menunjukkan bahwa:

  • \(P(\text{Asma} \mid \text{Dekat Industri}) = 0{,}50\): Setiap anak yang tinggal dekat kawasan industri memiliki peluang 50% untuk menderita asma.
  • \(P(\text{Asma} \mid \text{Jauh dari Industri}) = 0{,}20\): Setiap anak yang tinggal jauh dari kawasan industri hanya memiliki peluang 20% untuk menderita asma.

Perbedaan substansial ini mengindikasikan adanya hubungan antara paparan polusi dan kejadian asma.

1.7.3 Interpretasi Odds dan Odds Ratio

  • Odds (Dekat Industri) = 1,00: Pada kelompok ini, kemungkinan asma sama besar dengan kemungkinan tidak asma (perbandingan 1:1).
  • Odds (Jauh dari Industri) = 0,25: Pada kelompok ini, kemungkinan asma hanya seperempat dari kemungkinan tidak asma.
  • Odds Ratio = 4,00: Anak yang tinggal dekat kawasan industri memiliki odds terkena asma 4 kali lebih besar dibandingkan anak yang tinggal jauh dari industri. Karena OR > 1, maka paparan polusi merupakan faktor risiko kejadian asma.

1.7.4 Interpretasi Relative Risk

Relative Risk = 2,50: Risiko terkena asma pada anak dekat kawasan industri adalah 2,5 kali lebih tinggi dibandingkan anak jauh dari industri. Ini berarti paparan polusi udara secara substansial meningkatkan risiko asma pada anak.

1.7.5 Interpretasi Uji Chi-Square

Berdasarkan hasil uji chi-square:

  • Nilai statistik \(\chi^2\) yang besar dan nilai \(p\)-value \(< 0{,}05\) menunjukkan bahwa kita menolak hipotesis nol (\(H_0\): paparan polusi dan kejadian asma saling independen).
  • Terdapat bukti statistik yang kuat bahwa terdapat hubungan yang signifikan antara paparan polusi udara (tinggal dekat industri) dan kejadian asma pada anak.
  • Seluruh frekuensi harapan (expected frequencies) bernilai > 5, sehingga asumsi uji chi-square terpenuhi dan hasilnya dapat dipercaya.

1.7.6 Implikasi Praktis

Temuan Nilai Makna Praktis
Prevalensi asma - dekat industri 50% Sangat tinggi, perlu intervensi segera
Prevalensi asma - jauh industri 20% Referensi baseline populasi sehat
Odds Ratio 4,00 Paparan polusi merupakan faktor risiko kuat
Relative Risk 2,50 Risiko meningkat 2,5 kali lipat akibat paparan
p-value < 0,05 Hubungan signifikan secara statistik

Kesimpulan Akhir:

Hasil analisis data kategori dengan tabel kontingensi \(2 \times 2\) secara konsisten menunjukkan bahwa paparan polusi udara dari kawasan industri memiliki asosiasi positif yang signifikan dengan kejadian asma pada anak. Nilai OR = 4,00 dan RR = 2,50, dikonfirmasi oleh uji chi-square yang signifikan (\(p < 0{,}05\)), mengindikasikan bahwa anak-anak yang tinggal dekat kawasan industri berisiko jauh lebih tinggi untuk menderita asma.

Temuan ini memiliki implikasi penting bagi kebijakan kesehatan lingkungan, khususnya dalam pengaturan zonasi pemukiman di sekitar kawasan industri dan program pengendalian polusi udara untuk melindungi kesehatan anak.


Laporan ini dibuat menggunakan R Markdown. Seluruh perhitungan dan visualisasi dihasilkan secara reproducible menggunakan R.

#> Dibuat dengan R versi: R version 4.5.1 (2025-06-13 ucrt)
#> Tanggal render: 10 April 2026

2 Tugas 6 Inferensi Tabel Kontingensi Dua Arah - Fathia Salwadifina

2.1 Pendahuluan

Laporan ini menyajikan analisis inferensi statistik pada tabel kontingensi dua arah menggunakan pendekatan data kategorik. Terdapat dua kasus yang dianalisis:

  • Kasus 1 (2×2): Hubungan antara kebiasaan merokok dan kejadian kanker paru.
  • Kasus 2 (2×3): Hubungan antara gender dan identifikasi partai politik.

Analisis dilakukan menggunakan berbagai metode inferensi kategorik, meliputi estimasi proporsi, uji dua proporsi, uji chi-square, uji likelihood ratio, Fisher exact test, serta analisis residual dan partisi chi-square.

# Load paket yang diperlukan
library(epitools)
library(vcd)
library(DescTools)
library(knitr)
library(kableExtra)
library(ggplot2)
library(dplyr)
library(tidyr)

2.2 Kasus 1: Tabel Kontingensi 2×2

2.2.1 Data dan Penyusunan Tabel Kontingensi

Data berikut menggambarkan hubungan antara kebiasaan merokok (Smoker vs Non-Smoker) dan status kanker paru (Cancer (+) vs Control (−)).

# Input data
tabel1 <- matrix(
  c(688, 650, 21, 59),
  nrow = 2,
  byrow = TRUE,
  dimnames = list(
    "Status Merokok" = c("Smoker", "Non-Smoker"),
    "Status Kanker"  = c("Cancer (+)", "Control (-)")
  )
)

# Tambahkan total baris dan kolom
tabel1_df <- as.data.frame.matrix(tabel1)
tabel1_df$Total <- rowSums(tabel1_df)
total_row <- colSums(tabel1_df)
tabel1_display <- rbind(tabel1_df, Total = total_row)

kable(tabel1_display,
      caption = "Tabel Kontingensi 2×2: Merokok dan Kanker Paru",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "bordered"),
                full_width = FALSE) %>%
  row_spec(3, bold = TRUE, background = "#f0f0f0") %>%
  column_spec(4, bold = TRUE)
Tabel Kontingensi 2×2: Merokok dan Kanker Paru
Cancer (+) Control (-) Total
Smoker 688 650 1338
Non-Smoker 21 59 80
Total 709 709 1418

2.2.2 Estimasi Titik Proporsi

Rumus: Proporsi kejadian kanker paru pada masing-masing kelompok:

\[\hat{p}_i = \frac{n_{i,\text{Cancer}}}{n_{i,\text{Total}}}\]

n_smoker     <- 1338
n_nonsmoker  <- 80
x_smoker     <- 688
x_nonsmoker  <- 21

p_smoker    <- x_smoker / n_smoker
p_nonsmoker <- x_nonsmoker / n_nonsmoker

cat("Proporsi kanker pada Smoker    :", round(p_smoker, 4), "\n")
#> Proporsi kanker pada Smoker    : 0.5142
cat("Proporsi kanker pada Non-Smoker:", round(p_nonsmoker, 4), "\n")
#> Proporsi kanker pada Non-Smoker: 0.2625

Interpretasi: Proporsi kanker paru pada kelompok perokok (= 51.42%) lebih besar dua kali lipat dibandingkan non-perokok (= 26.25%), hal tersebut mengindikasikan adanya perbedaan risiko yang substansial antara kedua kelompok.

2.2.3 Interval Kepercayaan 95%, RD, RR, dan OR

2.2.3.1 CI Proporsi Smoker

ci_smoker <- prop.test(x_smoker, n_smoker, conf.level = 0.95)
cat("95% CI proporsi kanker - Smoker:\n")
#> 95% CI proporsi kanker - Smoker:
cat("[", round(ci_smoker$conf.int[1], 4), ",",
        round(ci_smoker$conf.int[2], 4), "]\n")
#> [ 0.487 , 0.5413 ]

2.2.3.2 CI Proporsi Non-Smoker

ci_nonsmoker <- prop.test(x_nonsmoker, n_nonsmoker, conf.level = 0.95)
cat("95% CI proporsi kanker - Non-Smoker:\n")
#> 95% CI proporsi kanker - Non-Smoker:
cat("[", round(ci_nonsmoker$conf.int[1], 4), ",",
        round(ci_nonsmoker$conf.int[2], 4), "]\n")
#> [ 0.1733 , 0.3748 ]

2.2.3.3 Risk Difference (RD), RR, dan OR

Rumus:

\[RD = \hat{p}_1 - \hat{p}_2, \quad RR = \frac{\hat{p}_1}{\hat{p}_2}, \quad OR = \frac{\hat{p}_1/(1-\hat{p}_1)}{\hat{p}_2/(1-\hat{p}_2)}\]

# Menggunakan epitools
hasil_epitools <- epitab(tabel1, method = "riskratio")
hasil_or       <- epitab(tabel1, method = "oddsratio")

# RD manual
RD <- p_smoker - p_nonsmoker
SE_RD <- sqrt((p_smoker*(1-p_smoker)/n_smoker) +
              (p_nonsmoker*(1-p_nonsmoker)/n_nonsmoker))
CI_RD_lower <- RD - 1.96 * SE_RD
CI_RD_upper <- RD + 1.96 * SE_RD

cat("=== Risk Difference (RD) ===\n")
#> === Risk Difference (RD) ===
cat("RD   =", round(RD, 4), "\n")
#> RD   = 0.2517
cat("95% CI: [", round(CI_RD_lower, 4), ",", round(CI_RD_upper, 4), "]\n\n")
#> 95% CI: [ 0.1516 , 0.3518 ]
cat("=== Risk Ratio / Relative Risk (RR) ===\n")
#> === Risk Ratio / Relative Risk (RR) ===
print(hasil_epitools$tab)
#>               Status Kanker
#> Status Merokok Cancer (+)        p0 Control (-)        p1 riskratio    lower
#>     Smoker            688 0.5142003         650 0.4857997  1.000000       NA
#>     Non-Smoker         21 0.2625000          59 0.7375000  1.518115 1.317306
#>               Status Kanker
#> Status Merokok    upper      p.value
#>     Smoker           NA           NA
#>     Non-Smoker 1.749536 1.476303e-05
cat("\n=== Odds Ratio (OR) ===\n")
#> 
#> === Odds Ratio (OR) ===
print(hasil_or$tab)
#>               Status Kanker
#> Status Merokok Cancer (+)         p0 Control (-)        p1 oddsratio    lower
#>     Smoker            688 0.97038082         650 0.9167842  1.000000       NA
#>     Non-Smoker         21 0.02961918          59 0.0832158  2.973773 1.786737
#>               Status Kanker
#> Status Merokok    upper      p.value
#>     Smoker           NA           NA
#>     Non-Smoker 4.949427 1.476303e-05

Interpretasi: Berdasarkan hasil yang diperoleh, RD = 0.251, RR > 1, dan OR >> 1 yang secara konsisten menunjukkan bahwa perokok memiliki risiko dan odds terkena kanker paru yang jauh lebih besar dibandingkan non-perokok. Ketiga ukuran ini mengindikasikan asosiasi yang kuat antara kebiasaan merokok dan kejadian kanker paru.

2.2.4 Uji Dua Proporsi

Hipotesis: \[H_0: p_{\text{Smoker}} = p_{\text{Non-Smoker}} \quad \text{vs} \quad H_1: p_{\text{Smoker}} \neq p_{\text{Non-Smoker}}\]

uji_prop <- prop.test(
  x = c(x_smoker, x_nonsmoker),
  n = c(n_smoker, n_nonsmoker),
  correct = FALSE
)
print(uji_prop)
#> 
#>  2-sample test for equality of proportions without continuity correction
#> 
#> data:  c(x_smoker, x_nonsmoker) out of c(n_smoker, n_nonsmoker)
#> X-squared = 19.129, df = 1, p-value = 1.222e-05
#> alternative hypothesis: two.sided
#> 95 percent confidence interval:
#>  0.1516343 0.3517663
#> sample estimates:
#>    prop 1    prop 2 
#> 0.5142003 0.2625000

Interpretasi: Berdasarkan hasil Uji Dua Proporsi, diperoleh p-value < 0.05, sehingga \(H_0\) ditolak dan dapat disimpulkan bahwa terdapat perbedaan proporsi kejadian kanker paru yang signifikan antara kelompok perokok dan non-perokok.

2.2.5 Uji Chi-Square Independensi

Hipotesis: \[H_0: \text{Status merokok dan kanker paru independen} \quad \text{vs} \quad H_1: \text{keduanya tidak independen}\]

\[\chi^2 = \sum \frac{(O - E)^2}{E}\]

uji_chi1 <- chisq.test(tabel1, correct = FALSE)
print(uji_chi1)
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  tabel1
#> X-squared = 19.129, df = 1, p-value = 1.222e-05
cat("\nFrekuensi Harapan (Expected):\n")
#> 
#> Frekuensi Harapan (Expected):
round(uji_chi1$expected, 2)
#>               Status Kanker
#> Status Merokok Cancer (+) Control (-)
#>     Smoker            669         669
#>     Non-Smoker         40          40

Interpretasi: Berdasarkan hasil Uji Chi-Square Independensi, diperoleh \(\chi^2\) = 19.129 (df = 1, p-value = 1.221601e-05). Karena p-value < 0.001, \(H_0\) ditolak maka dapat disimpulkan bahwa status merokok dan kejadian kanker paru terbukti tidak independen.

2.2.6 Uji Likelihood Ratio (G²)

Rumus: \[G^2 = 2 \sum O_{ij} \ln\left(\frac{O_{ij}}{E_{ij}}\right)\]

O <- as.vector(tabel1)
E <- as.vector(uji_chi1$expected)
G2 <- 2 * sum(O * log(O / E))
df_G2 <- (nrow(tabel1) - 1) * (ncol(tabel1) - 1)
p_G2 <- pchisq(G2, df = df_G2, lower.tail = FALSE)

cat("G² (Likelihood Ratio) =", round(G2, 4), "\n")
#> G² (Likelihood Ratio) = 19.878
cat("df =", df_G2, "\n")
#> df = 1
cat("p-value =", format(p_G2, scientific = TRUE), "\n")
#> p-value = 8.25441e-06

Interpretasi: Berdasarkan hasil Uji Likelihood Ratio, diperoleh G² = 19.878 dengan p-value < 0.001, sehingga \(H_0\) ditolak. Hasil ini konsisten dengan uji chi-square dan memperkuat kesimpulan bahwa terdapat hubungan signifikan antara kebiasaan merokok dan kejadian kanker paru.

2.2.7 Fisher Exact Test

uji_fisher <- fisher.test(tabel1)
print(uji_fisher)
#> 
#>  Fisher's Exact Test for Count Data
#> 
#> data:  tabel1
#> p-value = 1.476e-05
#> alternative hypothesis: true odds ratio is not equal to 1
#> 95 percent confidence interval:
#>  1.755611 5.210711
#> sample estimates:
#> odds ratio 
#>   2.971634

Interpretasi: Berdasarkan hasil Fisher Exact Test, diperoleh p-value < 0.001 dengan OR = 2.972 (95% CI: [1.756, 5.211]). Karena p-value < 0.05 dan seluruh interval kepercayaan OR > 1, dapat disimpulkan bahwa terdapat asosiasi signifikan antara kebiasaan merokok dan kejadian kanker paru.

2.2.8 Perbandingan Hasil Uji (Butir 4–7)

perbandingan <- data.frame(
  Metode        = c("Uji Dua Proporsi", "Chi-Square", "Likelihood Ratio (G²)", "Fisher Exact Test"),
  Statistik_Uji = c(round(uji_prop$statistic, 3),
                    round(uji_chi1$statistic, 3),
                    round(G2, 3),
                    "—"),
  p_value       = c(format(uji_prop$p.value, scientific=TRUE),
                    format(uji_chi1$p.value, scientific=TRUE),
                    format(p_G2, scientific=TRUE),
                    format(uji_fisher$p.value, scientific=TRUE)),
  Keputusan     = rep("Tolak H₀", 4),
  Interpretasi  = c(
    "Proporsi kanker berbeda signifikan antar kelompok",
    "Merokok & kanker tidak independen",
    "Konsisten: asosiasi signifikan",
    "Asosiasi kuat; OR >> 1"
  )
)

kable(perbandingan,
      caption = "Perbandingan Hasil Uji Statistik – Kasus 1",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped","hover","bordered"),
                full_width = TRUE) %>%
  column_spec(1, bold = TRUE)
Perbandingan Hasil Uji Statistik – Kasus 1
Metode Statistik_Uji p_value Keputusan Interpretasi
Uji Dua Proporsi 19.129 1.221601e-05 Tolak H₀ Proporsi kanker berbeda signifikan antar kelompok
Chi-Square 19.129 1.221601e-05 Tolak H₀ Merokok & kanker tidak independen
Likelihood Ratio (G²) 19.878 8.25441e-06 Tolak H₀ Konsisten: asosiasi signifikan
Fisher Exact Test 1.476303e-05 Tolak H₀ Asosiasi kuat; OR >> 1

Ringkasan: Seluruh metode (uji dua proporsi, chi-square, likelihood ratio, dan Fisher exact test) menghasilkan keputusan yang sama: tolak H₀. Tidak ada perbedaan substantif antar metode karena ukuran sampel besar dan seluruh frekuensi harapan > 5. Fisher exact test lebih konservatif dan cocok untuk sampel kecil, namun di sini hasilnya konsisten.

2.2.9 Visualisasi Kasus 1

par(mfrow = c(1, 2))

# Mosaic plot
mosaic(tabel1,
       shade = TRUE,
       legend = TRUE,
       main = "Mosaic Plot: Merokok vs Kanker Paru",
       labeling_args = list(set_varnames = c(
         "Status Merokok" = "Status Merokok",
         "Status Kanker"  = "Status Kanker")))

# Grafik proporsi
prop_df <- data.frame(
  Kelompok = c("Smoker", "Non-Smoker"),
  Proporsi = c(p_smoker, p_nonsmoker),
  Lower    = c(ci_smoker$conf.int[1], ci_nonsmoker$conf.int[1]),
  Upper    = c(ci_smoker$conf.int[2], ci_nonsmoker$conf.int[2])
)

barplot(
  prop_df$Proporsi,
  names.arg = prop_df$Kelompok,
  col = c("#FF6A6A", "#7AC5CD"),
  ylim = c(0, 0.7),
  ylab = "Proporsi Kanker Paru",
  main = "Proporsi Kanker Paru per Kelompok",
  las = 1
)
arrows(
  x0 = c(0.7, 1.9),
  y0 = prop_df$Lower,
  y1 = prop_df$Upper,
  angle = 90, code = 3, length = 0.1, lwd = 2
)
abline(h = 0, col = "black")

par(mfrow = c(1, 1))

Interpretasi Visualisasi: Mosaic plot menampilkan warna biru pada sel Smoker–Cancer(+) dan merah pada Non-Smoker–Cancer(+), mengonfirmasi asosiasi yang nyata antara kedua variabel. Grafik proporsi memperlihatkan perbedaan mencolok dengan interval kepercayaan yang tidak saling tumpang tindih, menegaskan signifikansi statistisnya.

2.2.10 Kesimpulan Kasus 1

Berdasarkan semua analisis yang telah dilakukan, terdapat bukti statistik yang sangat kuat bahwa kebiasaan merokok berhubungan dengan kejadian kanker paru. Proporsi kanker pada perokok (= 51.4%) secara signifikan lebih tinggi dibandingkan non-perokok (= 26.3%). Nilai OR yang jauh di atas 1 mengindikasikan bahwa perokok memiliki odds terkena kanker paru yang jauh lebih besar. Keempat metode uji menghasilkan p-value < 0.001 sehingga \(H_0\) (independensi) ditolak pada seluruh taraf signifikansi yang umum digunakan.


2.3 Kasus 2: Tabel Kontingensi 2×3

2.3.1 Data dan Penyusunan Tabel Kontingensi

Data berikut menggambarkan hubungan antara gender dan identifikasi partai politik.

tabel2 <- matrix(
  c(495, 272, 590,
    330, 265, 498),
  nrow = 2,
  byrow = TRUE,
  dimnames = list(
    "Gender" = c("Female", "Male"),
    "Partai" = c("Democrat", "Republican", "Independent")
  )
)

tabel2_df <- as.data.frame.matrix(tabel2)
tabel2_df$Total <- rowSums(tabel2_df)
total_row2 <- colSums(tabel2_df)
tabel2_display <- rbind(tabel2_df, Total = total_row2)

kable(tabel2_display,
      caption = "Tabel Kontingensi 2×3: Gender dan Partai Politik",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped","hover","bordered"),
                full_width = FALSE) %>%
  row_spec(3, bold = TRUE, background = "#f0f0f0") %>%
  column_spec(5, bold = TRUE)
Tabel Kontingensi 2×3: Gender dan Partai Politik
Democrat Republican Independent Total
Female 495 272 590 1357
Male 330 265 498 1093
Total 825 537 1088 2450

2.3.2 Frekuensi Harapan

Rumus: \[E_{ij} = \frac{n_{i\cdot} \times n_{\cdot j}}{n}\]

uji_chi2 <- chisq.test(tabel2, correct = FALSE)

E_df <- as.data.frame(round(uji_chi2$expected, 2))
E_df$Total <- rowSums(E_df)
E_display <- rbind(E_df, Total = colSums(E_df))

kable(E_display,
      caption = "Frekuensi Harapan (Expected Frequencies)",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped","hover","bordered"),
                full_width = FALSE) %>%
  row_spec(3, bold = TRUE, background = "#f0f0f0")
Frekuensi Harapan (Expected Frequencies)
Democrat Republican Independent Total
Female 456.95 297.43 602.62 1357
Male 368.05 239.57 485.38 1093
Total 825.00 537.00 1088.00 2450

Semua frekuensi harapan > 5, sehingga asumsi uji chi-square terpenuhi.

2.3.3 Uji Chi-Square Independensi

Hipotesis: \[H_0: \text{Gender dan Partai Politik independen} \quad \text{vs} \quad H_1: \text{keduanya tidak independen}\]

print(uji_chi2)
#> 
#>  Pearson's Chi-squared test
#> 
#> data:  tabel2
#> X-squared = 12.569, df = 2, p-value = 0.001865

Interpretasi: Berdasarkan hasil Uji Chi-Square Independensi, diperoleh \(\chi^2\) = 12.569 (df = 2, p-value = 0.0019). Karena p-value < 0.05, \(H_0\) ditolak maka dapat disimpulkan bahwa gender dan identifikasi partai politik terbukti tidak independen.

2.3.4 Residual Pearson dan Standardized Residual

Rumus:

\[\text{Residual Pearson: } r_{ij} = \frac{O_{ij} - E_{ij}}{\sqrt{E_{ij}}}\]

\[\text{Standardized Residual: } d_{ij} = \frac{O_{ij} - E_{ij}}{\sqrt{E_{ij}(1-p_{i\cdot})(1-p_{\cdot j})}}\]

# Residual Pearson
pearson_res <- (tabel2 - uji_chi2$expected) / sqrt(uji_chi2$expected)
cat("=== Residual Pearson ===\n")
#> === Residual Pearson ===
print(round(pearson_res, 3))
#>         Partai
#> Gender   Democrat Republican Independent
#>   Female    1.780     -1.475      -0.514
#>   Male     -1.983      1.643       0.573
# Standardized residual (dari chisq.test)
std_res <- uji_chi2$stdres
cat("\n=== Standardized Residual ===\n")
#> 
#> === Standardized Residual ===
print(round(std_res, 3))
#>         Partai
#> Gender   Democrat Republican Independent
#>   Female    3.272     -2.499      -1.032
#>   Male     -3.272      2.499       1.032
res_df <- data.frame(
  Sel             = c("Female–Democrat","Female–Republican","Female–Independent",
                      "Male–Democrat","Male–Republican","Male–Independent"),
  Observed        = c(495, 272, 590, 330, 265, 498),
  Expected        = round(as.vector(t(uji_chi2$expected)), 2),
  Pearson_Res     = round(as.vector(t(pearson_res)), 3),
  Std_Residual    = round(as.vector(t(std_res)), 3),
  Interpretasi    = c(
    "Lebih banyak dari harapan (signifikan)",
    "Lebih sedikit dari harapan (signifikan)",
    "Sedikit lebih banyak",
    "Lebih sedikit dari harapan (signifikan)",
    "Lebih banyak dari harapan (signifikan)",
    "Sedikit lebih sedikit"
  )
)

kable(res_df,
      caption = "Residual Pearson dan Standardized Residual – Kasus 2",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped","hover","bordered"),
                full_width = TRUE) %>%
  row_spec(which(abs(res_df$Std_Residual) > 1.96),
           background = "#fff3cd")
Residual Pearson dan Standardized Residual – Kasus 2
Sel Observed Expected Pearson_Res Std_Residual Interpretasi
Female–Democrat 495 456.95 1.780 3.272 Lebih banyak dari harapan (signifikan)
Female–Republican 272 297.43 -1.475 -2.499 Lebih sedikit dari harapan (signifikan)
Female–Independent 590 602.62 -0.514 -1.032 Sedikit lebih banyak
Male–Democrat 330 368.05 -1.983 -3.272 Lebih sedikit dari harapan (signifikan)
Male–Republican 265 239.57 1.643 2.499 Lebih banyak dari harapan (signifikan)
Male–Independent 498 485.38 0.573 1.032 Sedikit lebih sedikit

Interpretasi: Sel Female–Democrat memiliki standardized residual positif signifikan (|d| > 1.96), sedangkan Female–Republican dan Male–Democrat memiliki residual negatif signifikan. Pola ini menunjukkan bahwa wanita cenderung berafiliasi dengan Partai Demokrat, sedangkan pria cenderung ke Partai Republik.

2.3.5 Partisi Chi-Square

2.3.5.1 Partisi 1: Democrat vs Republican (hanya 2 kolom pertama)

tabel2_dem_rep <- tabel2[, c("Democrat", "Republican")]
chi_dem_rep <- chisq.test(tabel2_dem_rep, correct = FALSE)

cat("=== Partisi 1: Democrat vs Republican ===\n")
#> === Partisi 1: Democrat vs Republican ===
print(tabel2_dem_rep)
#>         Partai
#> Gender   Democrat Republican
#>   Female      495        272
#>   Male        330        265
cat("\nChi-Square =", round(chi_dem_rep$statistic, 3),
    "| df =", chi_dem_rep$parameter,
    "| p-value =", round(chi_dem_rep$p.value, 4), "\n")
#> 
#> Chi-Square = 11.555 | df = 1 | p-value = 7e-04

2.3.5.2 Partisi 2: (Democrat + Republican) vs Independent

tabel2_part2 <- cbind(
  "Dem+Rep"     = rowSums(tabel2[, c("Democrat","Republican")]),
  "Independent" = tabel2[, "Independent"]
)
chi_part2 <- chisq.test(tabel2_part2, correct = FALSE)

cat("=== Partisi 2: (Democrat+Republican) vs Independent ===\n")
#> === Partisi 2: (Democrat+Republican) vs Independent ===
print(tabel2_part2)
#>        Dem+Rep Independent
#> Female     767         590
#> Male       595         498
cat("\nChi-Square =", round(chi_part2$statistic, 3),
    "| df =", chi_part2$parameter,
    "| p-value =", round(chi_part2$p.value, 4), "\n")
#> 
#> Chi-Square = 1.065 | df = 1 | p-value = 0.302

2.3.5.3 Perbandingan Partisi dengan Chi-Square Keseluruhan

chi_total <- uji_chi2$statistic
chi_p1    <- chi_dem_rep$statistic
chi_p2    <- chi_part2$statistic
chi_sum   <- chi_p1 + chi_p2

partisi_df <- data.frame(
  Analisis           = c("Chi-Square Keseluruhan (2×3)",
                         "Partisi 1: Dem vs Rep",
                         "Partisi 2: (Dem+Rep) vs Ind",
                         "Jumlah Partisi 1 + 2"),
  Chi_Square         = round(c(chi_total, chi_p1, chi_p2, chi_sum), 3),
  df                 = c(2, 1, 1, 2),
  p_value            = c(round(uji_chi2$p.value, 4),
                         round(chi_dem_rep$p.value, 4),
                         round(chi_part2$p.value, 4),
                         "—"),
  Keputusan          = c("Tolak H₀","Tolak H₀","Tidak Tolak H₀","—")
)

kable(partisi_df,
      caption = "Perbandingan Partisi vs Chi-Square Keseluruhan",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped","hover","bordered"),
                full_width = TRUE) %>%
  row_spec(4, bold = TRUE, background = "#d4edda")
Perbandingan Partisi vs Chi-Square Keseluruhan
Analisis Chi_Square df p_value Keputusan
Chi-Square Keseluruhan (2×3) 12.569 2 0.0019 Tolak H₀
Partisi 1: Dem vs Rep 11.555 1 7e-04 Tolak H₀
Partisi 2: (Dem+Rep) vs Ind 1.065 1 0.302 Tidak Tolak H₀
Jumlah Partisi 1 + 2 12.620 2

Interpretasi Partisi: Dekomposisi aditif terpenuhi karena jumlah chi-square dua partisi ≈ chi-square keseluruhan. Partisi 1 (Democrat vs Republican) signifikan (p < 0.05), sedangkan Partisi 2 ((Dem+Rep) vs Independent) tidak signifikan (p > 0.05), hal tersebut menunjukkan bahwa perbedaan gender hanya nyata pada preferensi antara dua partai utama, bukan pada pilihan Independen.

2.3.6 Visualisasi Kasus 2

par(mfrow = c(2, 2))

# 1. Mosaic plot
mosaic(tabel2,
       shade = TRUE,
       legend = TRUE,
       main = "Mosaic Plot: Gender vs Partai Politik")

# 2. Grafik proporsi per gender
prop2 <- prop.table(tabel2, margin = 1) * 100
barplot(t(prop2),
        beside = TRUE,
        col = c("#104E8B", "#CD5555", "#9BCD9B"),
        legend.text = colnames(tabel2),
        args.legend = list(x = "topright", bty = "n"),
        ylim = c(0, 60),
        ylab = "Proporsi (%)",
        main = "Proporsi Afiliasi Partai per Gender",
        names.arg = c("Female", "Male"),
        las = 1)

# 3. Heatmap standardized residual
std_res_mat <- uji_chi2$stdres
image(1:ncol(std_res_mat), 1:nrow(std_res_mat),
      t(std_res_mat)[, nrow(std_res_mat):1],
      col = colorRampPalette(c("#d73027","white","#4575b4"))(20),
      xlab = "", ylab = "",
      main = "Heatmap Standardized Residual",
      axes = FALSE)
axis(1, at = 1:3, labels = colnames(std_res_mat), las = 1)
axis(2, at = 1:2, labels = rev(rownames(std_res_mat)), las = 1)
for (i in 1:nrow(std_res_mat))
  for (j in 1:ncol(std_res_mat))
    text(j, nrow(std_res_mat) + 1 - i,
         round(std_res_mat[i, j], 2), cex = 1.1, font = 2)
box()

# 4. Grafik partisi chi-square
barplot(
  c(chi_p1, chi_p2),
  names.arg = c("Partisi 1\nDem vs Rep", "Partisi 2\n(D+R) vs Ind"),
  col = c("#e67", "#9b59b6"),
  ylab = expression(chi^2),
  main = "Kontribusi Partisi terhadap Chi-Square Total",
  ylim = c(0, max(chi_p1, chi_p2) * 1.3),
  las = 1
)
abline(h = qchisq(0.95, df = 1), lty = 2, col = "red", lwd = 2)
legend("topright", legend = "Nilai kritis χ²(0.05, df=1)",
       lty = 2, col = "red", bty = "n")

par(mfrow = c(1, 1))

Interpretasi Visualisasi: Mosaic plot dan heatmap residual membuktikan bahwa sel Female–Democrat (residual positif) dan Male–Republican (residual positif) menyimpang paling jauh dari kondisi independensi. Grafik proporsi memperlihatkan wanita lebih cenderung Demokrat dan pria lebih cenderung Republik, sementara grafik partisi menunjukkan hanya Partisi 1 yang melampaui nilai kritis chi-square.

2.3.7 Kesimpulan Kasus 2

Uji chi-square keseluruhan (2×3) menghasilkan p-value < 0.05, menunjukkan bahwa gender dan identifikasi partai politik tidak independen. Analisis residual mengidentifikasi bahwa sel Female–Democrat dan Male–Republican memiliki kontribusi terbesar terhadap asosiasi tersebut. Partisi chi-square mengungkap bahwa perbedaan gender terletak terutama pada preferensi antara Demokrat dan Republik, bukan pada pilihan Independen. Dengan demikian, gender secara signifikan membedakan preferensi antara dua partai utama, tetapi tidak terlalu membedakan kecenderungan memilih jalur Independen.


2.4 Ringkasan Keseluruhan

ringkasan <- data.frame(
  Kasus      = c("Kasus 1 (2×2)", "Kasus 2 (2×3)"),
  Variabel   = c("Merokok vs Kanker Paru", "Gender vs Partai Politik"),
  Chi_Square = c(round(uji_chi1$statistic, 3), round(uji_chi2$statistic, 3)),
  df         = c(uji_chi1$parameter, uji_chi2$parameter),
  p_value    = c(format(uji_chi1$p.value, scientific = TRUE),
                 round(uji_chi2$p.value, 4)),
  Kesimpulan = c("Terdapat hubungan signifikan (perokok berisiko lebih tinggi)",
                 "Terdapat hubungan signifikan (wanita cenderung Demokrat, pria Republik)")
)

kable(ringkasan,
      caption = "Ringkasan Hasil Analisis",
      align = "c") %>%
  kable_styling(bootstrap_options = c("striped","hover","bordered"),
                full_width = TRUE) %>%
  column_spec(1, bold = TRUE)
Ringkasan Hasil Analisis
Kasus Variabel Chi_Square df p_value Kesimpulan
Kasus 1 (2×2) Merokok vs Kanker Paru 19.129 1 1.221601e-05 Terdapat hubungan signifikan (perokok berisiko lebih tinggi)
Kasus 2 (2×3) Gender vs Partai Politik 12.569 2 0.0019 Terdapat hubungan signifikan (wanita cenderung Demokrat, pria Republik)