Analisis Data Kategori (Categorical Data Analysis) adalah sekumpulan metode statistik yang dirancang khusus untuk menganalisis data yang diukur pada skala nominal atau ordinal, di mana setiap observasi dikelompokkan ke dalam kategori-kategori yang bersifat diskret dan tidak kontinu.
Berbeda dengan analisis data kontinu yang menggunakan mean, variansi, atau distribusi normal, analisis data kategori menggunakan frekuensi, proporsi, dan probabilitas sebagai dasar inferensi statistik. Metode-metode utama dalam analisis data kategori meliputi:
Variabel kategori memiliki karakteristik yang membedakannya dari variabel kontinu:
| Karakteristik | Penjelasan |
|---|---|
| Diskret | Nilai hanya berupa kategori tertentu, tidak ada nilai di antara dua kategori |
| Tidak Terukur Secara Numerik | Nilai tidak memiliki jarak (interval) yang bermakna secara matematis |
| Skala Nominal | Kategori tidak memiliki urutan alami (contoh: jenis kelamin, agama) |
| Skala Ordinal | Kategori memiliki urutan alami, tetapi jarak antar kategori tidak sama (contoh: tingkat pendidikan, tingkat kepuasan) |
| Ringkasan dengan Frekuensi | Dideskripsikan dengan frekuensi dan proporsi, bukan rata-rata |
Analisis data kategori digunakan secara luas di berbagai bidang keilmuan:
1. Bidang Kesehatan Masyarakat Meneliti apakah ada hubungan antara kebiasaan konsumsi gula berlebih (ya/tidak) dengan kejadian diabetes tipe 2 (ya/tidak) pada populasi dewasa.
2. Bidang Pendidikan Menganalisis apakah metode pembelajaran (daring/luring/hybrid) berpengaruh terhadap kelulusan tepat waktu (lulus tepat waktu/tidak) mahasiswa.
3. Bidang Sosiologi Menguji apakah terdapat hubungan antara tingkat pendidikan ibu (SD/SMP/SMA/Perguruan Tinggi) dengan status gizi balita (normal/stunting/wasting).
4. Bidang Ekonomi Memeriksa asosiasi antara kepemilikan kartu kredit (ya/tidak) dengan keputusan membeli secara impulsif (ya/tidak) pada konsumen ritel.
Tabel Kontingensi (Contingency Table atau Cross-tabulation Table) adalah suatu tabel yang merangkum distribusi frekuensi bersama dari dua atau lebih variabel kategori secara simultan. Tabel ini memperlihatkan bagaimana observasi tersebar di setiap kombinasi kategori dari variabel-variabel yang diamati.
Tabel kontingensi yang melibatkan dua variabel dengan masing-masing \(r\) baris dan \(c\) kolom disebut tabel kontingensi \(r \times c\). Kasus paling sederhana adalah tabel \(2 \times 2\) yang melibatkan dua variabel biner.
Secara umum, struktur tabel kontingensi \(r \times c\) adalah sebagai berikut:
| \(Y = 1\) | \(Y = 2\) | \(\cdots\) | \(Y = c\) | Total Baris | |
|---|---|---|---|---|---|
| \(X = 1\) | \(n_{11}\) | \(n_{12}\) | \(\cdots\) | \(n_{1c}\) | \(n_{1\bullet}\) |
| \(X = 2\) | \(n_{21}\) | \(n_{22}\) | \(\cdots\) | \(n_{2c}\) | \(n_{2\bullet}\) |
| \(\vdots\) | \(\vdots\) | \(\vdots\) | \(\ddots\) | \(\vdots\) | \(\vdots\) |
| \(X = r\) | \(n_{r1}\) | \(n_{r2}\) | \(\cdots\) | \(n_{rc}\) | \(n_{r\bullet}\) |
| Total Kolom | \(n_{\bullet 1}\) | \(n_{\bullet 2}\) | \(\cdots\) | \(n_{\bullet c}\) | \(n\) |
Keterangan:
Distribusi Bersama (Joint Distribution) menggambarkan probabilitas bahwa dua variabel secara bersamaan mengambil nilai-nilai tertentu.
Secara formal, joint probability didefinisikan sebagai:
\[\pi_{ij} = P(X = i, Y = j)\]
Ditaksir dari data sampel sebagai:
\[\hat{\pi}_{ij} = \frac{n_{ij}}{n}\]
dengan syarat:
\[\sum_{i=1}^{r} \sum_{j=1}^{c} \pi_{ij} = 1\]
Joint distribution memberikan gambaran lengkap tentang sebaran bersama dua variabel kategori dalam suatu populasi.
Distribusi Marginal (Marginal Distribution) adalah distribusi probabilitas untuk satu variabel, diperoleh dengan menjumlahkan (memarjinalkan) probabilitas bersama atas semua nilai variabel lainnya.
Marginal distribution untuk baris (variabel X):
\[\pi_{i\bullet} = P(X = i) = \sum_{j=1}^{c} \pi_{ij}\]
Marginal distribution untuk kolom (variabel Y):
\[\pi_{\bullet j} = P(Y = j) = \sum_{i=1}^{r} \pi_{ij}\]
Distribusi marginal memberikan informasi tentang distribusi masing-masing variabel secara terpisah, tanpa memperhatikan variabel lainnya.
Probabilitas Bersyarat (Conditional Probability) adalah probabilitas suatu kejadian terjadi, dengan syarat bahwa kejadian lain telah diketahui terjadi.
Probabilitas bersyarat Y = j diberikan X = i:
\[P(Y = j \mid X = i) = \frac{P(X = i, Y = j)}{P(X = i)} = \frac{\pi_{ij}}{\pi_{i\bullet}}\]
Probabilitas bersyarat X = i diberikan Y = j:
\[P(X = i \mid Y = j) = \frac{\pi_{ij}}{\pi_{\bullet j}}\]
Jika \(P(Y = j \mid X = i) = P(Y = j)\) untuk semua \(i\) dan \(j\), maka variabel \(X\) dan \(Y\) dikatakan independen (saling bebas).
Misalkan sebuah penelitian mengamati hubungan antara kebiasaan membaca buku (Rutin/Tidak Rutin) dan kemampuan berpikir kritis (Tinggi/Rendah) pada 200 mahasiswa:
# Membuat tabel kontingensi 2x2
tabel_buku <- matrix(c(80, 20, 40, 60),
nrow = 2, byrow = TRUE)
rownames(tabel_buku) <- c("Rutin Membaca", "Tidak Rutin")
colnames(tabel_buku) <- c("Berpikir Kritis Tinggi", "Berpikir Kritis Rendah")
# Tampilkan tabel frekuensi
cat("=== Tabel Kontingensi: Kebiasaan Membaca vs Berpikir Kritis ===\n\n")#> === Tabel Kontingensi: Kebiasaan Membaca vs Berpikir Kritis ===
#> Berpikir Kritis Tinggi Berpikir Kritis Rendah Sum
#> Rutin Membaca 80 20 100
#> Tidak Rutin 40 60 100
#> Sum 120 80 200
Interpretasi distribusi:
#> === Joint Distribution (Proporsi Bersama) ===
#> Berpikir Kritis Tinggi Berpikir Kritis Rendah Sum
#> Rutin Membaca 0.4 0.1 0.5
#> Tidak Rutin 0.2 0.3 0.5
#> Sum 0.6 0.4 1.0
#>
#> === Marginal Distribution Baris (P(X=i)) ===
#> Rutin Membaca Tidak Rutin
#> 0.5 0.5
#>
#> === Marginal Distribution Kolom (P(Y=j)) ===
#> Berpikir Kritis Tinggi Berpikir Kritis Rendah
#> 0.6 0.4
#>
#> === Conditional Probability P(Y | X) ===
#> Berpikir Kritis Tinggi Berpikir Kritis Rendah
#> Rutin Membaca 0.8 0.2
#> Tidak Rutin 0.4 0.6
Ukuran Asosiasi (Measures of Association) adalah statistik yang mengukur kekuatan dan arah hubungan antara dua variabel kategori. Ukuran ini sangat penting dalam epidemiologi, ilmu kesehatan, dan ilmu sosial untuk menginterpretasikan besarnya hubungan antar variabel.
Pada tabel kontingensi \(2 \times 2\), notasi sel adalah sebagai berikut:
| Outcome (+) | Outcome (−) | Total | |
|---|---|---|---|
| Exposed (+) | \(a\) | \(b\) | \(a + b\) |
| Not Exposed (−) | \(c\) | \(d\) | \(c + d\) |
| Total | \(a + c\) | \(b + d\) | \(n\) |
Odds adalah rasio antara peluang suatu kejadian terjadi dengan peluang kejadian tersebut tidak terjadi.
Odds untuk kelompok Exposed: \[\text{Odds}_{\text{exposed}} = \frac{a / (a+b)}{b / (a+b)} = \frac{a}{b}\]
Odds untuk kelompok Not Exposed: \[\text{Odds}_{\text{unexposed}} = \frac{c / (c+d)}{d / (c+d)} = \frac{c}{d}\]
Interpretasi: Odds = 3 berarti kejadian 3 kali lebih mungkin terjadi dibandingkan tidak terjadi.
Odds Ratio adalah rasio antara odds pada kelompok terpapar (exposed) dibandingkan dengan odds pada kelompok tidak terpapar (unexposed).
\[\text{OR} = \frac{\text{Odds}_{\text{exposed}}}{\text{Odds}_{\text{unexposed}}} = \frac{a/b}{c/d} = \frac{ad}{bc}\]
Interpretasi: - \(\text{OR} = 1\): Tidak ada asosiasi antara paparan dan outcome - \(\text{OR} > 1\): Paparan meningkatkan risiko outcome (faktor risiko) - \(\text{OR} < 1\): Paparan menurunkan risiko outcome (faktor protektif)
Relative Risk (atau Risk Ratio) adalah rasio antara risiko (probabilitas) terjadinya outcome pada kelompok terpapar dibandingkan pada kelompok tidak terpapar.
\[\text{RR} = \frac{P(\text{Outcome} \mid \text{Exposed})}{P(\text{Outcome} \mid \text{Not Exposed})} = \frac{a/(a+b)}{c/(c+d)}\]
Interpretasi: - \(\text{RR} = 1\): Risiko sama di kedua kelompok - \(\text{RR} > 1\): Kelompok terpapar memiliki risiko lebih tinggi - \(\text{RR} < 1\): Kelompok terpapar memiliki risiko lebih rendah
Catatan: RR hanya dapat dihitung pada studi kohort atau cross-sectional. Pada studi case-control, gunakan OR sebagai pendekatan.
Latar Belakang: Penelitian ini menginvestigasi apakah anak-anak yang tinggal di dekat kawasan industri (paparan polusi udara tinggi) memiliki risiko kejadian asma yang lebih besar dibandingkan anak-anak yang tinggal di kawasan perumahan (paparan rendah).
Desain: Studi kohort prospektif, n = 300 anak usia 6–12 tahun, observasi selama 2 tahun.
Data yang diperoleh dari penelitian adalah sebagai berikut:
| Asma (+) | Asma (−) | Total | |
|---|---|---|---|
| Dekat Industri | 75 | 75 | 150 |
| Jauh dari Industri | 30 | 120 | 150 |
| Total | 105 | 195 | 300 |
Sehingga: \(a = 75\), \(b = 75\), \(c = 30\), \(d = 120\), \(n = 300\)
Peluang Asma pada anak dekat industri:
\[P(\text{Asma} \mid \text{Dekat Industri}) = \frac{a}{a + b} = \frac{75}{75 + 75} = \frac{75}{150} = 0{,}50\]
Peluang Asma pada anak jauh dari industri:
\[P(\text{Asma} \mid \text{Jauh dari Industri}) = \frac{c}{c + d} = \frac{30}{30 + 120} = \frac{30}{150} = 0{,}20\]
Odds Asma pada kelompok Dekat Industri:
\[\text{Odds}_{\text{dekat}} = \frac{a}{b} = \frac{75}{75} = 1{,}00\]
Artinya: Anak di dekat industri memiliki peluang asma sama besar dengan peluang tidak asma (1:1).
Odds Asma pada kelompok Jauh dari Industri:
\[\text{Odds}_{\text{jauh}} = \frac{c}{d} = \frac{30}{120} = 0{,}25\]
Artinya: Anak jauh dari industri, peluang asma 4 kali lebih kecil dari peluang tidak asma.
\[\text{OR} = \frac{\text{Odds}_{\text{dekat}}}{\text{Odds}_{\text{jauh}}} = \frac{a/b}{c/d} = \frac{ad}{bc} = \frac{75 \times 120}{75 \times 30} = \frac{9000}{2250} = 4{,}00\]
Menghitung Relative Risk:
\[\text{RR} = \frac{a/(a+b)}{c/(c+d)} = \frac{75/150}{30/150} = \frac{0{,}50}{0{,}20} = 2{,}50\]
Kesimpulan Perhitungan Manual:
# ============================================================
# DATA: Paparan Polusi Udara vs Kejadian Asma pada Anak
# ============================================================
data_asma <- matrix(c(75, 75, 30, 120),
nrow = 2,
byrow = TRUE)
rownames(data_asma) <- c("Dekat Industri", "Jauh dari Industri")
colnames(data_asma) <- c("Asma (+)", "Asma (-)")
cat("=== Tabel Kontingensi: Paparan Polusi vs Asma ===\n\n")#> === Tabel Kontingensi: Paparan Polusi vs Asma ===
#> Asma (+) Asma (-) Sum
#> Dekat Industri 75 75 150
#> Jauh dari Industri 30 120 150
#> Sum 105 195 300
# ----- Menghitung Odds -----
a <- data_asma[1, 1] # Dekat Industri & Asma
b <- data_asma[1, 2] # Dekat Industri & Tidak Asma
c_val <- data_asma[2, 1] # Jauh dari Industri & Asma
d <- data_asma[2, 2] # Jauh dari Industri & Tidak Asma
odds_dekat <- a / b
odds_jauh <- c_val / d
OR_manual <- (a * d) / (b * c_val)
RR_manual <- (a / (a + b)) / (c_val / (c_val + d))
cat("=== Hasil Perhitungan Ukuran Asosiasi ===\n\n")#> === Hasil Perhitungan Ukuran Asosiasi ===
#> Odds (Dekat Industri) : 1.0000
#> Odds (Jauh dari Industri) : 0.2500
#> Odds Ratio (OR) : 4.0000
#> Relative Risk (RR) : 2.5000
# ----- Menggunakan fungsi fisher.test untuk OR & CI -----
cat("\n=== Odds Ratio dengan Confidence Interval (Fisher's Exact Test) ===\n\n")#>
#> === Odds Ratio dengan Confidence Interval (Fisher's Exact Test) ===
#>
#> Fisher's Exact Test for Count Data
#>
#> data: data_asma
#> p-value = 7.201e-08
#> alternative hypothesis: true odds ratio is not equal to 1
#> 95 percent confidence interval:
#> 2.329297 6.928419
#> sample estimates:
#> odds ratio
#> 3.980505
#> === Uji Chi-Square: Independensi Paparan Polusi vs Asma ===
#>
#> Pearson's Chi-squared test with Yates' continuity correction
#>
#> data: data_asma
#> X-squared = 28.366, df = 1, p-value = 1.004e-07
#>
#> === Frekuensi Harapan (Expected Frequencies) ===
#> Asma (+) Asma (-)
#> Dekat Industri 52.5 97.5
#> Jauh dari Industri 52.5 97.5
par(mfrow = c(1, 2), mar = c(5, 4, 4, 2) + 0.1)
# --- Plot 1: Grouped Bar Chart ---
barplot(t(prop.table(data_asma, margin = 1)),
beside = FALSE,
col = c("#2e86c1", "#aed6f1"),
main = "Proporsi Kejadian Asma\nBerdasarkan Kelompok Paparan",
ylab = "Proporsi",
ylim = c(0, 1.1),
legend.text = colnames(data_asma),
args.legend = list(x = "topright", bty = "n", cex = 0.9),
border = "white")
box()
# --- Plot 2: Odds Ratio Plot ---
or_val <- OR_manual
ci_lower <- exp(log(or_val) - 1.96 * sqrt(1/a + 1/b + 1/c_val + 1/d))
ci_upper <- exp(log(or_val) + 1.96 * sqrt(1/a + 1/b + 1/c_val + 1/d))
plot(1, or_val,
xlim = c(0.5, 1.5),
ylim = c(0, 8),
xaxt = "n",
xlab = "",
ylab = "Odds Ratio",
main = "Odds Ratio dengan\n95% Confidence Interval",
pch = 18, cex = 2.5, col = "#1a5276")
abline(h = 1, lty = 2, col = "red", lwd = 2)
segments(1, ci_lower, 1, ci_upper, col = "#1a5276", lwd = 2)
segments(0.95, ci_lower, 1.05, ci_lower, col = "#1a5276", lwd = 2)
segments(0.95, ci_upper, 1.05, ci_upper, col = "#1a5276", lwd = 2)
text(1, or_val + 0.4,
labels = sprintf("OR = %.2f\n95%% CI: [%.2f, %.2f]", or_val, ci_lower, ci_upper),
cex = 0.9, col = "#1a5276", font = 2)#> ============================================================
#> RINGKASAN HASIL ANALISIS DATA KATEGORI
#> Studi: Paparan Polusi Udara vs Asma Anak
#> ============================================================
#> Jumlah Sampel Total : 300 anak
#> Prevalensi Asma (Overall) : 35.0%
#> Prevalensi - Dekat Industri : 50.0%
#> Prevalensi - Jauh Industri : 20.0%
#> Odds Ratio (OR) : 4.0000
#> 95% CI untuk OR : [2.3963, 6.6769]
#> Relative Risk (RR) : 2.5000
#> Chi-Square Statistic (X²) : 28.3663
#> Derajat Kebebasan (df) : 1
#> p-value : 0.000000
#> ============================================================
Dari 300 anak yang diamati, terdapat 105 anak (35%) yang didiagnosis menderita asma. Proporsi asma pada anak yang tinggal dekat kawasan industri adalah 50% (75 dari 150 anak), jauh lebih tinggi dibandingkan anak yang tinggal jauh dari industri sebesar 20% (30 dari 150 anak).
Probabilitas bersyarat menunjukkan bahwa:
Perbedaan substansial ini mengindikasikan adanya hubungan antara paparan polusi dan kejadian asma.
Relative Risk = 2,50: Risiko terkena asma pada anak dekat kawasan industri adalah 2,5 kali lebih tinggi dibandingkan anak jauh dari industri. Ini berarti paparan polusi udara secara substansial meningkatkan risiko asma pada anak.
Berdasarkan hasil uji chi-square:
| Temuan | Nilai | Makna Praktis |
|---|---|---|
| Prevalensi asma - dekat industri | 50% | Sangat tinggi, perlu intervensi segera |
| Prevalensi asma - jauh industri | 20% | Referensi baseline populasi sehat |
| Odds Ratio | 4,00 | Paparan polusi merupakan faktor risiko kuat |
| Relative Risk | 2,50 | Risiko meningkat 2,5 kali lipat akibat paparan |
| p-value | < 0,05 | Hubungan signifikan secara statistik |
Kesimpulan Akhir:
Hasil analisis data kategori dengan tabel kontingensi \(2 \times 2\) secara konsisten menunjukkan bahwa paparan polusi udara dari kawasan industri memiliki asosiasi positif yang signifikan dengan kejadian asma pada anak. Nilai OR = 4,00 dan RR = 2,50, dikonfirmasi oleh uji chi-square yang signifikan (\(p < 0{,}05\)), mengindikasikan bahwa anak-anak yang tinggal dekat kawasan industri berisiko jauh lebih tinggi untuk menderita asma.
Temuan ini memiliki implikasi penting bagi kebijakan kesehatan lingkungan, khususnya dalam pengaturan zonasi pemukiman di sekitar kawasan industri dan program pengendalian polusi udara untuk melindungi kesehatan anak.
Laporan ini dibuat menggunakan R Markdown. Seluruh perhitungan dan visualisasi dihasilkan secara reproducible menggunakan R.
#> Dibuat dengan R versi: R version 4.5.1 (2025-06-13 ucrt)
#> Tanggal render: 10 April 2026
Laporan ini menyajikan analisis inferensi statistik pada tabel kontingensi dua arah menggunakan pendekatan data kategorik. Terdapat dua kasus yang dianalisis:
Analisis dilakukan menggunakan berbagai metode inferensi kategorik, meliputi estimasi proporsi, uji dua proporsi, uji chi-square, uji likelihood ratio, Fisher exact test, serta analisis residual dan partisi chi-square.
# Load paket yang diperlukan
library(epitools)
library(vcd)
library(DescTools)
library(knitr)
library(kableExtra)
library(ggplot2)
library(dplyr)
library(tidyr)Data berikut menggambarkan hubungan antara kebiasaan merokok (Smoker vs Non-Smoker) dan status kanker paru (Cancer (+) vs Control (−)).
# Input data
tabel1 <- matrix(
c(688, 650, 21, 59),
nrow = 2,
byrow = TRUE,
dimnames = list(
"Status Merokok" = c("Smoker", "Non-Smoker"),
"Status Kanker" = c("Cancer (+)", "Control (-)")
)
)
# Tambahkan total baris dan kolom
tabel1_df <- as.data.frame.matrix(tabel1)
tabel1_df$Total <- rowSums(tabel1_df)
total_row <- colSums(tabel1_df)
tabel1_display <- rbind(tabel1_df, Total = total_row)
kable(tabel1_display,
caption = "Tabel Kontingensi 2×2: Merokok dan Kanker Paru",
align = "c") %>%
kable_styling(bootstrap_options = c("striped", "hover", "bordered"),
full_width = FALSE) %>%
row_spec(3, bold = TRUE, background = "#f0f0f0") %>%
column_spec(4, bold = TRUE)| Cancer (+) | Control (-) | Total | |
|---|---|---|---|
| Smoker | 688 | 650 | 1338 |
| Non-Smoker | 21 | 59 | 80 |
| Total | 709 | 709 | 1418 |
Rumus: Proporsi kejadian kanker paru pada masing-masing kelompok:
\[\hat{p}_i = \frac{n_{i,\text{Cancer}}}{n_{i,\text{Total}}}\]
n_smoker <- 1338
n_nonsmoker <- 80
x_smoker <- 688
x_nonsmoker <- 21
p_smoker <- x_smoker / n_smoker
p_nonsmoker <- x_nonsmoker / n_nonsmoker
cat("Proporsi kanker pada Smoker :", round(p_smoker, 4), "\n")#> Proporsi kanker pada Smoker : 0.5142
#> Proporsi kanker pada Non-Smoker: 0.2625
Interpretasi: Proporsi kanker paru pada kelompok perokok (= 51.42%) lebih besar dua kali lipat dibandingkan non-perokok (= 26.25%), hal tersebut mengindikasikan adanya perbedaan risiko yang substansial antara kedua kelompok.
ci_smoker <- prop.test(x_smoker, n_smoker, conf.level = 0.95)
cat("95% CI proporsi kanker - Smoker:\n")#> 95% CI proporsi kanker - Smoker:
#> [ 0.487 , 0.5413 ]
ci_nonsmoker <- prop.test(x_nonsmoker, n_nonsmoker, conf.level = 0.95)
cat("95% CI proporsi kanker - Non-Smoker:\n")#> 95% CI proporsi kanker - Non-Smoker:
#> [ 0.1733 , 0.3748 ]
Rumus:
\[RD = \hat{p}_1 - \hat{p}_2, \quad RR = \frac{\hat{p}_1}{\hat{p}_2}, \quad OR = \frac{\hat{p}_1/(1-\hat{p}_1)}{\hat{p}_2/(1-\hat{p}_2)}\]
# Menggunakan epitools
hasil_epitools <- epitab(tabel1, method = "riskratio")
hasil_or <- epitab(tabel1, method = "oddsratio")
# RD manual
RD <- p_smoker - p_nonsmoker
SE_RD <- sqrt((p_smoker*(1-p_smoker)/n_smoker) +
(p_nonsmoker*(1-p_nonsmoker)/n_nonsmoker))
CI_RD_lower <- RD - 1.96 * SE_RD
CI_RD_upper <- RD + 1.96 * SE_RD
cat("=== Risk Difference (RD) ===\n")#> === Risk Difference (RD) ===
#> RD = 0.2517
#> 95% CI: [ 0.1516 , 0.3518 ]
#> === Risk Ratio / Relative Risk (RR) ===
#> Status Kanker
#> Status Merokok Cancer (+) p0 Control (-) p1 riskratio lower
#> Smoker 688 0.5142003 650 0.4857997 1.000000 NA
#> Non-Smoker 21 0.2625000 59 0.7375000 1.518115 1.317306
#> Status Kanker
#> Status Merokok upper p.value
#> Smoker NA NA
#> Non-Smoker 1.749536 1.476303e-05
#>
#> === Odds Ratio (OR) ===
#> Status Kanker
#> Status Merokok Cancer (+) p0 Control (-) p1 oddsratio lower
#> Smoker 688 0.97038082 650 0.9167842 1.000000 NA
#> Non-Smoker 21 0.02961918 59 0.0832158 2.973773 1.786737
#> Status Kanker
#> Status Merokok upper p.value
#> Smoker NA NA
#> Non-Smoker 4.949427 1.476303e-05
Interpretasi: Berdasarkan hasil yang diperoleh, RD = 0.251, RR > 1, dan OR >> 1 yang secara konsisten menunjukkan bahwa perokok memiliki risiko dan odds terkena kanker paru yang jauh lebih besar dibandingkan non-perokok. Ketiga ukuran ini mengindikasikan asosiasi yang kuat antara kebiasaan merokok dan kejadian kanker paru.
Hipotesis: \[H_0: p_{\text{Smoker}} = p_{\text{Non-Smoker}} \quad \text{vs} \quad H_1: p_{\text{Smoker}} \neq p_{\text{Non-Smoker}}\]
uji_prop <- prop.test(
x = c(x_smoker, x_nonsmoker),
n = c(n_smoker, n_nonsmoker),
correct = FALSE
)
print(uji_prop)#>
#> 2-sample test for equality of proportions without continuity correction
#>
#> data: c(x_smoker, x_nonsmoker) out of c(n_smoker, n_nonsmoker)
#> X-squared = 19.129, df = 1, p-value = 1.222e-05
#> alternative hypothesis: two.sided
#> 95 percent confidence interval:
#> 0.1516343 0.3517663
#> sample estimates:
#> prop 1 prop 2
#> 0.5142003 0.2625000
Interpretasi: Berdasarkan hasil Uji Dua Proporsi, diperoleh p-value < 0.05, sehingga \(H_0\) ditolak dan dapat disimpulkan bahwa terdapat perbedaan proporsi kejadian kanker paru yang signifikan antara kelompok perokok dan non-perokok.
Hipotesis: \[H_0: \text{Status merokok dan kanker paru independen} \quad \text{vs} \quad H_1: \text{keduanya tidak independen}\]
\[\chi^2 = \sum \frac{(O - E)^2}{E}\]
#>
#> Pearson's Chi-squared test
#>
#> data: tabel1
#> X-squared = 19.129, df = 1, p-value = 1.222e-05
#>
#> Frekuensi Harapan (Expected):
#> Status Kanker
#> Status Merokok Cancer (+) Control (-)
#> Smoker 669 669
#> Non-Smoker 40 40
Interpretasi: Berdasarkan hasil Uji Chi-Square Independensi, diperoleh \(\chi^2\) = 19.129 (df = 1, p-value = 1.221601e-05). Karena p-value < 0.001, \(H_0\) ditolak maka dapat disimpulkan bahwa status merokok dan kejadian kanker paru terbukti tidak independen.
Rumus: \[G^2 = 2 \sum O_{ij} \ln\left(\frac{O_{ij}}{E_{ij}}\right)\]
O <- as.vector(tabel1)
E <- as.vector(uji_chi1$expected)
G2 <- 2 * sum(O * log(O / E))
df_G2 <- (nrow(tabel1) - 1) * (ncol(tabel1) - 1)
p_G2 <- pchisq(G2, df = df_G2, lower.tail = FALSE)
cat("G² (Likelihood Ratio) =", round(G2, 4), "\n")#> G² (Likelihood Ratio) = 19.878
#> df = 1
#> p-value = 8.25441e-06
Interpretasi: Berdasarkan hasil Uji Likelihood Ratio, diperoleh G² = 19.878 dengan p-value < 0.001, sehingga \(H_0\) ditolak. Hasil ini konsisten dengan uji chi-square dan memperkuat kesimpulan bahwa terdapat hubungan signifikan antara kebiasaan merokok dan kejadian kanker paru.
#>
#> Fisher's Exact Test for Count Data
#>
#> data: tabel1
#> p-value = 1.476e-05
#> alternative hypothesis: true odds ratio is not equal to 1
#> 95 percent confidence interval:
#> 1.755611 5.210711
#> sample estimates:
#> odds ratio
#> 2.971634
Interpretasi: Berdasarkan hasil Fisher Exact Test, diperoleh p-value < 0.001 dengan OR = 2.972 (95% CI: [1.756, 5.211]). Karena p-value < 0.05 dan seluruh interval kepercayaan OR > 1, dapat disimpulkan bahwa terdapat asosiasi signifikan antara kebiasaan merokok dan kejadian kanker paru.
perbandingan <- data.frame(
Metode = c("Uji Dua Proporsi", "Chi-Square", "Likelihood Ratio (G²)", "Fisher Exact Test"),
Statistik_Uji = c(round(uji_prop$statistic, 3),
round(uji_chi1$statistic, 3),
round(G2, 3),
"—"),
p_value = c(format(uji_prop$p.value, scientific=TRUE),
format(uji_chi1$p.value, scientific=TRUE),
format(p_G2, scientific=TRUE),
format(uji_fisher$p.value, scientific=TRUE)),
Keputusan = rep("Tolak H₀", 4),
Interpretasi = c(
"Proporsi kanker berbeda signifikan antar kelompok",
"Merokok & kanker tidak independen",
"Konsisten: asosiasi signifikan",
"Asosiasi kuat; OR >> 1"
)
)
kable(perbandingan,
caption = "Perbandingan Hasil Uji Statistik – Kasus 1",
align = "c") %>%
kable_styling(bootstrap_options = c("striped","hover","bordered"),
full_width = TRUE) %>%
column_spec(1, bold = TRUE)| Metode | Statistik_Uji | p_value | Keputusan | Interpretasi |
|---|---|---|---|---|
| Uji Dua Proporsi | 19.129 | 1.221601e-05 | Tolak H₀ | Proporsi kanker berbeda signifikan antar kelompok |
| Chi-Square | 19.129 | 1.221601e-05 | Tolak H₀ | Merokok & kanker tidak independen |
| Likelihood Ratio (G²) | 19.878 | 8.25441e-06 | Tolak H₀ | Konsisten: asosiasi signifikan |
| Fisher Exact Test | — | 1.476303e-05 | Tolak H₀ | Asosiasi kuat; OR >> 1 |
Ringkasan: Seluruh metode (uji dua proporsi, chi-square, likelihood ratio, dan Fisher exact test) menghasilkan keputusan yang sama: tolak H₀. Tidak ada perbedaan substantif antar metode karena ukuran sampel besar dan seluruh frekuensi harapan > 5. Fisher exact test lebih konservatif dan cocok untuk sampel kecil, namun di sini hasilnya konsisten.
par(mfrow = c(1, 2))
# Mosaic plot
mosaic(tabel1,
shade = TRUE,
legend = TRUE,
main = "Mosaic Plot: Merokok vs Kanker Paru",
labeling_args = list(set_varnames = c(
"Status Merokok" = "Status Merokok",
"Status Kanker" = "Status Kanker")))# Grafik proporsi
prop_df <- data.frame(
Kelompok = c("Smoker", "Non-Smoker"),
Proporsi = c(p_smoker, p_nonsmoker),
Lower = c(ci_smoker$conf.int[1], ci_nonsmoker$conf.int[1]),
Upper = c(ci_smoker$conf.int[2], ci_nonsmoker$conf.int[2])
)
barplot(
prop_df$Proporsi,
names.arg = prop_df$Kelompok,
col = c("#FF6A6A", "#7AC5CD"),
ylim = c(0, 0.7),
ylab = "Proporsi Kanker Paru",
main = "Proporsi Kanker Paru per Kelompok",
las = 1
)
arrows(
x0 = c(0.7, 1.9),
y0 = prop_df$Lower,
y1 = prop_df$Upper,
angle = 90, code = 3, length = 0.1, lwd = 2
)
abline(h = 0, col = "black")
par(mfrow = c(1, 1))Interpretasi Visualisasi: Mosaic plot menampilkan warna biru pada sel Smoker–Cancer(+) dan merah pada Non-Smoker–Cancer(+), mengonfirmasi asosiasi yang nyata antara kedua variabel. Grafik proporsi memperlihatkan perbedaan mencolok dengan interval kepercayaan yang tidak saling tumpang tindih, menegaskan signifikansi statistisnya.
Berdasarkan semua analisis yang telah dilakukan, terdapat bukti statistik yang sangat kuat bahwa kebiasaan merokok berhubungan dengan kejadian kanker paru. Proporsi kanker pada perokok (= 51.4%) secara signifikan lebih tinggi dibandingkan non-perokok (= 26.3%). Nilai OR yang jauh di atas 1 mengindikasikan bahwa perokok memiliki odds terkena kanker paru yang jauh lebih besar. Keempat metode uji menghasilkan p-value < 0.001 sehingga \(H_0\) (independensi) ditolak pada seluruh taraf signifikansi yang umum digunakan.
Data berikut menggambarkan hubungan antara gender dan identifikasi partai politik.
tabel2 <- matrix(
c(495, 272, 590,
330, 265, 498),
nrow = 2,
byrow = TRUE,
dimnames = list(
"Gender" = c("Female", "Male"),
"Partai" = c("Democrat", "Republican", "Independent")
)
)
tabel2_df <- as.data.frame.matrix(tabel2)
tabel2_df$Total <- rowSums(tabel2_df)
total_row2 <- colSums(tabel2_df)
tabel2_display <- rbind(tabel2_df, Total = total_row2)
kable(tabel2_display,
caption = "Tabel Kontingensi 2×3: Gender dan Partai Politik",
align = "c") %>%
kable_styling(bootstrap_options = c("striped","hover","bordered"),
full_width = FALSE) %>%
row_spec(3, bold = TRUE, background = "#f0f0f0") %>%
column_spec(5, bold = TRUE)| Democrat | Republican | Independent | Total | |
|---|---|---|---|---|
| Female | 495 | 272 | 590 | 1357 |
| Male | 330 | 265 | 498 | 1093 |
| Total | 825 | 537 | 1088 | 2450 |
Rumus: \[E_{ij} = \frac{n_{i\cdot} \times n_{\cdot j}}{n}\]
uji_chi2 <- chisq.test(tabel2, correct = FALSE)
E_df <- as.data.frame(round(uji_chi2$expected, 2))
E_df$Total <- rowSums(E_df)
E_display <- rbind(E_df, Total = colSums(E_df))
kable(E_display,
caption = "Frekuensi Harapan (Expected Frequencies)",
align = "c") %>%
kable_styling(bootstrap_options = c("striped","hover","bordered"),
full_width = FALSE) %>%
row_spec(3, bold = TRUE, background = "#f0f0f0")| Democrat | Republican | Independent | Total | |
|---|---|---|---|---|
| Female | 456.95 | 297.43 | 602.62 | 1357 |
| Male | 368.05 | 239.57 | 485.38 | 1093 |
| Total | 825.00 | 537.00 | 1088.00 | 2450 |
Semua frekuensi harapan > 5, sehingga asumsi uji chi-square terpenuhi.
Hipotesis: \[H_0: \text{Gender dan Partai Politik independen} \quad \text{vs} \quad H_1: \text{keduanya tidak independen}\]
#>
#> Pearson's Chi-squared test
#>
#> data: tabel2
#> X-squared = 12.569, df = 2, p-value = 0.001865
Interpretasi: Berdasarkan hasil Uji Chi-Square Independensi, diperoleh \(\chi^2\) = 12.569 (df = 2, p-value = 0.0019). Karena p-value < 0.05, \(H_0\) ditolak maka dapat disimpulkan bahwa gender dan identifikasi partai politik terbukti tidak independen.
Rumus:
\[\text{Residual Pearson: } r_{ij} = \frac{O_{ij} - E_{ij}}{\sqrt{E_{ij}}}\]
\[\text{Standardized Residual: } d_{ij} = \frac{O_{ij} - E_{ij}}{\sqrt{E_{ij}(1-p_{i\cdot})(1-p_{\cdot j})}}\]
# Residual Pearson
pearson_res <- (tabel2 - uji_chi2$expected) / sqrt(uji_chi2$expected)
cat("=== Residual Pearson ===\n")#> === Residual Pearson ===
#> Partai
#> Gender Democrat Republican Independent
#> Female 1.780 -1.475 -0.514
#> Male -1.983 1.643 0.573
# Standardized residual (dari chisq.test)
std_res <- uji_chi2$stdres
cat("\n=== Standardized Residual ===\n")#>
#> === Standardized Residual ===
#> Partai
#> Gender Democrat Republican Independent
#> Female 3.272 -2.499 -1.032
#> Male -3.272 2.499 1.032
res_df <- data.frame(
Sel = c("Female–Democrat","Female–Republican","Female–Independent",
"Male–Democrat","Male–Republican","Male–Independent"),
Observed = c(495, 272, 590, 330, 265, 498),
Expected = round(as.vector(t(uji_chi2$expected)), 2),
Pearson_Res = round(as.vector(t(pearson_res)), 3),
Std_Residual = round(as.vector(t(std_res)), 3),
Interpretasi = c(
"Lebih banyak dari harapan (signifikan)",
"Lebih sedikit dari harapan (signifikan)",
"Sedikit lebih banyak",
"Lebih sedikit dari harapan (signifikan)",
"Lebih banyak dari harapan (signifikan)",
"Sedikit lebih sedikit"
)
)
kable(res_df,
caption = "Residual Pearson dan Standardized Residual – Kasus 2",
align = "c") %>%
kable_styling(bootstrap_options = c("striped","hover","bordered"),
full_width = TRUE) %>%
row_spec(which(abs(res_df$Std_Residual) > 1.96),
background = "#fff3cd")| Sel | Observed | Expected | Pearson_Res | Std_Residual | Interpretasi |
|---|---|---|---|---|---|
| Female–Democrat | 495 | 456.95 | 1.780 | 3.272 | Lebih banyak dari harapan (signifikan) |
| Female–Republican | 272 | 297.43 | -1.475 | -2.499 | Lebih sedikit dari harapan (signifikan) |
| Female–Independent | 590 | 602.62 | -0.514 | -1.032 | Sedikit lebih banyak |
| Male–Democrat | 330 | 368.05 | -1.983 | -3.272 | Lebih sedikit dari harapan (signifikan) |
| Male–Republican | 265 | 239.57 | 1.643 | 2.499 | Lebih banyak dari harapan (signifikan) |
| Male–Independent | 498 | 485.38 | 0.573 | 1.032 | Sedikit lebih sedikit |
Interpretasi: Sel Female–Democrat memiliki standardized residual positif signifikan (|d| > 1.96), sedangkan Female–Republican dan Male–Democrat memiliki residual negatif signifikan. Pola ini menunjukkan bahwa wanita cenderung berafiliasi dengan Partai Demokrat, sedangkan pria cenderung ke Partai Republik.
tabel2_dem_rep <- tabel2[, c("Democrat", "Republican")]
chi_dem_rep <- chisq.test(tabel2_dem_rep, correct = FALSE)
cat("=== Partisi 1: Democrat vs Republican ===\n")#> === Partisi 1: Democrat vs Republican ===
#> Partai
#> Gender Democrat Republican
#> Female 495 272
#> Male 330 265
cat("\nChi-Square =", round(chi_dem_rep$statistic, 3),
"| df =", chi_dem_rep$parameter,
"| p-value =", round(chi_dem_rep$p.value, 4), "\n")#>
#> Chi-Square = 11.555 | df = 1 | p-value = 7e-04
tabel2_part2 <- cbind(
"Dem+Rep" = rowSums(tabel2[, c("Democrat","Republican")]),
"Independent" = tabel2[, "Independent"]
)
chi_part2 <- chisq.test(tabel2_part2, correct = FALSE)
cat("=== Partisi 2: (Democrat+Republican) vs Independent ===\n")#> === Partisi 2: (Democrat+Republican) vs Independent ===
#> Dem+Rep Independent
#> Female 767 590
#> Male 595 498
cat("\nChi-Square =", round(chi_part2$statistic, 3),
"| df =", chi_part2$parameter,
"| p-value =", round(chi_part2$p.value, 4), "\n")#>
#> Chi-Square = 1.065 | df = 1 | p-value = 0.302
chi_total <- uji_chi2$statistic
chi_p1 <- chi_dem_rep$statistic
chi_p2 <- chi_part2$statistic
chi_sum <- chi_p1 + chi_p2
partisi_df <- data.frame(
Analisis = c("Chi-Square Keseluruhan (2×3)",
"Partisi 1: Dem vs Rep",
"Partisi 2: (Dem+Rep) vs Ind",
"Jumlah Partisi 1 + 2"),
Chi_Square = round(c(chi_total, chi_p1, chi_p2, chi_sum), 3),
df = c(2, 1, 1, 2),
p_value = c(round(uji_chi2$p.value, 4),
round(chi_dem_rep$p.value, 4),
round(chi_part2$p.value, 4),
"—"),
Keputusan = c("Tolak H₀","Tolak H₀","Tidak Tolak H₀","—")
)
kable(partisi_df,
caption = "Perbandingan Partisi vs Chi-Square Keseluruhan",
align = "c") %>%
kable_styling(bootstrap_options = c("striped","hover","bordered"),
full_width = TRUE) %>%
row_spec(4, bold = TRUE, background = "#d4edda")| Analisis | Chi_Square | df | p_value | Keputusan |
|---|---|---|---|---|
| Chi-Square Keseluruhan (2×3) | 12.569 | 2 | 0.0019 | Tolak H₀ |
| Partisi 1: Dem vs Rep | 11.555 | 1 | 7e-04 | Tolak H₀ |
| Partisi 2: (Dem+Rep) vs Ind | 1.065 | 1 | 0.302 | Tidak Tolak H₀ |
| Jumlah Partisi 1 + 2 | 12.620 | 2 | — | — |
Interpretasi Partisi: Dekomposisi aditif terpenuhi karena jumlah chi-square dua partisi ≈ chi-square keseluruhan. Partisi 1 (Democrat vs Republican) signifikan (p < 0.05), sedangkan Partisi 2 ((Dem+Rep) vs Independent) tidak signifikan (p > 0.05), hal tersebut menunjukkan bahwa perbedaan gender hanya nyata pada preferensi antara dua partai utama, bukan pada pilihan Independen.
par(mfrow = c(2, 2))
# 1. Mosaic plot
mosaic(tabel2,
shade = TRUE,
legend = TRUE,
main = "Mosaic Plot: Gender vs Partai Politik")# 2. Grafik proporsi per gender
prop2 <- prop.table(tabel2, margin = 1) * 100
barplot(t(prop2),
beside = TRUE,
col = c("#104E8B", "#CD5555", "#9BCD9B"),
legend.text = colnames(tabel2),
args.legend = list(x = "topright", bty = "n"),
ylim = c(0, 60),
ylab = "Proporsi (%)",
main = "Proporsi Afiliasi Partai per Gender",
names.arg = c("Female", "Male"),
las = 1)
# 3. Heatmap standardized residual
std_res_mat <- uji_chi2$stdres
image(1:ncol(std_res_mat), 1:nrow(std_res_mat),
t(std_res_mat)[, nrow(std_res_mat):1],
col = colorRampPalette(c("#d73027","white","#4575b4"))(20),
xlab = "", ylab = "",
main = "Heatmap Standardized Residual",
axes = FALSE)
axis(1, at = 1:3, labels = colnames(std_res_mat), las = 1)
axis(2, at = 1:2, labels = rev(rownames(std_res_mat)), las = 1)
for (i in 1:nrow(std_res_mat))
for (j in 1:ncol(std_res_mat))
text(j, nrow(std_res_mat) + 1 - i,
round(std_res_mat[i, j], 2), cex = 1.1, font = 2)
box()
# 4. Grafik partisi chi-square
barplot(
c(chi_p1, chi_p2),
names.arg = c("Partisi 1\nDem vs Rep", "Partisi 2\n(D+R) vs Ind"),
col = c("#e67", "#9b59b6"),
ylab = expression(chi^2),
main = "Kontribusi Partisi terhadap Chi-Square Total",
ylim = c(0, max(chi_p1, chi_p2) * 1.3),
las = 1
)
abline(h = qchisq(0.95, df = 1), lty = 2, col = "red", lwd = 2)
legend("topright", legend = "Nilai kritis χ²(0.05, df=1)",
lty = 2, col = "red", bty = "n")
par(mfrow = c(1, 1))Interpretasi Visualisasi: Mosaic plot dan heatmap residual membuktikan bahwa sel Female–Democrat (residual positif) dan Male–Republican (residual positif) menyimpang paling jauh dari kondisi independensi. Grafik proporsi memperlihatkan wanita lebih cenderung Demokrat dan pria lebih cenderung Republik, sementara grafik partisi menunjukkan hanya Partisi 1 yang melampaui nilai kritis chi-square.
Uji chi-square keseluruhan (2×3) menghasilkan p-value < 0.05, menunjukkan bahwa gender dan identifikasi partai politik tidak independen. Analisis residual mengidentifikasi bahwa sel Female–Democrat dan Male–Republican memiliki kontribusi terbesar terhadap asosiasi tersebut. Partisi chi-square mengungkap bahwa perbedaan gender terletak terutama pada preferensi antara Demokrat dan Republik, bukan pada pilihan Independen. Dengan demikian, gender secara signifikan membedakan preferensi antara dua partai utama, tetapi tidak terlalu membedakan kecenderungan memilih jalur Independen.
ringkasan <- data.frame(
Kasus = c("Kasus 1 (2×2)", "Kasus 2 (2×3)"),
Variabel = c("Merokok vs Kanker Paru", "Gender vs Partai Politik"),
Chi_Square = c(round(uji_chi1$statistic, 3), round(uji_chi2$statistic, 3)),
df = c(uji_chi1$parameter, uji_chi2$parameter),
p_value = c(format(uji_chi1$p.value, scientific = TRUE),
round(uji_chi2$p.value, 4)),
Kesimpulan = c("Terdapat hubungan signifikan (perokok berisiko lebih tinggi)",
"Terdapat hubungan signifikan (wanita cenderung Demokrat, pria Republik)")
)
kable(ringkasan,
caption = "Ringkasan Hasil Analisis",
align = "c") %>%
kable_styling(bootstrap_options = c("striped","hover","bordered"),
full_width = TRUE) %>%
column_spec(1, bold = TRUE)| Kasus | Variabel | Chi_Square | df | p_value | Kesimpulan |
|---|---|---|---|---|---|
| Kasus 1 (2×2) | Merokok vs Kanker Paru | 19.129 | 1 | 1.221601e-05 | Terdapat hubungan signifikan (perokok berisiko lebih tinggi) |
| Kasus 2 (2×3) | Gender vs Partai Politik | 12.569 | 2 | 0.0019 | Terdapat hubungan signifikan (wanita cenderung Demokrat, pria Republik) |