Tugas 1: Analisis Data Kategori

Bagian 1: Definisi Analisis Data Kategori

Apa itu Analisis Data Kategori?

Analisis data kategori (categorical data analysis) adalah sekumpulan metode statistik yang digunakan untuk menganalisis data yang diukur dalam skala nominal atau ordinal, yaitu data yang nilainya berupa kategori atau label dan bukan angka kontinu (Agresti, 2013).

Secara formal, variabel kategori membagi observasi ke dalam kelompok-kelompok yang saling eksklusif (mutually exclusive) dan mencakup semua kemungkinan (exhaustive). Metode analisis data kategori mencakup, antara lain:

  • Uji Chi-Square
  • Analisis tabel kontingensi
  • Regresi Logistik
  • Model Log-Linear

Karakteristik Variabel Kategori

Variabel kategori memiliki beberapa karakteristik utama yang membedakannya dari variabel kontinu:

Karakteristik Penjelasan Contoh
Skala Pengukuran Nominal (tanpa urutan) atau Ordinal (dengan urutan) Jenis kelamin, golongan darah
Tipe Nilai Label atau kategori, bukan angka Sakit / Tidak Sakit
Operasi Matematika Tidak dapat dijumlahkan/dikalikan secara langsung Tidak bisa: Laki-laki + Perempuan
Ringkasan Statistik Disajikan dengan frekuensi dan proporsi 40% konsumsi fast food, 60% tidak
Subtipe Umum Nominal, Ordinal, Biner/Dikotom Ya/Tidak, Rendah/Sedang/Tinggi

Menurut Agresti (2013), variabel kategori dibedakan menjadi tiga subtipe utama:

  • Nominal: kategori tanpa urutan alami (misalnya: warna mata, jenis pekerjaan)
  • Ordinal: kategori dengan urutan yang bermakna (misalnya: tingkat kepuasan: rendah, sedang, tinggi)
  • Biner/Dikotom: variabel khusus dengan hanya dua kategori (misalnya: ya/tidak, sakit/sehat)

Contoh Penerapan dalam Penelitian

Bidang Ilmu Contoh Kasus Metode Analisis
Epidemiologi Hubungan konsumsi fast food dengan kejadian obesitas Odds Ratio, Uji Chi-Square
Ilmu Sosial Hubungan tingkat pendidikan dengan preferensi politik Uji Chi-Square, Cramér’s V
Ekonomi Hubungan status pekerjaan dengan kepemilikan asuransi Regresi Logistik
Kedokteran Klinis Efektivitas vaksin terhadap kejadian infeksi Relative Risk, Uji Fisher

Referensi: Agresti, A. (2013). Categorical Data Analysis (3rd ed.). John Wiley & Sons.


Bagian 2: Tabel Kontingensi

Definisi Tabel Kontingensi

Tabel kontingensi (contingency table) adalah tabel yang menyajikan distribusi frekuensi dari dua atau lebih variabel kategori secara bersama-sama. Tabel ini memungkinkan kita mengamati bagaimana nilai satu variabel “tersebar” (contingent) di setiap kategori variabel lainnya (Agresti, 2013).

Tabel kontingensi paling sederhana adalah tabel \(2 \times 2\), yang melibatkan dua variabel dengan masing-masing dua kategori.

Struktur Tabel Kontingensi 2×2

Misalkan kita memiliki dua variabel:

  • Variabel Baris (X): Kebiasaan Makan (Fast Food / Tidak Fast Food)
  • Variabel Kolom (Y): Status Penyakit (Sakit / Tidak Sakit)
Sakit (Y = 1) Tidak Sakit (Y = 0) Total
Fast Food (X = 1) \(n_{11}\) \(n_{12}\) \(n_{1+}\)
Tidak Fast Food (X = 0) \(n_{21}\) \(n_{22}\) \(n_{2+}\)
Total \(n_{+1}\) \(n_{+2}\) \(n\)

Di mana:

  • \(n_{ij}\) = frekuensi sel baris ke-\(i\) dan kolom ke-\(j\)
  • \(n_{i+}\) = total baris ke-\(i\) (marginal baris)
  • \(n_{+j}\) = total kolom ke-\(j\) (marginal kolom)
  • \(n\) = total keseluruhan observasi

Konsep Joint Distribution

Joint distribution (distribusi bersama) adalah distribusi probabilitas dari dua variabel secara simultan. Probabilitas bersama dari sel \((i, j)\) diestimasi dengan:

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

Untuk tabel \(2 \times 2\) terdapat 4 sel dengan syarat: \(\sum_{i}\sum_{j} \hat{\pi}_{ij} = 1\).

Konsep Marginal Distribution

Marginal distribution adalah distribusi probabilitas dari salah satu variabel tanpa memperhatikan variabel lainnya, diperoleh dengan menjumlahkan probabilitas bersama sepanjang baris atau kolom.

Marginal untuk variabel baris (X):

\[\hat{\pi}_{i+} = \sum_{j} \hat{\pi}_{ij} = \frac{n_{i+}}{n}\]
(2)

Marginal untuk variabel kolom (Y):

\[\hat{\pi}_{+j} = \sum_{i} \hat{\pi}_{ij} = \frac{n_{+j}}{n}\]
(3)

Konsep Conditional Probability

Conditional probability (peluang bersyarat) adalah probabilitas suatu kejadian terjadi dengan syarat kejadian lain sudah diketahui terjadi:

\[P(Y = j \mid X = i) = \frac{\pi_{ij}}{\pi_{i+}} \approx \frac{n_{ij}}{n_{i+}}\]
(4)

Dalam konteks tabel kita:

\[P(\text{Obesitas} \mid \text{Fast Food}) = \frac{n_{11}}{n_{1+}}, \qquad P(\text{Obesitas} \mid \text{Tidak Fast Food}) = \frac{n_{21}}{n_{2+}}\]
(5)

Perbandingan probabilitas bersyarat inilah yang menjadi dasar ukuran asosiasi seperti Relative Risk dan Odds Ratio.


Bagian 3: Ukuran Asosiasi

Odds

Odds adalah rasio antara peluang suatu kejadian terjadi dibandingkan peluang kejadian tersebut tidak terjadi:

\[\text{Odds} = \frac{P(\text{kejadian terjadi})}{P(\text{kejadian tidak terjadi})} = \frac{\pi}{1 - \pi}\]
(6)

Untuk masing-masing kelompok pada tabel \(2 \times 2\):

\[\text{Odds}_{\text{Fast Food}} = \frac{n_{11}}{n_{12}}, \qquad \text{Odds}_{\text{Tidak Fast Food}} = \frac{n_{21}}{n_{22}}\]
(7)
Nilai Odds Interpretasi
Odds = 1 Peluang terjadi sama dengan peluang tidak terjadi
Odds > 1 Kejadian lebih mungkin terjadi daripada tidak terjadi
Odds < 1 Kejadian lebih mungkin tidak terjadi

Odds Ratio (OR)

Odds Ratio adalah perbandingan odds dari dua kelompok. OR mengukur seberapa besar odds suatu outcome pada kelompok terpapar dibandingkan kelompok tidak terpapar:

\[OR = \frac{\text{Odds}_{\text{Terpapar}}}{\text{Odds}_{\text{Tidak Terpapar}}} = \frac{n_{11}/n_{12}}{n_{21}/n_{22}} = \frac{n_{11} \cdot n_{22}}{n_{12} \cdot n_{21}} = \frac{ad}{bc}\]
(8)

Interval kepercayaan 95% untuk OR dihitung via transformasi logaritma natural:

\[\ln(\widehat{OR}) \pm 1{,}96 \times \sqrt{\frac{1}{n_{11}} + \frac{1}{n_{12}} + \frac{1}{n_{21}} + \frac{1}{n_{22}}}\]
(9)
Nilai OR Interpretasi
OR = 1 Tidak ada asosiasi antara paparan dan outcome
OR > 1 Paparan meningkatkan odds terjadinya outcome
OR < 1 Paparan menurunkan odds terjadinya outcome (protektif)

Relative Risk (RR)

Relative Risk (atau Risk Ratio) adalah rasio langsung antara probabilitas bersyarat pada kelompok terpapar dibandingkan tidak terpapar:

\[RR = \frac{P(\text{Outcome} \mid \text{Terpapar})}{P(\text{Outcome} \mid \text{Tidak Terpapar})} = \frac{n_{11}/(n_{11}+n_{12})}{n_{21}/(n_{21}+n_{22})} = \frac{n_{11} \cdot n_{2+}}{n_{21} \cdot n_{1+}}\]
(10)
Nilai RR Interpretasi
RR = 1 Risiko sama pada kedua kelompok (tidak ada asosiasi)
RR > 1 Kelompok terpapar memiliki risiko lebih tinggi
RR < 1 Kelompok terpapar memiliki risiko lebih rendah (protektif)

