Dalam statistika, data dapat dibedakan menjadi dua jenis besar: data kontinu dan data kategori. Data kontinu nilainya berupa angka yang bisa mengambil nilai berapa saja dalam suatu rentang — misalnya tinggi badan, berat badan, atau suhu. Sedangkan data kategori adalah data yang nilainya hanya bisa masuk ke dalam kelompok atau kategori tertentu yang sudah ditentukan, tanpa ada nilai di antaranya.
Analisis data kategori (categorical data analysis) adalah kumpulan metode statistik yang dirancang khusus untuk menganalisis data jenis ini. Menurut Agresti (2013), cakupannya mulai dari yang sederhana seperti tabel kontingensi dan uji chi-square, sampai yang lebih kompleks seperti regresi logistik dan model log-linear. Metode-metode ini tidak bisa begitu saja digantikan oleh metode untuk data kontinu, karena asumsi dasarnya memang berbeda — misalnya asumsi normalitas jelas tidak berlaku untuk data yang hanya bernilai “ya” atau “tidak”.
Ada beberapa hal yang perlu dipahami tentang variabel kategori agar tidak salah dalam memilih metode analisis:
1. Nilainya berupa kategori, bukan angka pengukuran
Variabel kategori merepresentasikan keanggotaan dalam suatu kelompok. Jenis kelamin (laki-laki/perempuan), status gizi, atau golongan darah adalah contohnya. Meskipun kadang dikodekan dengan angka (misal: 0 dan 1), angka itu hanya label, tidak punya makna numerik seperti pada variabel kontinu.
2. Tidak ada jarak antar kategori yang bermakna
Ini yang jadi pembeda utama dari variabel kontinu. Pada variabel kontinu, kita bisa bilang selisih antara nilai 10 dan 20 sama besarnya dengan selisih antara 20 dan 30. Pada variabel kategori, konsep “jarak” ini tidak berlaku — tidak ada artinya bilang kategori “gizi kurang” lebih jauh dari “gizi baik” dibanding kategori lainnya.
3. Skala pengukurannya nominal atau ordinal
Mengacu pada klasifikasi Stevens (1946):
4. Dirangkum dengan frekuensi dan proporsi
Karena tidak bisa dijumlah atau dirata-rata secara langsung, ringkasan yang tepat untuk variabel kategori adalah frekuensi (jumlah per kelompok) dan proporsi atau persentasenya. Ukuran seperti mean dan standar deviasi tidak relevan di sini.
Analisis data kategori sangat luas penggunaannya. Beberapa contoh nyata:
Epidemiologi: menguji apakah ada hubungan antara kebiasaan merokok (ya/tidak) dengan kejadian hipertensi (ya/tidak). Ukuran seperti odds ratio dan relative risk digunakan untuk mengkuantifikasi besarnya risiko.
Gizi dan kesehatan masyarakat: menganalisis apakah status gizi balita (gizi kurang/gizi baik) berhubungan dengan kejadian ISPA. Ini yang akan saya gunakan sebagai contoh kasus dalam laporan ini.
Psikologi: mengukur tingkat kesepakatan dua observer dalam menilai perilaku subjek yang dikategorikan (misal: agresif/tidak agresif), menggunakan koefisien Kappa Cohen.
Tabel kontingensi (contingency table) adalah tabel yang digunakan untuk menampilkan distribusi frekuensi dari dua atau lebih variabel kategori secara bersamaan. Tabel ini menyusun observasi berdasarkan kombinasi kategori dari masing-masing variabel, sehingga memungkinkan kita melihat pola hubungan antarvariabel secara langsung sebelum melakukan pengujian statistik.
Bentuk paling sederhana adalah tabel \(2 \times 2\), yang terbentuk ketika masing-masing variabel hanya punya dua kategori. Inilah yang paling sering ditemui dalam praktik, terutama untuk variabel biner seperti ya/tidak atau terpapar/tidak terpapar (Agresti, 2013).
Secara umum, struktur tabel kontingensi \(2 \times 2\) adalah sebagai berikut:
| Y = 1 | Y = 0 | Total | |
|---|---|---|---|
| X = 1 | \(n_{11}\) | \(n_{12}\) | \(n_{1+}\) |
| X = 0 | \(n_{21}\) | \(n_{22}\) | \(n_{2+}\) |
| Total | \(n_{+1}\) | \(n_{+2}\) | \(n\) |
Keterangan:
Untuk menjelaskan konsep-konsep berikutnya, saya gunakan satu contoh yang sama sepanjang bagian ini: data hasil pencatatan di posyandu terhadap 200 balita, dengan variabel status gizi (gizi kurang/gizi baik) dan kejadian ISPA dalam tiga bulan terakhir (ya/tidak).
| ISPA | Tidak ISPA | Total | |
|---|---|---|---|
| Gizi Kurang | 55 | 45 | 100 |
| Gizi Baik | 25 | 75 | 100 |
| Total | 80 | 120 | 200 |
Joint distribution atau distribusi bersama adalah distribusi peluang yang menggambarkan kemungkinan suatu observasi jatuh pada kombinasi kategori tertentu dari kedua variabel secara simultan.
Rumus:
\[\pi_{ij} = P(X = i,\; Y = j) = \frac{n_{ij}}{n}\]
dengan syarat \(\displaystyle\sum_{i,j} \pi_{ij} = 1\).
Contoh:
\[\pi_{11} = P(\text{Gizi Kurang} \cap \text{ISPA}) = \frac{55}{200} = 0{,}275\]
\[\pi_{12} = P(\text{Gizi Kurang} \cap \text{Tidak ISPA}) = \frac{45}{200} = 0{,}225\]
\[\pi_{21} = P(\text{Gizi Baik} \cap \text{ISPA}) = \frac{25}{200} = 0{,}125\]
\[\pi_{22} = P(\text{Gizi Baik} \cap \text{Tidak ISPA}) = \frac{75}{200} = 0{,}375\]
Cek: \(0{,}275 + 0{,}225 + 0{,}125 + 0{,}375 = 1{,}00\) ✓
Marginal distribution adalah distribusi peluang dari satu variabel saja, tanpa memperhatikan variabel lainnya. Diperoleh dengan menjumlahkan frekuensi sepanjang baris atau kolom — istilah “marginal” mengacu pada posisinya yang berada di tepi (margin) tabel.
Rumus:
\[\pi_{i+} = \sum_j \pi_{ij} = \frac{n_{i+}}{n} \qquad \pi_{+j} = \sum_i \pi_{ij} = \frac{n_{+j}}{n}\]
Jika dua variabel independen, berlaku \(\pi_{ij} = \pi_{i+} \cdot \pi_{+j}\) untuk semua sel. Kondisi ini menjadi hipotesis nol dalam uji chi-square.
Contoh:
\[\pi_{1+} = P(\text{Gizi Kurang}) = \frac{100}{200} = 0{,}50 \qquad \pi_{2+} = P(\text{Gizi Baik}) = \frac{100}{200} = 0{,}50\]
\[\pi_{+1} = P(\text{ISPA}) = \frac{80}{200} = 0{,}40 \qquad \pi_{+2} = P(\text{Tidak ISPA}) = \frac{120}{200} = 0{,}60\]
Sebagai cek independensi: jika independen, seharusnya \(\pi_{11} = 0{,}50 \times 0{,}40 = 0{,}20\), namun kenyataannya \(\pi_{11} = 0{,}275\) — ini sudah memberi sinyal awal adanya asosiasi.
Conditional probability atau peluang bersyarat adalah peluang variabel \(Y\) mengambil nilai tertentu, dengan syarat nilai variabel \(X\) sudah diketahui.
Rumus:
\[P(Y = j \mid X = i) = \frac{\pi_{ij}}{\pi_{i+}} = \frac{n_{ij}}{n_{i+}}\]
Contoh:
\[P(\text{ISPA} \mid \text{Gizi Kurang}) = \frac{55}{100} = 0{,}55\]
\[P(\text{ISPA} \mid \text{Gizi Baik}) = \frac{25}{100} = 0{,}25\]
Perbedaan yang cukup besar antara kedua peluang bersyarat ini (0,55 vs 0,25) mengindikasikan bahwa status gizi dan kejadian ISPA tidak independen. Kalau keduanya benar-benar independen, kedua nilai ini seharusnya sama besarnya.
Ukuran asosiasi digunakan untuk mengkuantifikasi seberapa kuat hubungan antara dua variabel kategori dalam tabel kontingensi. Tiga ukuran yang umum digunakan adalah Odds, Odds Ratio, dan Relative Risk. Untuk penjelasan rumus, digunakan notasi tabel \(2 \times 2\) standar berikut:
| Y = 1 | Y = 0 | |
|---|---|---|
| X = 1 | \(a\) | \(b\) |
| X = 0 | \(c\) | \(d\) |
Odds adalah perbandingan antara peluang suatu kejadian terjadi dengan peluang kejadian tersebut tidak terjadi. Berbeda dengan peluang (probability) yang nilainya antara 0 dan 1, odds bisa bernilai lebih dari 1.
\[\text{Odds}(Y=1 \mid X=1) = \frac{P(Y=1 \mid X=1)}{P(Y=0 \mid X=1)} = \frac{a}{b}\]
\[\text{Odds}(Y=1 \mid X=0) = \frac{P(Y=1 \mid X=0)}{P(Y=0 \mid X=0)} = \frac{c}{d}\]
Interpretasi: Jika odds = 2, artinya dalam kelompok tersebut kejadian \(Y=1\) dua kali lebih mungkin terjadi dibanding tidak terjadi. Odds = 1 berarti peluang terjadi dan tidak terjadi sama besar. Odds < 1 berarti kejadian lebih jarang terjadi dibanding tidak terjadi.
Odds Ratio (OR) adalah rasio antara odds kelompok \(X=1\) (terpapar) dengan odds kelompok \(X=0\) (tidak terpapar).
\[OR = \frac{a/b}{c/d} = \frac{ad}{bc}\]
OR merupakan ukuran asosiasi yang paling banyak digunakan dalam analisis data kategori karena dapat diestimasi pada semua desain studi, termasuk case-control (Fleiss et al., 2003).
Interpretasi:
Relative Risk (RR) atau Risk Ratio adalah perbandingan langsung antara peluang kejadian \(Y=1\) pada kelompok \(X=1\) dengan peluang kejadian \(Y=1\) pada kelompok \(X=0\).
\[RR = \frac{P(Y=1 \mid X=1)}{P(Y=1 \mid X=0)} = \frac{a/(a+b)}{c/(c+d)}\]
Interpretasi:
Perlu dicatat bahwa RR hanya valid dihitung pada studi dengan desain prospektif (cohort atau cross-sectional). Pada studi case-control, sampling dilakukan berdasarkan status \(Y\), sehingga proporsi \(a/(a+b)\) dan \(c/(c+d)\) tidak mencerminkan peluang kejadian sesungguhnya — dalam kondisi ini hanya OR yang dapat digunakan.
Data berasal dari pencatatan di posyandu terhadap 200 balita. Variabel yang diamati adalah status gizi (gizi kurang/gizi baik) dan apakah balita pernah mengalami ISPA dalam tiga bulan terakhir.
| ISPA | Tidak ISPA | Total | |
|---|---|---|---|
| Gizi Kurang | \(a = 55\) | \(b = 45\) | \(100\) |
| Gizi Baik | \(c = 25\) | \(d = 75\) | \(100\) |
| Total | \(80\) | \(120\) | \(n = 200\) |
\[P(\text{ISPA} \mid \text{Gizi Kurang}) = \frac{a}{a+b} = \frac{55}{100} = 0{,}55\]
\[P(\text{ISPA} \mid \text{Gizi Baik}) = \frac{c}{c+d} = \frac{25}{100} = 0{,}25\]
Balita dengan gizi kurang punya peluang terkena ISPA sebesar 55%, jauh lebih tinggi dibanding balita gizi baik yang hanya 25%.
\[\text{Odds}_{\text{Gizi Kurang}} = \frac{a}{b} = \frac{55}{45} \approx 1{,}222\]
Pada balita gizi kurang, kejadian ISPA 1,22 kali lebih mungkin terjadi dibanding tidak terjadi.
\[\text{Odds}_{\text{Gizi Baik}} = \frac{c}{d} = \frac{25}{75} \approx 0{,}333\]
Pada balita gizi baik, ISPA justru lebih jarang terjadi — odds-nya di bawah 1, artinya lebih banyak yang tidak mengalami ISPA.
\[OR = \frac{ad}{bc} = \frac{55 \times 75}{45 \times 25} = \frac{4125}{1125} \approx 3{,}667\]
Odds balita gizi kurang terkena ISPA sekitar 3,67 kali lebih besar dibandingkan balita gizi baik. Nilai OR yang jauh di atas 1 ini mengindikasikan asosiasi yang cukup kuat antara status gizi dan kejadian ISPA.
Karena data cross-sectional, RR juga bisa dihitung:
\[RR = \frac{a/(a+b)}{c/(c+d)} = \frac{55/100}{25/100} = \frac{0{,}55}{0{,}25} = 2{,}20\]
Balita gizi kurang 2,2 kali lebih berisiko terkena ISPA dibanding balita gizi baik.
Perlu diperhatikan bahwa \(OR \neq RR\) (3,67 vs 2,20). Ini wajar karena proporsi kejadian ISPA secara keseluruhan cukup besar (40%), sehingga kondisi rare event tidak terpenuhi dan OR cenderung melebih-besarkan risiko relatif. Semakin langka kejadian, OR dan RR akan semakin konvergen.
# Input data
data_gizi <- matrix(
c(55, 45, 25, 75),
nrow = 2,
byrow = TRUE,
dimnames = list(
"Status Gizi" = c("Gizi Kurang", "Gizi Baik"),
"ISPA" = c("ISPA", "Tidak ISPA")
)
)
cat("Tabel Kontingensi:\n")## Tabel Kontingensi:
## ISPA
## Status Gizi ISPA Tidak ISPA
## Gizi Kurang 55 45
## Gizi Baik 25 75
##
## Joint Distribution:
## ISPA
## Status Gizi ISPA Tidak ISPA
## Gizi Kurang 0.275 0.225
## Gizi Baik 0.125 0.375
##
## Conditional Distribution (per baris):
## ISPA
## Status Gizi ISPA Tidak ISPA
## Gizi Kurang 0.55 0.45
## Gizi Baik 0.25 0.75
a <- data_gizi[1, 1] # Gizi Kurang & ISPA
b <- data_gizi[1, 2] # Gizi Kurang & Tidak ISPA
c <- data_gizi[2, 1] # Gizi Baik & ISPA
d <- data_gizi[2, 2] # Gizi Baik & Tidak ISPA
odds_gk <- a / b
odds_gb <- c / d
OR_gizi <- (a * d) / (b * c)
RR_gizi <- (a / (a + b)) / (c / (c + d))
cat("Odds Gizi Kurang :", round(odds_gk, 4), "\n")## Odds Gizi Kurang : 1.2222
## Odds Gizi Baik : 0.3333
## Odds Ratio (OR) : 3.6667
## Relative Risk : 2.2
Hasilnya konsisten dengan perhitungan manual: OR ≈ 3,667 dan RR = 2,20.
Uji chi-square digunakan untuk menguji hipotesis bahwa kedua variabel independen. Hipotesisnya:
Statistik ujinya:
\[\chi^2 = \sum_{i,j} \frac{(n_{ij} - \hat{\mu}_{ij})^2}{\hat{\mu}_{ij}}, \quad \hat{\mu}_{ij} = \frac{n_{i+} \cdot n_{+j}}{n}\]
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: data_gizi
## X-squared = 17.521, df = 1, p-value = 2.842e-05
##
## Frekuensi yang diharapkan di bawah H0:
## ISPA
## Status Gizi ISPA Tidak ISPA
## Gizi Kurang 40 60
## Gizi Baik 40 60
# Mosaic plot untuk visualisasi distribusi bersama
mosaicplot(
data_gizi,
main = "Status Gizi vs Kejadian ISPA pada Balita",
color = c("#E74C3C", "#2980B9"),
xlab = "Status Gizi",
ylab = "Kejadian ISPA",
las = 1
)Uji chi-square menghasilkan \(p\)-value \(< 0{,}05\), sehingga \(H_0\) ditolak pada tingkat signifikansi 5%. Artinya, data memberikan bukti yang cukup kuat bahwa status gizi dan kejadian ISPA tidak independen — ada asosiasi yang signifikan secara statistik antara keduanya.
Nilai \(OR \approx 3{,}67\) menunjukkan bahwa odds balita gizi kurang terkena ISPA hampir 4 kali lebih besar dibanding balita gizi baik. Nilai \(RR = 2{,}20\) mengonfirmasi dari sudut peluang: risiko ISPA pada balita gizi kurang 2,2 kali lebih tinggi. Perbedaan antara OR dan RR wajar terjadi karena proporsi kejadian ISPA keseluruhan cukup besar (40%), sehingga OR melebih-besarkan risiko relatif dibanding RR.
Secara substantif, temuan ini konsisten dengan teori yang sudah lama dikenal dalam ilmu gizi dan kesehatan anak. Balita dengan gizi kurang memiliki sistem imun yang lebih lemah karena kekurangan mikronutrien seperti vitamin A, zinc, dan zat besi yang berperan penting dalam respons imunologis. Kondisi ini membuat mereka lebih rentan terhadap infeksi saluran pernapasan akut.
Hasil ini bisa menjadi dasar untuk memperkuat program pemantauan gizi balita di posyandu, khususnya sebagai upaya pencegahan ISPA. Meski begitu, perlu diingat beberapa keterbatasan: data ini bersifat cross-sectional sehingga tidak bisa menyimpulkan kausalitas secara langsung, dan faktor perancu seperti kondisi sanitasi rumah, kepadatan hunian, serta paparan asap rokok tidak dikontrol dalam analisis ini.
Data berikut menggambarkan hubungan antara kebiasaan merokok dan kejadian kanker paru dalam sebuah studi kasus-kontrol.
tabel1 <- matrix(
c(688, 650, 21, 59),
nrow = 2,
byrow = TRUE,
dimnames = list(
"Status Merokok" = c("Smoker", "Non-Smoker"),
"Status Kanker" = c("Cancer (+)", "Control (-)")
)
)
kable(
addmargins(tabel1),
caption = "Tabel 1. Tabel Kontingensi 2×2: Kebiasaan Merokok dan Kanker Paru"
) |>
kable_styling(
bootstrap_options = c("striped", "hover", "bordered"),
full_width = FALSE, position = "center"
) |>
row_spec(3, bold = TRUE, background = "#f5f5f5") |>
column_spec(4, bold = TRUE)| Cancer (+) | Control (-) | Sum | |
|---|---|---|---|
| Smoker | 688 | 650 | 1338 |
| Non-Smoker | 21 | 59 | 80 |
| Sum | 709 | 709 | 1418 |
Dari tabel di atas, total sampel adalah \(n = 1418\), dengan 1338 Smoker dan 80 Non-Smoker.
Dengan notasi standar tabel \(2 \times 2\):
| Cancer (+) | Control (−) | Total | |
|---|---|---|---|
| Smoker | \(a = 688\) | \(b = 650\) | \(n_1 = 1338\) |
| Non-Smoker | \(c = 21\) | \(d = 59\) | \(n_2 = 80\) |
| Total | \(n_{+1} = 709\) | \(n_{+2} = 709\) | \(n = 1418\) |
\[\hat{p}_1 = \frac{a}{n_1} = \frac{688}{1338} \approx 0{,}5142\]
\[\hat{p}_2 = \frac{c}{n_2} = \frac{21}{80} = 0{,}2625\]
\[RD = \hat{p}_1 - \hat{p}_2 = 0{,}5142 - 0{,}2625 = 0{,}2517\]
\[SE_{RD} = \sqrt{\frac{\hat{p}_1(1-\hat{p}_1)}{n_1} + \frac{\hat{p}_2(1-\hat{p}_2)}{n_2}} = \sqrt{\frac{0{,}5142 \times 0{,}4858}{1338} + \frac{0{,}2625 \times 0{,}7375}{80}}\]
\[SE_{RD} = \sqrt{0{,}000187 + 0{,}002420} = \sqrt{0{,}002607} \approx 0{,}05106\]
\[95\%\text{ CI}: 0{,}2517 \pm 1{,}96 \times 0{,}05106 = [0{,}1516;\; 0{,}3518]\]
Karena interval tidak mencakup 0, perbedaan risiko absolut ini signifikan.
\[RR = \frac{\hat{p}_1}{\hat{p}_2} = \frac{0{,}5142}{0{,}2625} \approx 1{,}9588\]
Untuk interval kepercayaan, digunakan transformasi log:
\[SE_{\ln RR} = \sqrt{\frac{1 - \hat{p}_1}{n_1 \hat{p}_1} + \frac{1 - \hat{p}_2}{n_2 \hat{p}_2}} = \sqrt{\frac{0{,}4858}{1338 \times 0{,}5142} + \frac{0{,}7375}{80 \times 0{,}2625}}\]
\[SE_{\ln RR} = \sqrt{\frac{0{,}4858}{688} + \frac{0{,}7375}{21}} = \sqrt{0{,}000706 + 0{,}035119} = \sqrt{0{,}035825} \approx 0{,}18928\]
\[95\%\text{ CI}: \exp\!\left(\ln(1{,}9588) \pm 1{,}96 \times 0{,}18928\right) = \exp(0{,}6731 \pm 0{,}3710) = \left[\exp(0{,}3021);\; \exp(1{,}0441)\right]\]
\[= [1{,}353;\; 2{,}841]\]
Interval tidak mencakup 1, sehingga RR signifikan secara statistik.
\[OR = \frac{ad}{bc} = \frac{688 \times 59}{650 \times 21} = \frac{40592}{13650} \approx 2{,}9736\]
\[SE_{\ln OR} = \sqrt{\frac{1}{a} + \frac{1}{b} + \frac{1}{c} + \frac{1}{d}} = \sqrt{\frac{1}{688} + \frac{1}{650} + \frac{1}{21} + \frac{1}{59}}\]
\[= \sqrt{0{,}001453 + 0{,}001538 + 0{,}047619 + 0{,}016949} = \sqrt{0{,}067559} \approx 0{,}2599\]
\[95\%\text{ CI}: \exp\!\left(\ln(2{,}9736) \pm 1{,}96 \times 0{,}2599\right) = \exp(1{,}0900 \pm 0{,}5094) = \left[\exp(0{,}5806);\; \exp(1{,}5994)\right]\]
\[= [1{,}787;\; 4{,}950]\]
Interval tidak mencakup 1, sehingga OR signifikan. OR > RR karena proporsi kejadian kanker cukup besar, sehingga syarat rare event tidak terpenuhi.
Frekuensi harapan di bawah \(H_0\) (\(\pi_{ij} = \pi_{i+} \cdot \pi_{+j}\)):
\[E_{11} = \frac{n_1 \cdot n_{+1}}{n} = \frac{1338 \times 709}{1418} \approx 669{,}13\]
\[E_{12} = \frac{n_1 \cdot n_{+2}}{n} = \frac{1338 \times 709}{1418} \approx 668{,}87\]
\[E_{21} = \frac{n_2 \cdot n_{+1}}{n} = \frac{80 \times 709}{1418} \approx 39{,}99\]
\[E_{22} = \frac{n_2 \cdot n_{+2}}{n} = \frac{80 \times 709}{1418} \approx 40{,}01\]
Catatan: Karena \(n_{+1} = n_{+2} = 709\) (studi case-control dengan jumlah kasus dan kontrol yang sama), \(E_{11} \approx E_{12}\) dan \(E_{21} \approx E_{22}\).
Statistik chi-square:
\[\chi^2 = \frac{(688 - 669{,}13)^2}{669{,}13} + \frac{(650 - 668{,}87)^2}{668{,}87} + \frac{(21 - 39{,}99)^2}{39{,}99} + \frac{(59 - 40{,}01)^2}{40{,}01}\]
\[= \frac{(18{,}87)^2}{669{,}13} + \frac{(-18{,}87)^2}{668{,}87} + \frac{(-18{,}99)^2}{39{,}99} + \frac{(18{,}99)^2}{40{,}01}\]
\[= \frac{356{,}08}{669{,}13} + \frac{356{,}08}{668{,}87} + \frac{360{,}62}{39{,}99} + \frac{360{,}62}{40{,}01}\]
\[= 0{,}5322 + 0{,}5323 + 9{,}0173 + 9{,}0128 = 19{,}095\]
Dengan df \(= (2-1)(2-1) = 1\), nilai kritis \(\chi^2_{0{,}05,1} = 3{,}841\). Karena \(\chi^2 = 19{,}095 > 3{,}841\), tolak \(H_0\).
a1 <- tabel1["Smoker", "Cancer (+)"]
b1 <- tabel1["Smoker", "Control (-)"]
c1 <- tabel1["Non-Smoker", "Cancer (+)"]
d1 <- tabel1["Non-Smoker", "Control (-)"]
n_smoker <- a1 + b1
n_nonsmoker <- c1 + d1
p_smoker <- a1 / n_smoker
p_nonsmoker <- c1 / n_nonsmoker
cat("Proporsi kanker pada Smoker :", round(p_smoker, 4), "\n")## Proporsi kanker pada Smoker : 0.5142
## Proporsi kanker pada Non-Smoker: 0.2625
Proporsi kanker paru pada kelompok Smoker adalah \(\hat{p}_1 \approx\) 0.5142 (sekitar 51.4%), sedangkan pada Non-Smoker adalah \(\hat{p}_2 \approx\) 0.2625 (sekitar 26.2%).
ci_smoker <- prop.test(a1, n_smoker, conf.level = 0.95)
ci_nonsmoker <- prop.test(c1, n_nonsmoker, conf.level = 0.95)
cat("95% CI Proporsi Smoker : [",
round(ci_smoker$conf.int[1], 4), ",",
round(ci_smoker$conf.int[2], 4), "]\n")## 95% CI Proporsi Smoker : [ 0.487 , 0.5413 ]
cat("95% CI Proporsi Non-Smoker: [",
round(ci_nonsmoker$conf.int[1], 4), ",",
round(ci_nonsmoker$conf.int[2], 4), "]\n")## 95% CI Proporsi Non-Smoker: [ 0.1733 , 0.3748 ]
Kedua interval tidak saling tumpang tindih, yang mengindikasikan perbedaan proporsi yang signifikan secara statistik.
Risk Difference (RD) mengukur perbedaan absolut risiko antara kedua kelompok:
\[RD = \hat{p}_1 - \hat{p}_2, \qquad SE_{RD} = \sqrt{\frac{\hat{p}_1(1-\hat{p}_1)}{n_1} + \frac{\hat{p}_2(1-\hat{p}_2)}{n_2}}, \qquad 95\%\text{ CI}: RD \pm 1{,}96 \times SE_{RD}\]
Risk Ratio (RR) mengukur perbandingan risiko relatif antar kelompok:
\[RR = \frac{\hat{p}_1}{\hat{p}_2}, \qquad SE_{\ln RR} = \sqrt{\frac{1-\hat{p}_1}{n_1 \hat{p}_1} + \frac{1-\hat{p}_2}{n_2 \hat{p}_2}}, \qquad 95\%\text{ CI}: \exp\!\left(\ln RR \pm 1{,}96 \times SE_{\ln RR}\right)\]
Odds Ratio (OR) mengukur perbandingan odds kejadian kanker antar kelompok:
\[OR = \frac{ad}{bc}, \qquad SE_{\ln OR} = \sqrt{\frac{1}{a} + \frac{1}{b} + \frac{1}{c} + \frac{1}{d}}, \qquad 95\%\text{ CI}: \exp\!\left(\ln OR \pm 1{,}96 \times SE_{\ln OR}\right)\]
# Risk Difference
RD <- p_smoker - p_nonsmoker
SE_RD <- sqrt(p_smoker * (1 - p_smoker) / n_smoker +
p_nonsmoker * (1 - p_nonsmoker) / n_nonsmoker)
CI_RD <- c(RD - 1.96 * SE_RD, RD + 1.96 * SE_RD)
cat("=== Risk Difference (RD) ===\n")## === Risk Difference (RD) ===
## RD : 0.2517
## SE(RD) : 0.0511
## 95% CI : [ 0.1516 , 0.3518 ]
# Risk Ratio
RR <- p_smoker / p_nonsmoker
SE_logRR <- sqrt((1 - p_smoker) / (n_smoker * p_smoker) +
(1 - p_nonsmoker) / (n_nonsmoker * p_nonsmoker))
CI_RR <- exp(c(log(RR) - 1.96 * SE_logRR, log(RR) + 1.96 * SE_logRR))
cat("=== Risk Ratio (RR) ===\n")## === Risk Ratio (RR) ===
## RR : 1.9589
## SE(ln RR) : 0.1893
## 95% CI : [ 1.3517 , 2.8387 ]
# Odds Ratio
OR <- (a1 * d1) / (b1 * c1)
SE_logOR <- sqrt(1/a1 + 1/b1 + 1/c1 + 1/d1)
CI_OR <- exp(c(log(OR) - 1.96 * SE_logOR, log(OR) + 1.96 * SE_logOR))
cat("=== Odds Ratio (OR) ===\n")## === Odds Ratio (OR) ===
## OR : 2.9738
## SE(ln OR) : 0.2599
## 95% CI : [ 1.7867 , 4.9495 ]
Interpretasi:
Hipotesis yang diuji:
uji_prop <- prop.test(
x = c(a1, c1),
n = c(n_smoker, n_nonsmoker),
alternative = "two.sided",
correct = FALSE
)
print(uji_prop)##
## 2-sample test for equality of proportions without continuity correction
##
## data: c(a1, c1) out of c(n_smoker, n_nonsmoker)
## X-squared = 19.129, df = 1, p-value = 1.222e-05
## alternative hypothesis: two.sided
## 95 percent confidence interval:
## 0.1516343 0.3517663
## sample estimates:
## prop 1 prop 2
## 0.5142003 0.2625000
##
## Pearson's Chi-squared test
##
## data: tabel1
## X-squared = 19.129, df = 1, p-value = 1.222e-05
##
## Frekuensi Harapan (Expected Frequencies):
## Status Kanker
## Status Merokok Cancer (+) Control (-)
## Smoker 669 669
## Non-Smoker 40 40
\[G^2 = 2 \sum_{i,j} O_{ij} \ln\!\left(\frac{O_{ij}}{E_{ij}}\right)\]
##
## Log likelihood ratio (G-test) test of independence without correction
##
## data: tabel1
## G = 19.878, X-squared df = 1, p-value = 8.254e-06
\[P = \frac{\dbinom{n_{1+}}{n_{11}} \dbinom{n_{2+}}{n_{21}}}{\dbinom{n}{n_{+1}}}\]
##
## Fisher's Exact Test for Count Data
##
## data: tabel1
## p-value = 1.476e-05
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
## 1.755611 5.210711
## sample estimates:
## odds ratio
## 2.971634
| Uji | Statistik Uji | df | p-value | Keputusan | Pendekatan |
|---|---|---|---|---|---|
| Uji Dua Proporsi | χ² = 19.1292 | 1 | 1.22e-05 | Tolak H₀ | Asimtotik |
| Chi-Square Pearson | χ² = 19.1292 | 1 | 1.22e-05 | Tolak H₀ | Asimtotik |
| Likelihood Ratio (G²) | G² = 19.878 | 1 | 8.25e-06 | Tolak H₀ | Asimtotik |
| Fisher Exact Test | — | — | 1.48e-05 | Tolak H₀ | Eksak |
Diskusi Perbandingan:
Keempat uji memberikan kesimpulan yang konsisten: seluruhnya menghasilkan \(p\)-value jauh di bawah 0,001.
mosaic(
tabel1,
shade = TRUE,
legend = TRUE,
main = "Gambar 1. Mosaic Plot: Merokok vs Kanker Paru",
labeling_args = list(
set_varnames = c(
"Status Merokok" = "Status Merokok",
"Status Kanker" = "Status Kanker"
)
)
)df_prop <- data.frame(
Kelompok = c("Smoker", "Non-Smoker"),
Proporsi = c(p_smoker, p_nonsmoker),
CI_lower = c(ci_smoker$conf.int[1], ci_nonsmoker$conf.int[1]),
CI_upper = c(ci_smoker$conf.int[2], ci_nonsmoker$conf.int[2])
)
ggplot(df_prop, aes(x = Kelompok, y = Proporsi, fill = Kelompok)) +
geom_bar(stat = "identity", width = 0.45, alpha = 0.85) +
geom_errorbar(
aes(ymin = CI_lower, ymax = CI_upper),
width = 0.12, linewidth = 0.8
) +
scale_fill_manual(values = c("#E74C3C", "#2980B9")) +
labs(
title = "Gambar 2. Proporsi Kanker Paru dengan 95% CI",
x = "Status Merokok",
y = "Proporsi Kanker Paru"
) +
theme_minimal(base_size = 13) +
theme(legend.position = "none")Mosaic plot menunjukkan sel Smoker–Cancer (+) berwarna biru (lebih besar dari harapan) dan sel Non-Smoker–Cancer (+) berwarna merah (lebih kecil dari harapan), mengonfirmasi asosiasi positif antara merokok dan kanker paru.
Berdasarkan seluruh analisis, terdapat hubungan yang signifikan secara statistik dan substantif antara kebiasaan merokok dan kejadian kanker paru:
Data berikut menggambarkan distribusi identifikasi partai politik berdasarkan gender dalam suatu survei terhadap 2450 responden.
tabel2 <- matrix(
c(495, 272, 590,
330, 265, 498),
nrow = 2,
byrow = TRUE,
dimnames = list(
"Gender" = c("Female", "Male"),
"Partai" = c("Democrat", "Republican", "Independent")
)
)
tabel2_tampil <- addmargins(tabel2)
rownames(tabel2_tampil) <- c("Female", "Male", "Total")
colnames(tabel2_tampil) <- c("Democrat", "Republican", "Independent", "Total")
kable(tabel2_tampil,
caption = "Tabel 3. Tabel Kontingensi 2x3: Gender dan Identifikasi Partai Politik") |>
kable_styling(bootstrap_options = c("striped", "hover", "bordered"),
full_width = FALSE, position = "center") |>
row_spec(3, bold = TRUE, background = "#f5f5f5") |>
column_spec(5, bold = TRUE)| Democrat | Republican | Independent | Total | |
|---|---|---|---|---|
| Female | 495 | 272 | 590 | 1357 |
| Male | 330 | 265 | 498 | 1093 |
| Total | 825 | 537 | 1088 | 2450 |
Frekuensi harapan di bawah hipotesis independensi dihitung sebagai:
\[E_{ij} = \frac{n_{i+} \cdot n_{+j}}{n}\]
di mana \(n_{i+}\) adalah total baris ke-\(i\) dan \(n_{+j}\) adalah total kolom ke-\(j\).
## Frekuensi Harapan (Expected Frequencies):
## Partai
## Gender Democrat Republican Independent
## Female 456.95 297.43 602.62
## Male 368.05 239.57 485.38
| Democrat | Republican | Independent | |
|---|---|---|---|
| Female | 456.95 | 297.43 | 602.62 |
| Male | 368.05 | 239.57 | 485.38 |
Semua frekuensi harapan jauh lebih besar dari 5, sehingga asumsi uji chi-square terpenuhi dengan baik.
Untuk tabel \(r \times c\), statistik chi-square berdistribusi \(\chi^2\) dengan derajat bebas \((r-1)(c-1)\). Pada tabel 2×3, df = \((2-1)(3-1) = 2\).
\[\chi^2 = \sum_{i=1}^{r} \sum_{j=1}^{c} \frac{(O_{ij} - E_{ij})^2}{E_{ij}}\]
##
## Pearson's Chi-squared test
##
## data: tabel2
## X-squared = 12.569, df = 2, p-value = 0.001865
\(\chi^2\) = 12.5693, df = 2, \(p\)-value = 0.0019. Karena \(p < 0{,}05\), tolak \(H_0\). Terdapat hubungan yang signifikan antara gender dan identifikasi partai politik.
Uji chi-square keseluruhan hanya memberitahu apakah ada asosiasi, tetapi tidak menjelaskan dari mana asosiasi itu berasal. Residual digunakan untuk mengidentifikasi sel mana yang paling menyimpang dari harapan independensi.
Residual Pearson mengukur simpangan tiap sel:
\[r_{ij} = \frac{O_{ij} - E_{ij}}{\sqrt{E_{ij}}}\]
Standardized Residual (Adjusted Residual) mengoreksi residual Pearson untuk variabilitas marginalnya, sehingga dapat langsung dibandingkan dengan distribusi \(N(0,1)\):
\[d_{ij} = \frac{O_{ij} - E_{ij}}{\sqrt{E_{ij}(1-p_{i+})(1-p_{+j})}}\]
Sel dengan \(|d_{ij}| > 2\) dianggap berkontribusi signifikan terhadap nilai chi-square.
## Residual Pearson:
## Partai
## Gender Democrat Republican Independent
## Female 1.7801 -1.4747 -0.5140
## Male -1.9834 1.6431 0.5728
##
## Standardized Residual (Adjusted):
## Partai
## Gender Democrat Republican Independent
## Female 3.2724 -2.4986 -1.0322
## Male -3.2724 2.4986 1.0322
| Democrat | Republican | Independent | Tipe | |
|---|---|---|---|---|
| Female | 1.780 | -1.475 | -0.514 | Pearson |
| Male | -1.983 | 1.643 | 0.573 | Pearson |
| Female1 | 3.272 | -2.499 | -1.032 | Standardized |
| Male1 | -3.272 | 2.499 | 1.032 | Standardized |
Interpretasi Residual:
Uji chi-square keseluruhan pada tabel 2×3 (df = 2) dapat diuraikan menjadi dua uji chi-square pada tabel 2×2 yang ortogonal, masing-masing berderajat bebas 1:
Jika partisi dilakukan dengan benar, berlaku sifat aditivitas:
\[\chi^2_{\text{total}} \approx \chi^2_{\text{P1}} + \chi^2_{\text{P2}}\]
# Partisi 1: Democrat vs Republican
tab_p1 <- tabel2[, c("Democrat", "Republican")]
chi_p1 <- chisq.test(tab_p1, correct = FALSE)
cat("=== Partisi 1: Democrat vs Republican ===\n")## === Partisi 1: Democrat vs Republican ===
## Partai
## Gender Democrat Republican Sum
## Female 495 272 767
## Male 330 265 595
## Sum 825 537 1362
##
## Pearson's Chi-squared test
##
## data: tab_p1
## X-squared = 11.555, df = 1, p-value = 0.0006758
# Partisi 2: (Democrat + Republican) vs Independent
dem_rep <- rowSums(tabel2[, c("Democrat", "Republican")])
indep <- tabel2[, "Independent"]
tab_p2 <- cbind("Dem+Rep" = dem_rep, "Independent" = indep)
chi_p2 <- chisq.test(tab_p2, correct = FALSE)
cat("\n=== Partisi 2: (Democrat + Republican) vs Independent ===\n")##
## === Partisi 2: (Democrat + Republican) vs Independent ===
## Dem+Rep Independent Sum
## Female 767 590 1357
## Male 595 498 1093
## Sum 1362 1088 2450
##
## Pearson's Chi-squared test
##
## data: tab_p2
## X-squared = 1.0654, df = 1, p-value = 0.302
chi2_total <- uji_chi2$statistic
chi2_p1 <- chi_p1$statistic
chi2_p2 <- chi_p2$statistic
chi2_sum <- chi2_p1 + chi2_p2
cat("Chi-Square keseluruhan (df=2) :", round(chi2_total, 4), "\n")## Chi-Square keseluruhan (df=2) : 12.5693
## Partisi 1 (df=1) : 11.5545
## Partisi 2 (df=1) : 1.0654
## Total Partisi 1 + 2 : 12.62
| Uji | Chi-Square | df | p-value |
|---|---|---|---|
| Chi-Square Keseluruhan (2x3) | 12.5693 | 2 | 0.0019 |
| Partisi 1: Democrat vs Republican | 11.5545 | 1 | 0.0007 |
| Partisi 2: (Dem+Rep) vs Independent | 1.0654 | 1 | 0.3020 |
| Total Partisi (P1 + P2) | 12.6200 | 2 | NA |
Interpretasi Partisi:
kontribusi <- (uji_chi2$observed - uji_chi2$expected)^2 / uji_chi2$expected
cat("Kontribusi tiap sel terhadap Chi-Square:\n")## Kontribusi tiap sel terhadap Chi-Square:
## Partai
## Gender Democrat Republican Independent
## Female 3.1686 2.1746 0.2642
## Male 3.9339 2.6999 0.3281
##
## Persentase kontribusi tiap sel (%):
## Partai
## Gender Democrat Republican Independent
## Female 25.21 17.30 2.10
## Male 31.30 21.48 2.61
cat("\nVerifikasi: Total =", round(sum(kontribusi), 4),
"| Chi-Square =", round(uji_chi2$statistic, 4), "\n")##
## Verifikasi: Total = 12.5693 | Chi-Square = 12.5693
Sel Female–Democrat dan Male–Democrat menyumbang porsi terbesar dari nilai chi-square, menegaskan bahwa perbedaan gender paling menonjol pada kecenderungan mengidentifikasi diri sebagai Democrat. Perempuan secara proporsional lebih banyak di kelompok Democrat, sementara laki-laki lebih banyak di kelompok Republican.
mosaic(tabel2,
shade = TRUE,
legend = TRUE,
main = "Gambar 3. Mosaic Plot: Gender vs Identifikasi Partai Politik",
labeling_args = list(set_varnames = c(
Gender = "Gender",
Partai = "Identifikasi Partai"
)))resid_df_plot <- as.data.frame(as.table(resid_std))
colnames(resid_df_plot) <- c("Gender", "Partai", "Residual")
ggplot(resid_df_plot, aes(x = Partai, y = Gender, fill = Residual)) +
geom_tile(color = "white", linewidth = 1.2) +
geom_text(aes(label = round(Residual, 2)), size = 5, fontface = "bold") +
scale_fill_gradient2(low = "#E74C3C", mid = "white", high = "#2980B9",
midpoint = 0, name = "Std.\nResidual") +
labs(title = "Gambar 4. Heatmap Standardized Residual",
subtitle = "Nilai |d| > 2 menunjukkan kontribusi signifikan",
x = "Identifikasi Partai", y = "Gender") +
theme_minimal(base_size = 13)prop_plot <- as.data.frame(prop.table(tabel2, margin = 1))
colnames(prop_plot) <- c("Gender", "Partai", "Proporsi")
prop_plot$Gender <- as.factor(prop_plot$Gender)
prop_plot$Partai <- as.factor(prop_plot$Partai)
ggplot(prop_plot, aes(x = Partai, y = Proporsi, fill = Gender)) +
geom_bar(stat = "identity", position = "dodge", width = 0.55, alpha = 0.85) +
scale_fill_manual(values = c("#E74C3C", "#3498DB")) +
scale_y_continuous(labels = scales::percent_format()) +
labs(title = "Gambar 5. Proporsi Identifikasi Partai berdasarkan Gender",
x = "Identifikasi Partai",
y = "Proporsi (dalam kelompok gender)") +
theme_minimal(base_size = 13)
Mosaic plot dan heatmap residual menunjukkan pola yang jelas: warna biru
pada Female–Democrat dan Male–Republican menandakan frekuensi lebih
besar dari harapan, sedangkan warna merah pada Female–Republican dan
Male–Democrat menandakan sebaliknya.
Berdasarkan seluruh analisis tabel kontingensi 2×3:
| Kasus | Variabel | Metode Utama | Hasil | Kesimpulan |
|---|---|---|---|---|
| Kasus 1 (2x2) | Merokok x Kanker Paru | Chi-square, Fisher, G2, Dua Proporsi | chi2 = 19.13, p < 0.001 | Merokok berkaitan signifikan dengan kanker paru |
| Kasus 2 (2x3) | Gender x Partai Politik | Chi-square, Partisi, Residual | chi2 = 12.57, p = 0.002 | Gender berkaitan signifikan dengan identifikasi partai |
Kedua kasus menunjukkan bahwa inferensi pada tabel kontingensi mampu mendeteksi dan mengkuantifikasi asosiasi antara variabel kategorikal secara komprehensif. Kombinasi antara estimasi ukuran asosiasi (RD, RR, OR), interval kepercayaan, berbagai uji hipotesis, serta analisis residual dan partisi memberikan gambaran yang lengkap — tidak hanya tentang apakah asosiasi ada, tetapi juga seberapa besar dan dari mana asosiasi itu berasal.