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:
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:
| 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.
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.
Misalkan kita memiliki dua variabel:
| 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:
Joint distribution (distribusi bersama) adalah distribusi probabilitas dari dua variabel secara simultan. Probabilitas bersama dari sel \((i, j)\) diestimasi dengan:
Untuk tabel \(2 \times 2\) terdapat 4 sel dengan syarat: \(\sum_{i}\sum_{j} \hat{\pi}_{ij} = 1\).
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):
Marginal untuk variabel kolom (Y):
Conditional probability (peluang bersyarat) adalah probabilitas suatu kejadian terjadi dengan syarat kejadian lain sudah diketahui terjadi:
Dalam konteks tabel kita:
Perbandingan probabilitas bersyarat inilah yang menjadi dasar ukuran asosiasi seperti Relative Risk dan Odds Ratio.
Odds adalah rasio antara peluang suatu kejadian terjadi dibandingkan peluang kejadian tersebut tidak terjadi:
Untuk masing-masing kelompok pada tabel \(2 \times 2\):
| 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 adalah perbandingan odds dari dua kelompok. OR mengukur seberapa besar odds suatu outcome pada kelompok terpapar dibandingkan kelompok tidak terpapar:
Interval kepercayaan 95% untuk OR dihitung via transformasi logaritma natural:
| 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 (atau Risk Ratio) adalah rasio langsung antara probabilitas bersyarat pada kelompok terpapar dibandingkan tidak terpapar:
| 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 (Pearson’s Chi-Square Test) digunakan untuk menguji apakah terdapat hubungan yang signifikan antara dua variabel kategori. Hipotesis yang diuji adalah:
Di mana frekuensi harapan dihitung dengan:
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 adalah ukuran kekuatan asosiasi berbasis Chi-Square yang nilainya berkisar antara 0 sampai 1, sehingga lebih mudah diinterpretasikan daripada nilai \(\chi^2\) mentah.
| 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 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.
| 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 |
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\)
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.
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.
\[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)}\]
\[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}\]
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.
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}\]
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\).
| Ukuran | Nilai |
|---|---|
| P(Obesitas | Fast Food) | 0,60 |
| P(Obesitas | 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 |
# 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 ===
## Obesitas Tidak Obesitas
## Fast Food 0.6 0.4
## Tidak Fast Food 0.2 0.8
##
## === Proporsi Total ===
## Obesitas Tidak Obesitas
## Fast Food 0.3 0.2
## Tidak Fast Food 0.1 0.4
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
## Odds Tidak Fast Food : 0.2500
## Odds Ratio (OR) : 6.0000
## 95% CI untuk OR : (3.1873 ; 11.2948)
## Relative Risk (RR) : 3.0000
##
## Pearson's Chi-squared test
##
## data: data
## X-squared = 33.333, df = 1, p-value = 7.764e-09
##
## === Frekuensi yang Diharapkan ===
## Obesitas Tidak Obesitas
## Fast Food 40 60
## Tidak Fast Food 40 60
# 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
## n : 200
## 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
##
## 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
##
## 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)
## p-value (Fisher) : 0.000000
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:
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.
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.
Rasio antara kedua nilai ini menghasilkan Odds Ratio = 6,00, yang berarti odds obesitas pada kelompok fast food adalah 6 kali lebih besar.
| 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 |
Berdasarkan hasil analisis, dapat disimpulkan bahwa:
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.
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):
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 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.
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.
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&#124;h} - \hat{p}_{j&#124;i}\) | Selisih absolut risiko antar kelompok |
| Risiko Relatif (RR) | \(RR = \hat{p}_{j&#124;h} \,/\, \hat{p}_{j&#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:
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 |
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:
Nilai \(|d_{ij}| > 1{,}96\) mengindikasikan sel tersebut berkontribusi signifikan terhadap ketidakindependenan pada \(\alpha = 0{,}05\).
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):
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\).
Proporsi kejadian kanker paru dihitung sebagai probabilitas bersyarat \(P(\text{Cancer} \mid \text{Status Merokok})\):
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%)
## 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)
## 95% CI Non-Smoker : (0.1733 ; 0.3748)
Rumus titik estimasi (Agresti, 2019):
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)
## RR = 1.9589 | 95% CI: (1.3517 ; 2.8387)
## 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 |
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
##
## Pearson's Chi-squared test
##
## data: k1
## X-squared = 19.129, df = 1, p-value = 1.222e-05
##
## === Frekuensi Harapan ===
## 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
## df = 1
## p-value = 0.000008
##
## 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
##
## 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)
## 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.
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") +
tema6Interpretasi 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 (%)") +
tema6Interpretasi 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.
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 ===
## Partai
## Gender Democrat Republican Independent
## Female 456.95 297.43 602.62
## Male 368.05 239.57 485.38
| 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.
##
## Pearson's Chi-squared test
##
## data: k2
## X-squared = 12.569, df = 2, p-value = 0.001865
##
## χ² = 12.5693
## df = 2
## p = 0.001865
## === Pearson Residual ===
## Partai
## Gender Democrat Republican Independent
## Female 1.7801 -1.4747 -0.5140
## Male -1.9834 1.6431 0.5728
##
## === Standardized Residual (Adjusted Residual) ===
## Partai
## Gender Democrat Republican Independent
## Female 3.2724 -2.4986 -1.0322
## Male -3.2724 2.4986 1.0322
| Gender | Democrat | Republican | Independent |
|---|---|---|---|
| Female | 3.272 | -2.499 | -1.032 |
| Male | -3.272 | 2.499 | 1.032 |
Interpretasi Standardized Residual:
Untuk tabel \(2\times3\) (\(df=2\)), dilakukan dua partisi \(2\times2\):
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
##
## Jumlah G² Partisi : 11.536 + 1.065 = 12.601
## 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.
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 (%)") +
tema6Interpretasi: 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 (%)") +
tema6Interpretasi 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: Terdapat asosiasi yang sangat signifikan antara kebiasaan merokok dan kanker paru (\(p < 0{,}001\) pada semua uji).
Temuan ini konsisten dengan literatur epidemiologi yang menegaskan merokok sebagai faktor risiko utama kanker paru.
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:
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.