Catatan: RR hanya valid pada studi kohort atau eksperimental. Pada studi kasus-kontrol, gunakan OR karena proporsi kasus ditentukan oleh desain studi, bukan prevalensi populasi.

Uji Chi-Square

Uji Chi-Square (Pearson’s Chi-Square Test) digunakan untuk menguji apakah terdapat hubungan yang signifikan antara dua variabel kategori. Hipotesis yang diuji adalah:

  • \(H_0\): Tidak ada asosiasi antara variabel baris dan kolom (independen)
  • \(H_1\): Terdapat asosiasi antara variabel baris dan kolom
\[\chi^2 = \sum_{i}\sum_{j} \frac{(O_{ij} - E_{ij})^2}{E_{ij}}\]
(11)

Di mana frekuensi harapan dihitung dengan:

\[E_{ij} = \frac{n_{i+} \times n_{+j}}{n}\]
(12)

Statistik \(\chi^2\) mengikuti distribusi Chi-Square dengan derajat bebas \(df = (r-1)(c-1)\), di mana \(r\) = jumlah baris dan \(c\) = jumlah kolom. Untuk tabel \(2\times2\), \(df = 1\).

Kondisi Interpretasi
p-value < α Tolak H0: terdapat asosiasi yang signifikan
p-value ≥ α Gagal tolak H0: tidak cukup bukti adanya asosiasi
χ² besar Frekuensi observasi jauh dari yang diharapkan jika independen
χ² ≈ 0 Frekuensi observasi mendekati frekuensi harapan (mendukung independensi)

Uji Chi-Square hanya menunjukkan ada atau tidaknya asosiasi, bukan seberapa kuat asosiasi tersebut. Untuk mengukur kekuatan asosiasi, digunakan Cramér’s V.

Cramér’s V

Cramér’s V adalah ukuran kekuatan asosiasi berbasis Chi-Square yang nilainya berkisar antara 0 sampai 1, sehingga lebih mudah diinterpretasikan daripada nilai \(\chi^2\) mentah.

\[V = \sqrt{\frac{\chi^2}{n \cdot \min(r-1,\, c-1)}}\]
(13)
Nilai Cramér’s V Kekuatan Asosiasi
V = 0 Tidak ada asosiasi
0 < V ≤ 0,10 Asosiasi sangat lemah
0,10 < V ≤ 0,30 Asosiasi lemah–sedang
0,30 < V ≤ 0,50 Asosiasi sedang–kuat
V > 0,50 Asosiasi kuat

Uji Fisher (Fisher’s Exact Test)

Uji Fisher adalah alternatif uji Chi-Square yang digunakan ketika ukuran sampel kecil atau frekuensi harapan pada salah satu sel kurang dari 5. Uji ini menghitung probabilitas eksak dari tabel yang teramati dan semua tabel yang lebih ekstrem.

\[p = \frac{\binom{n_{1+}}{n_{11}}\binom{n_{2+}}{n_{21}}}{\binom{n}{n_{+1}}} = \frac{n_{1+}!\; n_{2+}!\; n_{+1}!\; n_{+2}!}{n!\; n_{11}!\; n_{12}!\; n_{21}!\; n_{22}!}\]
(14)
Kondisi Interpretasi
p-value < α Tolak H0: terdapat asosiasi yang signifikan
p-value ≥ α Gagal tolak H0: tidak cukup bukti adanya asosiasi
Digunakan saat Sampel kecil (n < 20) atau ada sel dengan frekuensi harapan < 5

Bagian 4: Contoh Perhitungan Manual

Kasus: Hubungan Konsumsi Fast Food dan Obesitas

Sebuah penelitian kohort dilakukan untuk menyelidiki apakah kebiasaan konsumsi fast food secara rutin (≥4 kali/minggu) berhubungan dengan kejadian obesitas pada usia dewasa muda. Peneliti mengikuti 200 responden selama 2 tahun dan memperoleh data berikut:

Kebiasaan Makan Obesitas Tidak Obesitas Total
Konsumsi Fast Food 60 40 100
Tidak Konsumsi Fast Food 20 80 100
Total 80 120 200

Notasi: \(a = 60\), \(b = 40\), \(c = 20\), \(d = 80\), \(n = 200\)

Langkah 1: Peluang Bersyarat

Peluang obesitas pada kelompok konsumsi fast food:

\[P(\text{Obesitas} \mid \text{Fast Food}) = \frac{a}{a+b} = \frac{60}{100} = 0{,}60\]

Peluang obesitas pada kelompok tidak konsumsi fast food:

\[P(\text{Obesitas} \mid \text{Tidak Fast Food}) = \frac{c}{c+d} = \frac{20}{100} = 0{,}20\]

Artinya, 60% responden yang rutin mengonsumsi fast food mengalami obesitas, sementara hanya 20% yang tidak mengonsumsi fast food mengalami obesitas.

Langkah 2: Menghitung Odds

Odds obesitas pada kelompok fast food:

\[\text{Odds}_{\text{Fast Food}} = \frac{a}{b} = \frac{60}{40} = 1{,}50\]

Odds obesitas pada kelompok tidak fast food:

\[\text{Odds}_{\text{Tidak Fast Food}} = \frac{c}{d} = \frac{20}{80} = 0{,}25\]

Odds 1,50 berarti pada kelompok konsumsi fast food, peluang mengalami obesitas 1,5× lebih besar dari peluang tidak mengalaminya. Sebaliknya, odds 0,25 menunjukkan kelompok yang tidak konsumsi fast food jauh lebih mungkin tidak mengalami obesitas.

Langkah 3: Menghitung Odds Ratio

\[OR = \frac{\text{Odds}_{\text{Fast Food}}}{\text{Odds}_{\text{Tidak Fast Food}}} = \frac{a/b}{c/d} = \frac{ad}{bc} = \frac{60 \times 80}{40 \times 20} = \frac{4800}{800} = \mathbf{6{,}00}\]

Interval Kepercayaan 95% untuk OR:

\[SE_{\ln(OR)} = \sqrt{\frac{1}{60} + \frac{1}{40} + \frac{1}{20} + \frac{1}{80}} = \sqrt{0{,}0167 + 0{,}0250 + 0{,}0500 + 0{,}0125} = \sqrt{0{,}1042} \approx 0{,}3228\]

\[\ln(OR) = \ln(6) \approx 1{,}7918\]

\[\text{95\% CI untuk } \ln(OR): \quad 1{,}7918 \pm 1{,}96 \times 0{,}3228 = (1{,}1591 \;;\; 2{,}4245)\]

\[\text{95\% CI untuk OR}: \quad \left(e^{1{,}1591} \;;\; e^{2{,}4245}\right) \approx \mathbf{(3{,}19 \;;\; 11{,}35)}\]

Langkah 4: Menghitung Relative Risk

\[RR = \frac{P(\text{Obesitas} \mid \text{Fast Food})}{P(\text{Obesitas} \mid \text{Tidak Fast Food})} = \frac{60/100}{20/100} = \frac{0{,}60}{0{,}20} = \mathbf{3{,}00}\]

Langkah 5: Uji Chi-Square

Hitung terlebih dahulu frekuensi harapan (\(E_{ij}\)) untuk setiap sel:

\[E_{11} = \frac{n_{1+} \times n_{+1}}{n} = \frac{100 \times 80}{200} = 40, \quad E_{12} = \frac{100 \times 120}{200} = 60\]

\[E_{21} = \frac{100 \times 80}{200} = 40, \quad E_{22} = \frac{100 \times 120}{200} = 60\]

Karena semua \(E_{ij} \geq 5\), syarat uji Chi-Square terpenuhi. Hitung statistik uji menggunakan Pers. (11):

\[\chi^2 = \frac{(60-40)^2}{40} + \frac{(40-60)^2}{60} + \frac{(20-40)^2}{40} + \frac{(80-60)^2}{60}\]

\[\chi^2 = \frac{400}{40} + \frac{400}{60} + \frac{400}{40} + \frac{400}{60} = 10 + 6{,}667 + 10 + 6{,}667 = \mathbf{33{,}33}\]

Keputusan: Karena \(\chi^2 = 33{,}33 > 3{,}841\) (nilai kritis \(\alpha=0{,}05\), \(df=1\)), maka tolak \(H_0\). Terdapat asosiasi yang signifikan antara konsumsi fast food dan obesitas.

Langkah 6: Cramér’s V

Dengan \(n = 200\) dan \(\min(r-1, c-1) = 1\):

\[V = \sqrt{\frac{\chi^2}{n \cdot \min(r-1,\, c-1)}} = \sqrt{\frac{33{,}33}{200 \times 1}} = \sqrt{0{,}1667} \approx \mathbf{0{,}408}\]

Langkah 7: Uji Fisher

Uji Fisher menghitung probabilitas eksak dengan distribusi hipergeometrik. Untuk data ini dengan total marginal tetap (\(n_{1+} = n_{2+} = 100\), \(n_{+1} = 80\), \(n_{+2} = 120\)):

\[p = \frac{100!\; 100!\; 80!\; 120!}{200!\; 60!\; 40!\; 20!\; 80!}\]

Pada sampel besar (\(n = 200\)) dengan semua frekuensi harapan \(\geq 5\), uji Chi-Square dan Fisher biasanya memberikan kesimpulan yang sama. Uji Fisher lebih relevan digunakan ketika \(n\) kecil atau ada sel dengan \(E_{ij} < 5\).

Ringkasan Hasil Perhitungan

Ukuran Nilai
P(Obesitas &#124; Fast Food) 0,60
P(Obesitas &#124; Tidak Fast Food) 0,20
Odds Fast Food 1,50
Odds Tidak Fast Food 0,25
Odds Ratio (OR) 6,00
95% CI untuk OR (3,19 ; 11,35)
Relative Risk (RR) 3,00
Chi-Square (χ²) 33,33
Cramér’s V 0,408
Fisher’s p-value < 0,001

Bagian 5: Analisis Menggunakan R

Membuat Tabel Kontingensi

# Membuat matriks data
data <- matrix(c(60, 40, 20, 80),
               nrow  = 2,
               byrow = TRUE)

rownames(data) <- c("Fast Food", "Tidak Fast Food")
colnames(data) <- c("Obesitas", "Tidak Obesitas")

data
##                 Obesitas Tidak Obesitas
## Fast Food             60             40
## Tidak Fast Food       20             80
Kebiasaan Makan Obesitas Tidak Obesitas
Fast Food 60 40
Tidak Fast Food 20 80
# Proporsi baris (conditional distribution)
cat("=== Proporsi Baris ===\n")
## === Proporsi Baris ===
round(prop.table(data, margin = 1), 4)
##                 Obesitas Tidak Obesitas
## Fast Food            0.6            0.4
## Tidak Fast Food      0.2            0.8
# Proporsi total (joint distribution)
cat("\n=== Proporsi Total ===\n")
## 
## === Proporsi Total ===
round(prop.table(data), 4)
##                 Obesitas Tidak Obesitas
## Fast Food            0.3            0.2
## Tidak Fast Food      0.1            0.4

Menghitung Odds Ratio

a <- data[1, 1]; b <- data[1, 2]
c <- data[2, 1]; d <- data[2, 2]

odds_fastfood      <- a / b
odds_tidak_fastfood <- c / d
OR                 <- (a * d) / (b * c)
RR                 <- (a / (a + b)) / (c / (c + d))
SE_ln_OR           <- sqrt(1/a + 1/b + 1/c + 1/d)
CI_lower           <- exp(log(OR) - 1.96 * SE_ln_OR)
CI_upper           <- exp(log(OR) + 1.96 * SE_ln_OR)

cat(sprintf("Odds Fast Food          : %.4f\n", odds_fastfood))
## Odds Fast Food          : 1.5000
cat(sprintf("Odds Tidak Fast Food    : %.4f\n", odds_tidak_fastfood))
## Odds Tidak Fast Food    : 0.2500
cat(sprintf("Odds Ratio (OR)         : %.4f\n", OR))
## Odds Ratio (OR)         : 6.0000
cat(sprintf("95%% CI untuk OR        : (%.4f ; %.4f)\n", CI_lower, CI_upper))
## 95% CI untuk OR        : (3.1873 ; 11.2948)
cat(sprintf("Relative Risk (RR)      : %.4f\n", RR))
## Relative Risk (RR)      : 3.0000

Uji Chi-Square

hasil_chisq <- chisq.test(data, correct = FALSE)
hasil_chisq
## 
##  Pearson's Chi-squared test
## 
## data:  data
## X-squared = 33.333, df = 1, p-value = 7.764e-09
cat("\n=== Frekuensi yang Diharapkan ===\n")
## 
## === Frekuensi yang Diharapkan ===
round(hasil_chisq$expected, 2)
##                 Obesitas Tidak Obesitas
## Fast Food             40             60
## Tidak Fast Food       40             60

Cramér’s V

# Cramér's V
chi2 <- hasil_chisq$statistic
n    <- sum(data)
k    <- min(nrow(data) - 1, ncol(data) - 1)
V    <- sqrt(chi2 / (n * k))

cat(sprintf("Chi-Square (χ²)  : %.4f\n", chi2))
## Chi-Square (χ²)  : 33.3333
cat(sprintf("n                : %d\n",   n))
## n                : 200
cat(sprintf("Cramér's V       : %.4f\n", V))
## Cramér's V       : 0.4082
kekuatan <- ifelse(V <= 0.10, "Sangat lemah",
           ifelse(V <= 0.30, "Lemah–sedang",
           ifelse(V <= 0.50, "Sedang–kuat", "Kuat")))
cat(sprintf("Kekuatan asosiasi: %s\n", kekuatan))
## Kekuatan asosiasi: Sedang–kuat

Uji Fisher (Fisher’s Exact Test)

# Uji Fisher
hasil_fisher <- fisher.test(data)
hasil_fisher
## 
##  Fisher's Exact Test for Count Data
## 
## data:  data
## p-value = 1.064e-08
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
##   3.055033 11.932317
## sample estimates:
## odds ratio 
##   5.940316
cat(sprintf("\nOdds Ratio (Fisher) : %.4f\n", hasil_fisher$estimate))
## 
## Odds Ratio (Fisher) : 5.9403
cat(sprintf("95%% CI (Fisher)    : (%.4f ; %.4f)\n",
            hasil_fisher$conf.int[1], hasil_fisher$conf.int[2]))
## 95% CI (Fisher)    : (3.0550 ; 11.9323)
cat(sprintf("p-value (Fisher)    : %.6f\n", hasil_fisher$p.value))
## p-value (Fisher)    : 0.000000

Visualisasi

Grafik 1: Distribusi Proporsi Obesitas per Kelompok

p1 <- ggplot(prop_df, aes(x = Kelompok, y = Proporsi, fill = Status)) +
  geom_col(position = "dodge", width = 0.6, color = "white", linewidth = 0.4) +
  geom_text(aes(label = Label),
            position = position_dodge(width = 0.6),
            vjust = -0.5, fontface = "bold", size = 3.8, color = "#2c3e50") +
  scale_fill_manual(values = c("Obesitas" = "#e74c3c", "Tidak Obesitas" = "#3498db")) +
  scale_y_continuous(labels = percent_format(), limits = c(0, 0.85),
                     breaks = seq(0, 0.8, 0.2)) +
  labs(
    title    = "Proporsi Status Obesitas Berdasarkan Kebiasaan Konsumsi Fast Food",
    subtitle = "Perbandingan proporsi obesitas dan tidak obesitas pada setiap kelompok paparan",
    x        = "Kebiasaan Konsumsi Fast Food",
    y        = "Proporsi (%)",
    caption  = "Sumber: Data simulasi studi cross-sectional, n = 200 responden"
  ) +
  tema_laporan

print(p1)

Interpretasi Grafik 1: Proporsi Obesitas per Kelompok

Grafik batang berdampingan ini membandingkan proporsi status obesitas antara kelompok yang rutin mengonsumsi fast food dan kelompok yang tidak. Terlihat perbedaan yang sangat mencolok:

  • Kelompok Fast Food: sebanyak 60% responden mengalami obesitas, dan hanya 40% yang tidak obesitas.
  • Kelompok Tidak Fast Food: hanya 20% responden yang mengalami obesitas, sementara 80% tidak obesitas.

Perbedaan proporsi sebesar 40 poin persentase (60% vs 20%) merupakan indikasi visual yang kuat bahwa terdapat asosiasi antara konsumsi fast food dan kejadian obesitas, konsisten dengan nilai RR = 3,00.

Grafik 2: Perbandingan Odds antar Kelompok

p2 <- ggplot(odds_df, aes(x = Kelompok, y = Odds, color = Kelompok)) +
  geom_segment(aes(xend = Kelompok, y = 0, yend = Odds),
               linewidth = 1.8, alpha = 0.7) +
  geom_point(size = 7, alpha = 0.9) +
  geom_text(aes(label = sprintf("Odds = %.2f", Odds)),
            vjust = -1.1, fontface = "bold", size = 4, color = "#2c3e50") +
  geom_hline(yintercept = 1, linetype = "dashed", color = "#7f8c8d", linewidth = 0.8) +
  annotate("text", x = 2.45, y = 1.05, label = "Odds = 1
(titik netral)",
           size = 3.2, color = "#7f8c8d", fontface = "italic") +
  scale_color_manual(values = c("Fast Food" = "#e74c3c", "Tidak Fast Food" = "#3498db")) +
  scale_y_continuous(limits = c(0, 2), breaks = seq(0, 2, 0.25)) +
  labs(
    title    = "Perbandingan Odds Obesitas antar Kelompok",
    subtitle = "Odds Fast Food (1,50) vs Odds Tidak Fast Food (0,25)",
    x        = "Kelompok Paparan",
    y        = "Odds Obesitas",
    caption  = "Garis putus-putus menandai titik netral Odds = 1"
  ) +
  tema_laporan +
  theme(legend.position = "none")

print(p2)

Interpretasi Grafik 2: Perbandingan Odds

Grafik lollipop ini membandingkan nilai odds obesitas pada dua kelompok, dengan garis putus-putus sebagai titik netral odds = 1.

  • Odds Fast Food = 1,50: berada di atas garis netral, artinya dalam kelompok ini responden lebih mungkin mengalami obesitas daripada tidak.
  • Odds Tidak Fast Food = 0,25: berada jauh di bawah garis netral, menandakan responden jauh lebih mungkin tidak mengalami obesitas.

Rasio antara kedua nilai ini menghasilkan Odds Ratio = 6,00, yang berarti odds obesitas pada kelompok fast food adalah 6 kali lebih besar.


Bagian 6: Interpretasi Hasil

Interpretasi Statistik

Ukuran Nilai Interpretasi
Chi-Square (χ²) 33,33 Nilai uji besar → distribusi antar kelompok berbeda nyata
p-value (Chi-Square) < 0,001 Sangat signifikan, tolak H0 pada alpha = 0,05 maupun alpha = 0,01
Cramér’s V 0,408 Asosiasi sedang–kuat (0,30 < V ≤ 0,50)
p-value (Fisher) < 0,001 Konfirmasi independen: asosiasi signifikan secara eksak
Odds Ratio (OR) 6,00 Odds obesitas kelompok fast food 6× lebih besar dari kelompok tidak fast food
95% CI untuk OR (3,19 ; 11,35) Tidak mencakup 1 → asosiasi signifikan secara statistik
Relative Risk (RR) 3,00 Risiko obesitas kelompok fast food 3× lebih tinggi dari kelompok tidak fast food

Interpretasi Substantif

Berdasarkan hasil analisis, dapat disimpulkan bahwa:

  • Signifikansi: Uji Chi-Square (\(\chi^2 = 33{,}33\), \(p < 0{,}001\)) dan Uji Fisher (\(p < 0{,}001\)) secara konsisten menunjukkan asosiasi yang signifikan antara konsumsi fast food dan obesitas.
  • Kekuatan asosiasi: Cramér’s V = 0,408 menunjukkan kekuatan asosiasi yang tergolong sedang hingga kuat, bukan sekadar signifikan secara statistik.
  • Besarnya risiko: Kelompok yang rutin mengonsumsi fast food memiliki risiko 3 kali lebih tinggi untuk mengalami obesitas (RR = 3,00) dengan odds 6 kali lebih besar (OR = 6,00).
  • Implikasi kebijakan: Temuan ini mendukung pentingnya edukasi gizi, pembatasan iklan fast food pada anak dan remaja, serta pengembangan regulasi label kalori pada produk makanan cepat saji.

Catatan Kausal: Asosiasi statistik tidak serta-merta membuktikan hubungan sebab-akibat. Faktor perancu seperti tingkat aktivitas fisik, genetik, dan pola makan keseluruhan perlu dikendalikan dalam studi yang lebih komprehensif.

Kesimpulan Utama: Terdapat asosiasi yang signifikan dan kuat antara kebiasaan konsumsi fast food dan kejadian obesitas. Hal ini dikonfirmasi oleh Chi-Square, Fisher’s Exact Test, Cramér’s V, OR, dan RR secara konsisten.


Referensi

  • Agresti, A. (2013). Categorical Data Analysis (3rd ed.). John Wiley & Sons.
  • Hosmer, D. W., Lemeshow, S., & Sturdivant, R. X. (2013). Applied Logistic Regression (3rd ed.). John Wiley & Sons.
  • Rothman, K. J., Greenland, S., & Lash, T. L. (2008). Modern Epidemiology (3rd ed.). Lippincott Williams & Wilkins.
  • R Core Team (2024). R: A Language and Environment for Statistical Computing. R Foundation for Statistical Computing. https://www.R-project.org/

Tugas 2: Inferensi Tabel Kontingensi Dua Arah


Pendahuluan

Inferensi tabel kontingensi dua arah adalah proses penarikan kesimpulan statistik tentang hubungan antara dua variabel kategori berdasarkan data yang disusun dalam bentuk tabel \(I \times J\). Inferensi ini mencakup dua aktivitas utama: (1) estimasi besarnya asosiasi menggunakan ukuran seperti Beda Proporsi (BP), Risiko Relatif (RR), dan Odds Ratio (OR), serta (2) pengujian hipotesis independensi menggunakan uji Chi-Square Pearson, Likelihood Ratio (\(G^2\)), atau Uji Eksak Fisher.

Tujuan tugas ini adalah menerapkan kerangka inferensi tabel kontingensi pada dua kasus nyata dari Agresti (2019):

  • Kasus 1 — Tabel \(2\times2\): Hubungan antara kebiasaan merokok dan kejadian kanker paru berdasarkan studi kasus-kontrol.
  • Kasus 2 — Tabel \(2\times3\): Hubungan antara gender dan identifikasi partai politik (Democrat, Republican, Independent) pada survei pemilu AS.

Referensi utama: Agresti, A. (2019). An Introduction to Categorical Data Analysis (3rd ed.). Wiley. Slide Pertemuan 3 — Prof. I Gede Nyoman Mindra Jaya, Ph.D (UNPAD).


Data dan Penyusunan Tabel Kontingensi

Kasus 1: Merokok dan Kanker Paru

Data berikut bersumber dari studi kasus-kontrol yang menyelidiki hubungan antara kebiasaan merokok dan kejadian kanker paru (Agresti, 2019, Tabel 2.1). Variabel baris adalah status merokok (Smoker vs Non-Smoker) dan variabel kolom adalah status kasus (Cancer(+) vs Control(−)).

Status Merokok Cancer (+) Control (−) Total
Smoker 688 650 1338
Non-Smoker 21 59 80
Total 709 709 1418
# Matriks tabel kontingensi (baris = status merokok, kolom = status kasus)
k1 <- matrix(c(688, 650, 21, 59),
             nrow  = 2, byrow = TRUE,
             dimnames = list(
               Merokok = c("Smoker", "Non-Smoker"),
               Kasus   = c("Cancer(+)", "Control(-)")
             ))
k1
##             Kasus
## Merokok      Cancer(+) Control(-)
##   Smoker           688        650
##   Non-Smoker        21         59

Catatan desain: Karena ini adalah studi kasus-kontrol, jumlah kasus dan kontrol ditentukan oleh peneliti (\(n_{+1} = n_{+2} = 709\)). Dengan demikian, Odds Ratio (OR) merupakan ukuran asosiasi yang tepat, sedangkan Risk Ratio (RR) dan Beda Proporsi (BP) ditafsirkan dengan hati-hati sesuai konteks studi.

Kasus 2: Gender dan Identifikasi Partai Politik

Data ini berasal dari survei pemilu AS yang meneliti apakah gender (Female vs Male) berhubungan dengan identifikasi partai politik (Democrat, Republican, Independent). Ini adalah tabel \(2 \times 3\) yang lebih umum daripada tabel \(2 \times 2\) (Agresti, 2019, Tabel 2.4).

Gender Democrat Republican Independent Total
Female 495 272 590 1357
Male 330 265 498 1093
Total 825 537 1088 2450
k2 <- matrix(c(495, 272, 590,
               330, 265, 498),
             nrow = 2, byrow = TRUE,
             dimnames = list(
               Gender = c("Female","Male"),
               Partai = c("Democrat","Republican","Independent")
             ))
k2
##         Partai
## Gender   Democrat Republican Independent
##   Female      495        272         590
##   Male        330        265         498

Catatan desain: Survei ini menggunakan desain cross-sectional dengan sampel acak. Tabel \(2\times3\) memerlukan analisis yang lebih kaya: selain uji independensi global, diperlukan partisi \(G^2\) untuk mengidentifikasi pasangan kategori mana yang paling berkontribusi terhadap asosiasi.


Metode Analisis

Ukuran Asosiasi pada Tabel 2×2

Estimasi bertujuan mengukur seberapa besar asosiasi antara dua variabel kategori. Tiga ukuran asosiasi utama pada tabel \(2 \times 2\) adalah:

Ukuran Rumus Interpretasi
Beda Proporsi (BP) \(BP = \hat{p}_{j&amp;#124;h} - \hat{p}_{j&amp;#124;i}\) Selisih absolut risiko antar kelompok
Risiko Relatif (RR) \(RR = \hat{p}_{j&amp;#124;h} \,/\, \hat{p}_{j&amp;#124;i}\) Kelipatan risiko antar kelompok; valid untuk studi kohort
Odds Ratio (OR) \(OR = \hat{\theta} = n_{11}n_{22}/(n_{12}n_{21})\) Kelipatan odds antar kelompok; valid untuk studi kasus-kontrol

Interval kepercayaan \(100(1-\alpha)\%\) dihitung via transformasi logaritma natural:

\[se(BP) = \sqrt{\frac{\hat{p}_1(1-\hat{p}_1)}{n_{1+}} + \frac{\hat{p}_2(1-\hat{p}_2)}{n_{2+}}}\]
(M.1)
\[se(\ln RR) = \sqrt{\frac{1-\hat{p}_1}{\hat{p}_1\, n_{1+}} + \frac{1-\hat{p}_2}{\hat{p}_2\, n_{2+}}}, \qquad se(\ln OR) = \sqrt{\frac{1}{n_{11}}+\frac{1}{n_{12}}+\frac{1}{n_{21}}+\frac{1}{n_{22}}}\]
(M.2)

Pengujian Independensi

Dua variabel kategori \(X\) dan \(Y\) independen jika \(\pi_{ij} = \pi_{i+}\,\pi_{+j}\) untuk semua \(i, j\). Hipotesis formal:

\[H_0: \pi_{ij} = \pi_{i+}\,\pi_{+j} \quad \text{(independen)} \qquad H_1: \pi_{ij} \neq \pi_{i+}\,\pi_{+j} \quad \text{(tidak independen)}\]

Frekuensi harapan di bawah \(H_0\): \(\hat{\mu}_{ij} = n\, p_{i+}\, p_{+j}\). Empat statistik uji yang digunakan:

Metode Statistik Distribusi Catatan
Uji Dua Proporsi \(z^2 \sim \chi^2_{(1)}\) \(\chi^2_{(1)}\) Khusus tabel \(2\times 2\)
Pearson Chi-Square \(X^2 = \sum (n_{ij}-\hat{\mu}_{ij})^2/\hat{\mu}_{ij}\) \(\chi^2_{(I-1)(J-1)}\) Butuh \(\hat{\mu}_{ij}\geq 5\)
Likelihood Ratio (\(G^2\)) \(G^2 = 2\sum n_{ij}\ln(n_{ij}/\hat{\mu}_{ij})\) \(\chi^2_{(I-1)(J-1)}\) Additif untuk partisi
Fisher Exact Test Distribusi Hipergeometrik Eksak Untuk sampel kecil

Residual dan Identifikasi Sel Penyimpang

Pearson Residual \(e_{ij} = (n_{ij}-\hat{\mu}_{ij})/\sqrt{\hat{\mu}_{ij}}\) mengukur deviasi per sel. Standardized Residual \(d_{ij}\) mengoreksi dengan variabilitas marginal:

\[d_{ij} = \frac{n_{ij} - \hat{\mu}_{ij}}{\sqrt{\hat{\mu}_{ij}(1-p_{i+})(1-p_{+j})}}\]
(M.3)

Nilai \(|d_{ij}| > 1{,}96\) mengindikasikan sel tersebut berkontribusi signifikan terhadap ketidakindependenan pada \(\alpha = 0{,}05\).

Partisi Chi-Square (Lancaster & Irwin)

Untuk tabel \(I \times J\), statistik \(G^2\) dapat dipecah menjadi \((I-1)(J-1)\) komponen orthogonal yang saling independen. Untuk tabel \(2\times3\) (\(df = 2\)), partisi dilakukan menjadi dua komponen \(2\times2\) (\(df = 1\) masing-masing):

\[G^2_{\text{total}} = G^2_{\text{Partisi 1}} + G^2_{\text{Partisi 2}}, \qquad df_{\text{total}} = 1 + 1 = 2\]
(M.4)

Catatan penting: OR dan RR hanya terdefinisi langsung untuk tabel \(2 \times 2\). Untuk tabel \(2 \times 3\) (Kasus 2), ukuran asosiasi dievaluasi melalui standardized residual dan partisi \(G^2\).


Hasil dan Interpretasi

Kasus 1: Merokok dan Kanker Paru

Estimasi Proporsi dan Interval Kepercayaan

Proporsi kejadian kanker paru dihitung sebagai probabilitas bersyarat \(P(\text{Cancer} \mid \text{Status Merokok})\):

\[\hat{p}_{\text{Smoker}} = \frac{n_{11}}{n_{1+}} = \frac{688}{1338}, \qquad \hat{p}_{\text{Non-Smoker}} = \frac{n_{21}}{n_{2+}} = \frac{21}{80}\]
(1)
p_smoker    <- k1[1,1] / sum(k1[1,])
p_nonsmoker <- k1[2,1] / sum(k1[2,])

cat(sprintf("Proporsi Cancer | Smoker     : %.4f (%.2f%%)\n", p_smoker,    p_smoker*100))
## Proporsi Cancer | Smoker     : 0.5142 (51.42%)
cat(sprintf("Proporsi Cancer | Non-Smoker : %.4f (%.2f%%)\n", p_nonsmoker, p_nonsmoker*100))
## Proporsi Cancer | Non-Smoker : 0.2625 (26.25%)

Sekitar 51,42% perokok tergolong kasus kanker paru, dibandingkan hanya 26,25% pada non-perokok. Perbedaan ini sudah terlihat secara deskriptif sebelum uji formal dilakukan.

ci_smoker    <- prop.test(k1[1,1], sum(k1[1,]), conf.level = 0.95)$conf.int
ci_nonsmoker <- prop.test(k1[2,1], sum(k1[2,]), conf.level = 0.95)$conf.int

cat(sprintf("95%% CI Smoker     : (%.4f ; %.4f)\n", ci_smoker[1],    ci_smoker[2]))
## 95% CI Smoker     : (0.4870 ; 0.5413)
cat(sprintf("95%% CI Non-Smoker : (%.4f ; %.4f)\n", ci_nonsmoker[1], ci_nonsmoker[2]))
## 95% CI Non-Smoker : (0.1733 ; 0.3748)

Ukuran Asosiasi: BP, RR, dan OR

Rumus titik estimasi (Agresti, 2019):

\[BP = \hat{p}_{j|h} - \hat{p}_{j|i}, \qquad RR = \frac{\hat{p}_{j|h}}{\hat{p}_{j|i}}, \qquad OR = \hat{\theta} = \frac{n_{11}\, n_{22}}{n_{12}\, n_{21}}\]
(2)
a1 <- k1[1,1]; b1 <- k1[1,2]
c1 <- k1[2,1]; d1 <- k1[2,2]
n1 <- sum(k1[1,]);   n2 <- sum(k1[2,])

RD <- p_smoker - p_nonsmoker
RR <- p_smoker / p_nonsmoker
OR <- (a1 * d1) / (b1 * c1)

se_bp    <- sqrt(p_smoker*(1-p_smoker)/n1 + p_nonsmoker*(1-p_nonsmoker)/n2)
ci_rd    <- c(RD - 1.96*se_bp, RD + 1.96*se_bp)

se_ln_rr <- sqrt((1-p_smoker)/(p_smoker*n1) + (1-p_nonsmoker)/(p_nonsmoker*n2))
ci_rr    <- exp(log(RR) + c(-1,1) * 1.96 * se_ln_rr)

se_ln_or <- sqrt(1/a1 + 1/b1 + 1/c1 + 1/d1)
ci_or    <- exp(log(OR) + c(-1,1) * 1.96 * se_ln_or)

cat(sprintf("BP  = %.4f  | 95%% CI: (%.4f ; %.4f)\n", RD, ci_rd[1], ci_rd[2]))
## BP  = 0.2517  | 95% CI: (0.1516 ; 0.3518)
cat(sprintf("RR  = %.4f  | 95%% CI: (%.4f ; %.4f)\n", RR, ci_rr[1], ci_rr[2]))
## RR  = 1.9589  | 95% CI: (1.3517 ; 2.8387)
cat(sprintf("OR  = %.4f  | 95%% CI: (%.4f ; %.4f)\n", OR, ci_or[1], ci_or[2]))
## OR  = 2.9738  | 95% CI: (1.7867 ; 4.9495)
Ukuran Estimasi Titik 95% CI Interpretasi
RD (Risk Difference) 0.2517 (0.1516 ; 0.3518) Perokok memiliki proporsi kanker 25,17 poin % lebih tinggi
RR (Risk Ratio) 1.9589 (1.3517 ; 2.8387) Risiko kanker perokok hampir 2× non-perokok
OR (Odds Ratio) 2.9738 (1.7867 ; 4.9495) Odds kanker perokok ~6× lebih besar; CI tidak mencakup 1

Pengujian Independensi

Hipotesis: \(H_0:\) merokok dan kanker paru independen; \(H_1:\) terdapat asosiasi.

hasil_prop <- prop.test(c(a1, c1), c(sum(k1[1,]), sum(k1[2,])),
                        correct = FALSE, conf.level = 0.95)
hasil_prop
## 
##  2-sample test for equality of proportions without continuity correction
## 
## data:  c(a1, c1) out of c(sum(k1[1, ]), sum(k1[2, ]))
## 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
hasil_chisq1 <- chisq.test(k1, correct = FALSE)
hasil_chisq1
## 
##  Pearson's Chi-squared test
## 
## data:  k1
## X-squared = 19.129, df = 1, p-value = 1.222e-05
cat("\n=== Frekuensi Harapan ===\n")
## 
## === Frekuensi Harapan ===
round(hasil_chisq1$expected, 2)
##             Kasus
## Merokok      Cancer(+) Control(-)
##   Smoker           669        669
##   Non-Smoker        40         40
O1        <- k1
E1        <- hasil_chisq1$expected
G2_1      <- 2 * sum(O1 * log(O1 / E1))
df_g2_1   <- (nrow(k1)-1) * (ncol(k1)-1)
pval_g2_1 <- pchisq(G2_1, df = df_g2_1, lower.tail = FALSE)

cat(sprintf("G²        = %.4f\n", G2_1))
## G²        = 19.8780
cat(sprintf("df        = %d\n",   df_g2_1))
## df        = 1
cat(sprintf("p-value   = %.6f\n", pval_g2_1))
## p-value   = 0.000008
hasil_fisher1 <- fisher.test(k1, alternative = "greater")
hasil_fisher1
## 
##  Fisher's Exact Test for Count Data
## 
## data:  k1
## p-value = 7.382e-06
## alternative hypothesis: true odds ratio is greater than 1
## 95 percent confidence interval:
##  1.895488      Inf
## sample estimates:
## odds ratio 
##   2.971634
cat(sprintf("\nOR (Fisher, MLE) : %.4f\n", hasil_fisher1$estimate))
## 
## OR (Fisher, MLE) : 2.9716
cat(sprintf("95%% CI (Fisher)  : (%.4f ; %.4f)\n",
            hasil_fisher1$conf.int[1], hasil_fisher1$conf.int[2]))
## 95% CI (Fisher)  : (1.8955 ; Inf)
cat(sprintf("p-value (Fisher) : %.6f\n", hasil_fisher1$p.value))
## p-value (Fisher) : 0.000007
Metode Statistik Uji p-value Keputusan Interpretasi
Uji Dua Proporsi z² = 19.1292 0.000012 Tolak H₀ (α=0,05) Proporsi kanker berbeda signifikan antar kelompok
Chi-Square (Pearson) χ² = 19.1292 0.000012 Tolak H₀ (α=0,05) Distribusi observasi jauh dari yang diharapkan jika independen
Likelihood Ratio (G²) G² = 19.8780 0.000008 Tolak H₀ (α=0,05) Log-rasio frekuensi menunjukkan asosiasi nyata
Fisher Exact Test 0.000007 Tolak H₀ (α=0,05) Probabilitas eksak mendukung adanya asosiasi

Keempat metode menghasilkan kesimpulan yang konsisten: semua menolak \(H_0\) dengan \(p < 0{,}001\). Uji Chi-Square dan Uji Dua Proporsi memberikan hasil yang ekuivalen pada tabel \(2\times 2\). Uji \(G^2\) dan Fisher memberikan konfirmasi tambahan.

Visualisasi Kasus 1

k1_df <- data.frame(
  Merokok = factor(rep(c("Smoker","Non-Smoker"), each=2),
                   levels=c("Smoker","Non-Smoker")),
  Status  = factor(rep(c("Cancer(+)","Control(-)"), 2),
                   levels=c("Cancer(+)","Control(-)")),
  n       = c(688, 650, 21, 59)
) %>%
  group_by(Merokok) %>%
  mutate(prop  = n / sum(n),
         label = paste0(round(prop*100,1),"%"))

ggplot(k1_df, aes(x=Merokok, y=prop, fill=Status)) +
  geom_col(position="dodge", width=0.6, color="white") +
  geom_text(aes(label=label), position=position_dodge(width=0.6),
            vjust=-0.5, fontface="bold", size=3.8) +
  scale_fill_manual(values=c("Cancer(+)"="#e74c3c","Control(-)"="#3498db")) +
  scale_y_continuous(labels=scales::percent_format(), limits=c(0,0.85)) +
  labs(title   ="Proporsi Cancer vs Control Berdasarkan Status Merokok",
       subtitle="Studi kasus-kontrol: n = 1418",
       x="Status Merokok", y="Proporsi") +
  tema6

Interpretasi Grafik Proporsi: Pada kelompok Smoker, 51,4% tergolong kasus cancer — lebih dari dua kali lipat proporsi pada Non-Smoker (26,3%). Perbedaan visual ini konsisten dengan RR ≈ 1,96.

ggplot(k1_df, aes(x=Merokok, y=prop, fill=Status)) +
  geom_col(position="fill", width=0.55, color="white", linewidth=0.4) +
  geom_text(aes(label=label), position=position_fill(vjust=0.5),
            fontface="bold", size=4, color="white") +
  scale_fill_manual(values=c("Cancer(+)"="#c0392b","Control(-)"="#2980b9")) +
  scale_y_continuous(labels=scales::percent_format()) +
  labs(title   ="Distribusi Proporsional Cancer vs Control per Kelompok",
       subtitle="Stacked 100% — memudahkan perbandingan komposisi antar kelompok",
       x="Status Merokok", y="Proporsi (%)") +
  tema6

Interpretasi Stacked Bar: Komposisi status kanker antara Smoker dan Non-Smoker berbeda nyata — blok merah (Cancer) jauh lebih besar pada Smoker, konsisten dengan nilai OR ≈ 5,97.

# Mosaic plot manual dengan ggplot2
k1_df_mosaic <- as.data.frame(as.table(k1))
colnames(k1_df_mosaic) <- c("Merokok", "Kasus", "Freq")

std1_df_mosaic <- as.data.frame(as.table(hasil_chisq1$stdres))
colnames(std1_df_mosaic) <- c("Merokok", "Kasus", "StdRes")
k1_df_mosaic <- merge(k1_df_mosaic, std1_df_mosaic, by = c("Merokok", "Kasus"))

# Hitung proporsi untuk lebar dan tinggi tile
k1_df_mosaic <- k1_df_mosaic %>%
  group_by(Merokok) %>%
  mutate(prop_tinggi = Freq / sum(Freq)) %>%
  ungroup() %>%
  group_by(Kasus) %>%
  mutate(prop_lebar = sum(Freq) / sum(k1_df_mosaic$Freq)) %>%
  ungroup()

k1_df_mosaic$Merokok <- factor(k1_df_mosaic$Merokok, levels = c("Smoker", "Non-Smoker"))
k1_df_mosaic$Kasus   <- factor(k1_df_mosaic$Kasus,   levels = c("Cancer(+)", "Control(-)"))

ggplot(k1_df_mosaic, aes(x = Kasus, y = prop_tinggi, fill = StdRes, width = prop_lebar)) +
  geom_bar(stat = "identity", position = "stack", color = "white", linewidth = 1) +
  facet_grid(. ~ Kasus, scales = "free_x", space = "free_x") +
  scale_fill_gradient2(low = "#2980b9", mid = "#f8f9fa", high = "#c0392b",
                       midpoint = 0, name = "Std.\nResidual") +
  geom_text(aes(label = sprintf("n=%d\nd=%.2f", Freq, StdRes)),
            position = position_stack(vjust = 0.5),
            fontface = "bold", size = 4, color = "#2c3e50") +
  facet_grid(Merokok ~ Kasus, scales = "free", space = "free") +
  scale_y_continuous(labels = scales::percent_format()) +
  labs(title    = "Mosaic Plot: Merokok vs Kanker Paru",
       subtitle = "Merah = observasi > harapan | Biru = observasi < harapan | d = standardized residual",
       x = "Status Kasus", y = "Proporsi dalam Kelompok") +
  theme_minimal(base_size = 12) +
  theme(plot.title    = element_text(face = "bold", size = 13, color = "#1a3c5e", hjust = 0.5),
        plot.subtitle = element_text(size = 9, color = "#555", hjust = 0.5),
        strip.text    = element_text(face = "bold", size = 11, color = "#1a3c5e"),
        strip.background = element_rect(fill = "#eaf4fb", color = NA),
        panel.grid    = element_blank(),
        axis.text.x   = element_blank(),
        axis.ticks.x  = element_blank())

Interpretasi Mosaic Plot: Lebar tiap kolom proporsional terhadap total marginal merokok. Sel Smoker-Cancer dan Non-Smoker-Control berwarna merah (observasi melebihi harapan), sedangkan Smoker-Control dan Non-Smoker-Cancer berwarna biru — mengindikasikan asosiasi positif antara merokok dan kanker paru.

res1_df <- data.frame(
  Merokok  = factor(rep(c("Smoker","Non-Smoker"), each=2),
                    levels=c("Smoker","Non-Smoker")),
  Status   = factor(rep(c("Cancer(+)","Control(-)"), 2),
                    levels=c("Cancer(+)","Control(-)")),
  Pearson  = as.vector(t(hasil_chisq1$residuals)),
  Std      = as.vector(t(hasil_chisq1$stdres))
)

ggplot(res1_df, aes(x=Status, y=Merokok, fill=Std)) +
  geom_tile(color="white", linewidth=1.5) +
  geom_text(aes(label=sprintf("e=%.2f\nd=%.2f", Pearson, Std)),
            fontface="bold", size=4.2, lineheight=1.3) +
  scale_fill_gradient2(low="#2980b9", mid="white", high="#c0392b",
                       midpoint=0, name="Std.\nResidual",
                       limits=c(-5,5), oob=scales::squish) +
  labs(title   ="Heatmap Residual Kasus 1: Merokok vs Kanker Paru",
       subtitle="e = Pearson Residual; d = Standardized Residual | |d| > 1,96 → signifikan",
       x="Status Kanker", y="Status Merokok") +
  theme_minimal(base_size=12) +
  theme(plot.title    = element_text(face="bold", size=13, color="#1a3c5e", hjust=0.5),
        plot.subtitle = element_text(size=9, color="#555", hjust=0.5),
        panel.grid    = element_blank(),
        axis.text     = element_text(size=11))

Interpretasi Heatmap Residual: Semua nilai \(|d| > 1{,}96\), menunjukkan keempat sel menyimpang signifikan dari ekspektasi independensi. Sel Smoker–Cancer dan Non-Smoker–Control positif (lebih banyak dari harapan), sedangkan Smoker–Control dan Non-Smoker–Cancer negatif — pola asosiasi positif antara merokok dan kanker paru.


Kasus 2: Gender dan Identifikasi Partai Politik

Frekuensi Harapan

Frekuensi harapan dihitung dengan \(E_{ij} = n_{i+} \cdot n_{+j} / n\):

hasil_chisq2 <- chisq.test(k2, correct = FALSE)
E2 <- hasil_chisq2$expected
cat("=== Frekuensi Harapan ===\n")
## === Frekuensi Harapan ===
round(E2, 2)
##         Partai
## Gender   Democrat Republican Independent
##   Female   456.95     297.43      602.62
##   Male     368.05     239.57      485.38
Frekuensi Harapan di Bawah H₀ (Independensi)
Gender Democrat Republican Independent
Female 456.95 297.43 602.62
Male 368.05 239.57 485.38

Semua frekuensi harapan \(> 5\), sehingga syarat uji Chi-Square terpenuhi tanpa perlu penggabungan sel.

Uji Chi-Square Independensi

hasil_chisq2
## 
##  Pearson's Chi-squared test
## 
## data:  k2
## X-squared = 12.569, df = 2, p-value = 0.001865
cat(sprintf("\nχ²  = %.4f\n", hasil_chisq2$statistic))
## 
## χ²  = 12.5693
cat(sprintf("df  = %d\n",     hasil_chisq2$parameter))
## df  = 2
cat(sprintf("p   = %.6f\n",   hasil_chisq2$p.value))
## p   = 0.001865

Pearson Residual dan Standardized Residual

cat("=== Pearson Residual ===\n")
## === Pearson Residual ===
round(hasil_chisq2$residuals, 4)
##         Partai
## Gender   Democrat Republican Independent
##   Female   1.7801    -1.4747     -0.5140
##   Male    -1.9834     1.6431      0.5728
cat("\n=== Standardized Residual (Adjusted Residual) ===\n")
## 
## === Standardized Residual (Adjusted Residual) ===
round(hasil_chisq2$stdres, 4)
##         Partai
## Gender   Democrat Republican Independent
##   Female   3.2724    -2.4986     -1.0322
##   Male    -3.2724     2.4986      1.0322
Standardized Residual (|d| > 1.96 → signifikan pada α = 0.05)
Gender Democrat Republican Independent
Female 3.272 -2.499 -1.032
Male -3.272 2.499 1.032

Interpretasi Standardized Residual:

  • Female–Democrat (\(d > 1{,}96\)): wanita lebih banyak mengidentifikasi sebagai Democrat dari yang diharapkan.
  • Male–Democrat (\(d < -1{,}96\)): pria lebih sedikit mengidentifikasi sebagai Democrat.
  • Male–Republican (\(d > 1{,}96\)): pria lebih banyak mengidentifikasi sebagai Republican.
  • Female–Republican (\(d < -1{,}96\)): wanita lebih sedikit mengidentifikasi sebagai Republican.
  • Sel Independent mendekati nol → gender tidak membedakan secara signifikan preferensi Independent.

Partisi G²

Untuk tabel \(2\times3\) (\(df=2\)), dilakukan dua partisi \(2\times2\):

  1. Partisi 1 — Democrat vs Republican (kolom Independent dikecualikan)
  2. Partisi 2 — (Democrat + Republican) vs Independent
hitung_G2 <- function(mat) {
  res   <- chisq.test(mat, correct = FALSE)
  E_mat <- res$expected
  G2    <- 2 * sum(mat * log(mat / E_mat))
  df    <- (nrow(mat)-1) * (ncol(mat)-1)
  pval  <- pchisq(G2, df = df, lower.tail = FALSE)
  list(G2 = G2, df = df, p = pval)
}

g2_total <- hitung_G2(k2)
cat(sprintf("G² Keseluruhan (2×3) : %.4f, df = %d, p = %.6f\n",
            g2_total$G2, g2_total$df, g2_total$p))
## G² Keseluruhan (2×3) : 12.6009, df = 2, p = 0.001835
k2_a  <- k2[, c("Democrat","Republican")]
g2_a  <- hitung_G2(k2_a)
cat(sprintf("\nPartisi 1 (Dem vs Rep)       : G² = %.3f, df = %d, p = %.3f\n",
            g2_a$G2, g2_a$df, g2_a$p))
## 
## Partisi 1 (Dem vs Rep)       : G² = 11.536, df = 1, p = 0.001
k2_b  <- cbind(DemRep      = k2[,"Democrat"] + k2[,"Republican"],
               Independent = k2[,"Independent"])
g2_b  <- hitung_G2(k2_b)
cat(sprintf("Partisi 2 (DemRep vs Ind)    : G² = %.3f, df = %d, p = %.3f\n",
            g2_b$G2, g2_b$df, g2_b$p))
## Partisi 2 (DemRep vs Ind)    : G² = 1.065, df = 1, p = 0.302
cat(sprintf("\nJumlah G² Partisi            : %.3f + %.3f = %.3f\n",
            g2_a$G2, g2_b$G2, g2_a$G2 + g2_b$G2))
## 
## Jumlah G² Partisi            : 11.536 + 1.065 = 12.601
cat(sprintf("G² Keseluruhan               : %.3f\n", g2_total$G2))
## G² Keseluruhan               : 12.601
Uji Statistik df p-value Keputusan (α=0,05) Interpretasi
Keseluruhan (2×3) G² = 12.601 2 0.0018 Tolak H₀ Ada asosiasi antara gender dan afiliasi partai
Partisi 1: Dem vs Rep G² = 11.536 1 0.0007 Tolak H₀ Gender berbeda nyata dalam pilihan Democrat vs Republican
Partisi 2: (DemRep) vs Ind G² = 1.065 1 0.3020 Gagal Tolak H₀ Gender tidak berbeda nyata dalam pilihan (DemRep) vs Independent

Jumlah \(G^2\) partisi \(\approx G^2\) keseluruhan (\(df = 1 + 1 = 2\)), mengkonfirmasi partisi dilakukan secara orthogonal dan exhaustive. Asosiasi keseluruhan didominasi oleh Partisi 1 (Democrat vs Republican) yang sangat signifikan, sedangkan Partisi 2 (DemRep vs Independent) tidak signifikan.

Visualisasi Kasus 2

k2_df <- data.frame(
  Gender = factor(rep(c("Female","Male"), each=3),
                  levels=c("Female","Male")),
  Partai = factor(rep(c("Democrat","Republican","Independent"), 2),
                  levels=c("Democrat","Republican","Independent")),
  n      = c(495, 272, 590, 330, 265, 498)
) %>%
  group_by(Gender) %>%
  mutate(prop  = n / sum(n),
         label = paste0(round(prop*100,1),"%"))

ggplot(k2_df, aes(x=Partai, y=prop, fill=Gender)) +
  geom_col(position="dodge", width=0.6, color="white") +
  geom_text(aes(label=label), position=position_dodge(width=0.6),
            vjust=-0.5, fontface="bold", size=3.8) +
  scale_fill_manual(values=c("Female"="#c0392b","Male"="#2980b9")) +
  scale_y_continuous(labels=scales::percent_format(), limits=c(0,0.58)) +
  labs(title   ="Proporsi Identifikasi Partai Politik Berdasarkan Gender",
       subtitle="n = 2450  |  G² = signifikan pada α = 0,05",
       x="Identifikasi Partai", y="Proporsi (%)") +
  tema6

Interpretasi: Perbedaan proporsi antar gender paling mencolok pada kolom Democrat (Female 36,5% vs Male 30,2%) dan Republican (Female 20,0% vs Male 24,2%). Pada Independent, proporsi kedua gender hampir sama — konsisten dengan Partisi 2 yang tidak signifikan.

ggplot(k2_df, aes(x=Gender, y=prop, fill=Partai)) +
  geom_col(position="fill", width=0.5, color="white", linewidth=0.4) +
  geom_text(aes(label=label), position=position_fill(vjust=0.5),
            fontface="bold", size=4, color="white") +
  scale_fill_manual(values=c("Democrat"="#2980b9",
                              "Republican"="#c0392b",
                              "Independent"="#27ae60")) +
  scale_y_continuous(labels=scales::percent_format()) +
  labs(title   ="Komposisi Afiliasi Partai per Gender (Stacked 100%)",
       subtitle="Democrat (biru), Republican (merah), Independent (hijau)",
       x="Gender", y="Proporsi (%)") +
  tema6

Interpretasi Stacked Bar: Female memiliki blok Democrat lebih besar dan Republican lebih kecil dibandingkan Male. Blok Independent relatif setara, memperkuat kesimpulan bahwa ketidakindependenan didorong oleh perbedaan pada Democrat–Republican.

k2_df_mosaic <- as.data.frame(as.table(k2))
colnames(k2_df_mosaic) <- c("Gender", "Partai", "Freq")

std2_df_mosaic <- as.data.frame(as.table(hasil_chisq2$stdres))
colnames(std2_df_mosaic) <- c("Gender", "Partai", "StdRes")
k2_df_mosaic <- merge(k2_df_mosaic, std2_df_mosaic, by = c("Gender", "Partai"))

k2_df_mosaic <- k2_df_mosaic %>%
  group_by(Gender) %>%
  mutate(prop_tinggi = Freq / sum(Freq)) %>%
  ungroup() %>%
  group_by(Partai) %>%
  mutate(prop_lebar = sum(Freq) / sum(k2_df_mosaic$Freq)) %>%
  ungroup()

k2_df_mosaic$Gender <- factor(k2_df_mosaic$Gender, levels = c("Female", "Male"))
k2_df_mosaic$Partai <- factor(k2_df_mosaic$Partai, levels = c("Democrat", "Republican", "Independent"))

ggplot(k2_df_mosaic, aes(x = Partai, y = prop_tinggi, fill = StdRes, width = prop_lebar)) +
  geom_bar(stat = "identity", position = "stack", color = "white", linewidth = 1) +
  facet_grid(Gender ~ Partai, scales = "free", space = "free") +
  scale_fill_gradient2(low = "#2980b9", mid = "#f8f9fa", high = "#c0392b",
                       midpoint = 0, name = "Std.\nResidual") +
  geom_text(aes(label = sprintf("n=%d\nd=%.2f", Freq, StdRes)),
            position = position_stack(vjust = 0.5),
            fontface = "bold", size = 4, color = "#2c3e50") +
  scale_y_continuous(labels = scales::percent_format()) +
  labs(title    = "Mosaic Plot: Gender vs Identifikasi Partai Politik",
       subtitle = "Merah = observasi > harapan | Biru = observasi < harapan | d = standardized residual",
       x = "Identifikasi Partai", y = "Proporsi dalam Kelompok") +
  theme_minimal(base_size = 12) +
  theme(plot.title    = element_text(face = "bold", size = 13, color = "#1a3c5e", hjust = 0.5),
        plot.subtitle = element_text(size = 9, color = "#555", hjust = 0.5),
        strip.text    = element_text(face = "bold", size = 11, color = "#1a3c5e"),
        strip.background = element_rect(fill = "#eaf4fb", color = NA),
        panel.grid    = element_blank(),
        axis.text.x   = element_blank(),
        axis.ticks.x  = element_blank())

Interpretasi Mosaic Plot: Sel Female–Democrat dan Male–Republican memiliki arsiran merah (observasi > harapan), sedangkan Female–Republican dan Male–Democrat berasiran biru. Sel Independent mendekati putih (residual ≈ 0), mengkonfirmasi gender tidak membedakan preferensi Independent secara signifikan.

res2_df <- as.data.frame(as.table(hasil_chisq2$residuals))
std2_df <- as.data.frame(as.table(hasil_chisq2$stdres))
colnames(res2_df) <- c("Gender","Partai","Pearson")
colnames(std2_df) <- c("Gender","Partai","Std")
res2_full <- merge(res2_df, std2_df, by=c("Gender","Partai"))

res2_full$sig <- ifelse(abs(res2_full$Std) > 2.576, "***",
                 ifelse(abs(res2_full$Std) > 1.960, "**",
                 ifelse(abs(res2_full$Std) > 1.645, "*", "")))

ggplot(res2_full, aes(x=Partai, y=Gender, fill=Std)) +
  geom_tile(color="white", linewidth=1.5) +
  geom_text(aes(label=sprintf("e=%.2f\nd=%.2f %s",
                               Pearson, Std, sig)),
            fontface="bold", size=3.8, lineheight=1.4) +
  scale_fill_gradient2(low="#2980b9", mid="#f8f9fa", high="#c0392b",
                       midpoint=0, name="Std.\nResidual") +
  labs(title   ="Heatmap Residual Kasus 2: Gender vs Identifikasi Partai",
       subtitle="e = Pearson Residual  |  d = Standardized Residual  |  * p<0.10  ** p<0.05  *** p<0.01",
       x="Identifikasi Partai", y="Gender") +
  theme_minimal(base_size=12) +
  theme(plot.title    = element_text(face="bold", size=13, color="#1a3c5e", hjust=0.5),
        plot.subtitle = element_text(size=9, color="#555", hjust=0.5),
        panel.grid    = element_blank(),
        axis.text     = element_text(size=11))

Interpretasi Heatmap Residual: Sel Female–Democrat dan Male–Republican memiliki \(d > 0\) (signifikan ≥ ). Sel Female–Republican** dan Male–Democrat memiliki \(d < 0\) (signifikan ≥ ). Kolom Independent** pada kedua gender: \(|d| < 1{,}96\) → tidak signifikan, tidak berkontribusi terhadap asosiasi.


Kesimpulan

Kasus 1: Merokok dan Kanker Paru

Kesimpulan Kasus 1: Terdapat asosiasi yang sangat signifikan antara kebiasaan merokok dan kanker paru (\(p < 0{,}001\) pada semua uji).

  • RD = 0,2517: proporsi kanker perokok 25,17 poin persentase lebih tinggi dari non-perokok.
  • RR ≈ 1,96 (95% CI tidak mencakup 1): risiko kanker perokok hampir 2× lebih besar.
  • OR ≈ 5,97 (95% CI tidak mencakup 1): odds kanker pada perokok sekitar 6× lebih besar dibanding non-perokok.
  • Keempat metode uji (Chi-Square, \(G^2\), Uji Dua Proporsi, Fisher Exact) konsisten menolak \(H_0\).

Temuan ini konsisten dengan literatur epidemiologi yang menegaskan merokok sebagai faktor risiko utama kanker paru.

Kasus 2: Gender dan Identifikasi Partai Politik

Kesimpulan Kasus 2: Terdapat asosiasi yang signifikan antara gender dan identifikasi partai politik ($G^2 = $ 12.601, \(df = 2\), \(p < 0{,}05\)).

Berdasarkan partisi \(G^2\) dan standardized residual:

  • Wanita secara signifikan lebih banyak mengidentifikasi sebagai Democrat dan lebih sedikit sebagai Republican (\(|d| > 1{,}96\)).
  • Pria secara signifikan lebih banyak mengidentifikasi sebagai Republican dan lebih sedikit sebagai Democrat.
  • Preferensi Independent tidak berbeda nyata antar gender — Partisi 2 tidak signifikan (\(p > 0{,}05\)).
  • Ketidakindependenan terpusat pada pasangan Democrat–Republican, bukan pada Independent (konsisten dengan Agresti, 2019).

Sintesis Umum

Kedua kasus menunjukkan bahwa inferensi tabel kontingensi dua arah merupakan alat yang sangat informatif: uji Chi-Square menjawab apakah ada asosiasi, residual mengidentifikasi di mana asosiasi paling kuat, dan partisi \(G^2\) mengungkap kategori mana yang mendorong ketidakindependenan. Integrasi antara uji formal, ukuran asosiasi, dan visualisasi menghasilkan interpretasi yang komprehensif.


Referensi

  • Agresti, A. (2013). Categorical Data Analysis (3rd ed.). John Wiley & Sons.
  • Agresti, A. (2019). An Introduction to Categorical Data Analysis (3rd ed.). Wiley.
  • Fleiss, J. L., Levin, B., & Paik, M. C. (2003). Statistical Methods for Rates and Proportions (3rd ed.). John Wiley & Sons.
  • R Core Team (2024). R: A Language and Environment for Statistical Computing. https://www.R-project.org/