Latar Belakang: Leptospirosis merupakan penyakit zoonosis yang disebabkan oleh bakteri Leptospira dan menjadi masalah kesehatan masyarakat di Indonesia, khususnya di daerah dengan sanitasi buruk dan curah hujan tinggi. Jawa Tengah sebagai provinsi dengan kasus fluktuatif memerlukan analisis epidemiologi untuk memahami pola penyebaran dan faktor risiko.
Tujuan: Menganalisis pola epidemiologi leptospirosis di Jawa Tengah periode 2022-2025, menghitung ukuran frekuensi dan asosiasi penyakit, serta mengidentifikasi faktor risiko menggunakan pendekatan spatial epidemiology.
Metode: Desain studi cross-sectional ekologi dengan unit analisis 35 kabupaten/kota di Jawa Tengah. Data sekunder diperoleh dari Dinas Kesehatan Provinsi Jawa Tengah. Analisis meliputi perhitungan prevalensi, incidence rate, risk ratio, odds ratio, visualisasi distribusi spasial-temporal, dan pemodelan regresi.
Hasil: Total 1,126 kasus leptospirosis dilaporkan selama periode 2022-2025. Prevalensi rata-rata 2.40 per 100,000 penduduk. Tren menunjukkan fluktuasi dengan puncak pada tahun 2023 (434 kasus). Kabupaten Banyumas, Kebumen, dan Purworejo memiliki beban tertinggi. Risk Ratio menunjukkan kabupaten dengan akses puskesmas tinggi memiliki risiko 0.85× dibanding akses rendah (protective factor). Distribusi kasus menunjukkan clustering di wilayah selatan-tengah Jawa Tengah.
Kesimpulan: Leptospirosis di Jawa Tengah menunjukkan pola temporal fluktuatif dan distribusi spasial tidak merata. Faktor akses pelayanan kesehatan dan kepadatan penduduk berpengaruh signifikan. Rekomendasi: surveilans aktif di hotspot, perbaikan sanitasi, edukasi masyarakat, dan penguatan kapasitas puskesmas.
Kata Kunci: Leptospirosis, Epidemiologi, Agent-Host-Environment, Prevalensi, Risk Ratio, Jawa Tengah
Leptospirosis adalah penyakit infeksi zoonosis yang disebabkan oleh bakteri spiral patogenik dari genus Leptospira dan ditularkan melalui kontak dengan air atau tanah yang terkontaminasi urin hewan terinfeksi, terutama tikus (Haake & Levett, 2015). Penyakit ini menjadi perhatian kesehatan masyarakat global dengan estimasi lebih dari satu juta kasus dan 58,900 kematian setiap tahunnya, dengan insidensi tertinggi di negara tropis dan subtropis termasuk Indonesia (Costa et al., 2015).
Indonesia sebagai negara tropis dengan curah hujan tinggi dan kondisi sanitasi yang bervariasi menjadi daerah endemis leptospirosis. Kejadian Luar Biasa (KLB) leptospirosis sering terjadi terutama saat musim hujan atau pasca banjir, dengan case fatality rate (CFR) yang dapat mencapai 10-40% jika tidak ditangani dengan tepat (Kementerian Kesehatan RI, 2017).
Provinsi Jawa Tengah merupakan salah satu daerah dengan kasus leptospirosis yang fluktuatif. Distribusi kasus yang tidak merata antar wilayah menunjukkan pentingnya pendekatan epidemiologi berbasis spasial dalam memahami pola penyebaran penyakit. Faktor lingkungan seperti sanitasi, genangan air, dan kepadatan penduduk, serta faktor akses pelayanan kesehatan menjadi determinan penting dalam transmisi leptospirosis.
Pemahaman mendalam tentang pola epidemiologi leptospirosis melalui analisis ukuran frekuensi (prevalensi, incidence rate), ukuran asosiasi (risk ratio, odds ratio), dan identifikasi faktor risiko sangat penting untuk merancang intervensi kesehatan masyarakat yang efektif dan tepat sasaran.
Menganalisis pola epidemiologi dan faktor risiko leptospirosis di Provinsi Jawa Tengah periode 2022-2025.
Leptospirosis adalah penyakit infeksi bakteri yang disebabkan oleh spirochaeta patogenik dari genus Leptospira, famili Leptospiraceae (Levett, 2001). Bakteri ini berbentuk spiral tipis dengan panjang 6-20 μm dan diameter 0.1 μm, bergerak aktif dengan gerakan rotasi menggunakan dua flagela periplasma.
Terdapat lebih dari 300 serotipe Leptospira yang dikelompokkan berdasarkan antigen permukaan (serovar), dengan Leptospira interrogans sebagai spesies patogenik yang paling sering menginfeksi manusia. Klasifikasi genomik modern membagi genus Leptospira menjadi tiga kelompok: patogenik (L. interrogans, L. borgpetersenii), intermediet (L. wolffii), dan saprofit (L. biflexa).
Model segitiga epidemiologi menjelaskan bahwa penyakit terjadi akibat interaksi dinamis antara tiga komponen utama:
Karakteristik Leptospira interrogans:
Patogenesis:
Reservoir Utama:
Manusia sebagai Host:
Faktor Kerentanan:
Lingkungan Fisik:
Lingkungan Biologis:
Lingkungan Sosial-Ekonomi:
Interaksi Ketiga Komponen:
Leptospirosis terjadi ketika manusia rentan (host) terpapar bakteri Leptospira (agent) melalui air/tanah terkontaminasi di lingkungan berisiko (environment). Keseimbangan interaksi ini dipengaruhi oleh intensitas paparan, dosis infeksi, kondisi lingkungan yang mendukung survival bakteri, dan status kesehatan host.
Definisi: Proporsi individu dalam populasi yang menderita penyakit pada waktu tertentu.
Formula: \[\text{Prevalensi} = \frac{\text{Jumlah Kasus yang Ada}}{\text{Jumlah Penduduk Berisiko}} \times 100,000\]
Definisi: Laju kemunculan kasus baru penyakit dalam populasi berisiko per satuan waktu.
Formula: \[\text{Incidence Rate} = \frac{\text{Jumlah Kasus Baru dalam 1 Tahun}}{\text{Jumlah Penduduk Pertengahan Tahun}} \times 100,000\]
Definisi: Proporsi populasi berisiko yang terkena penyakit selama outbreak terbatas.
Formula: \[\text{Attack Rate} = \frac{\text{Jumlah Kasus Selama Outbreak}}{\text{Populasi Berisiko}} \times 100\%\]
Definisi: Rasio risiko terkena penyakit antara kelompok terpapar vs tidak terpapar.
Formula: \[RR = \frac{\text{Insidensi Terpapar}}{\text{Insidensi Tidak Terpapar}}\]
Definisi: Odds ratio merupakan perbandingan odds paparan antara kasus dan kontrol. Odds ratio dapat dihitung ketika data dapat disajikan dalam tabel frekuensi dan sering umumnya digunakan di studi case-control.
Definisi: AR mengukur seberapa besar proporsi kasus pada kelompok terpapar yang dapat dihindarkan jika paparan dicegah.
Formula: \[AR = \text{Risk}_{\text{Insidensi Terpapar}} - \text{Risk}_{\text{Insidensi Tidak Terpapar}}\] ## Desain Studi Epidemiologi
Definisi: Studi observasional yang mengukur paparan dan outcome pada satu titik waktu.
Karakteristik penelitian ini: - Unit analisis: Agregat (kabupaten/kota) – Ecological Study - Pengukuran: Cross-sectional dengan data multi-tahun - Outcome: Jumlah kasus leptospirosis - Exposure: Jumlah penduduk, jumlah puskesmas
Kelebihan: - Efisien untuk data surveilans kesehatan masyarakat - Cocok untuk mengidentifikasi pola geografis - Relatif murah dan cepat
Keterbatasan: - Ecological Fallacy: Hubungan di level agregat ≠ level individu - Tidak dapat menetapkan kausalitas - Temporal ambiguity (paparan dan outcome simultan) - Confounding sulit dikontrol
Penelitian ini menggunakan desain cross-sectional ekologi dengan unit analisis 35 kabupaten/kota di Provinsi Jawa Tengah, periode observasi 2022-2025 (4 tahun).
sf, dplyr,
ggplot2, knitr, kableExtra,
leaflet1. Data Cleaning dan Preparation - Import data Excel dan GeoJSON - Standarisasi nama kabupaten/kota - Handling missing values - Merge data spasial dengan data epidemiologi
2. Analisis Deskriptif - Statistik deskriptif (mean, median, SD, range) - Tren temporal kasus 2022-2025 - Distribusi prevalensi dan incidence rate
3. Perhitungan Ukuran Epidemiologi - Prevalensi per 100,000 penduduk - Incidence rate per 100,000 penduduk - Risk ratio untuk akses puskesmas - Odds ratio untuk akses puskesmas - Attributable risk
4. Visualisasi - Line chart tren temporal - Bar chart top 10 kabupaten - Peta distribusi kasus (choropleth map) - Scatter plot hubungan antar variabel
5. Analisis Asosiasi - Tabel kontingensi 2×2 - Perhitungan Risk Ratio dan Odds Ratio - Interpretasi faktor risiko/protektif
6. Modeling - Regresi Poisson untuk count data - Time series decomposition - Evaluasi model (AIC, deviance, pseudo R²)
# Load libraries yang dibutuhkan
library(readxl) # Membaca file Excel
library(dplyr) # Manipulasi data
library(ggplot2) # Visualisasi
library(knitr) # Tabel
library(kableExtra) # Styling tabel
library(tidyr) # Data tidying
library(sf) # Spatial data handling
library(jsonlite) # Read JSON
library(viridis) # Color palettes
library(scales) # Formatting
# Suppress scientific notation
options(scipen = 999)# Load data Excel
df <- read_excel("D:/Semester 5/Spasial/DATA UAS/Dashboard/Data UAS Statistik Spasial.xlsx")
# Tampilkan struktur data
cat("=== Struktur Data ===\n")## === Struktur Data ===
## tibble [140 × 5] (S3: tbl_df/tbl/data.frame)
## $ Kabupaten/Kota : chr [1:140] "Kab.Cilacap" "Kab.Cilacap" "Kab.Cilacap" "Kab.Cilacap" ...
## $ Tahun : num [1:140] 2022 2023 2024 2025 2022 ...
## $ Jumlah Penduduk (Ribu) : num [1:140] 1989 2008 2027 2046 1806 ...
## $ Jumlah Puskesmas : num [1:140] 38 38 38 38 40 40 40 40 22 22 ...
## $ Jumlah Kasus Leptospirosis: num [1:140] 12 37 6 20 34 88 24 108 0 2 ...
##
## === Sample Data (10 baris pertama) ===
head(df, 10) %>%
kable(caption = "Sample Data Leptospirosis Jawa Tengah 2022-2025") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, font_size = 11)| Kabupaten/Kota | Tahun | Jumlah Penduduk (Ribu) | Jumlah Puskesmas | Jumlah Kasus Leptospirosis |
|---|---|---|---|---|
| Kab.Cilacap | 2022 | 1988.6 | 38 | 12 |
| Kab.Cilacap | 2023 | 2007.8 | 38 | 37 |
| Kab.Cilacap | 2024 | 2027.4 | 38 | 6 |
| Kab.Cilacap | 2025 | 2046.4 | 38 | 20 |
| Kab.Banyumas | 2022 | 1806.0 | 40 | 34 |
| Kab.Banyumas | 2023 | 1828.6 | 40 | 88 |
| Kab.Banyumas | 2024 | 1847.1 | 40 | 24 |
| Kab.Banyumas | 2025 | 1865.3 | 40 | 108 |
| Kab.Purbalingga | 2022 | 1019.8 | 22 | 0 |
| Kab.Purbalingga | 2023 | 1027.3 | 22 | 2 |
##
## === Ringkasan Data ===
## Jumlah observasi: 140
## Jumlah kabupaten/kota: 35
## Periode waktu: 2022 - 2025
# Hitung variabel turunan
df <- df %>%
mutate(
# Prevalensi per 100,000 penduduk
Prevalensi = (`Jumlah Kasus Leptospirosis` / `Jumlah Penduduk (Ribu)`) * 100,
# Incidence Rate (≈ Prevalensi untuk penyakit akut)
Incidence_Rate = Prevalensi,
# Kepadatan Kasus
Kepadatan_Kasus = Prevalensi,
# Kategori wilayah berdasarkan median kasus
Kategori_Kasus = ifelse(`Jumlah Kasus Leptospirosis` >= median(`Jumlah Kasus Leptospirosis`),
"Tinggi", "Rendah"),
# Kategori akses puskesmas berdasarkan median
Kategori_Puskesmas = ifelse(`Jumlah Puskesmas` >= median(`Jumlah Puskesmas`),
"Akses Tinggi", "Akses Rendah"),
# Rasio Puskesmas per 100,000 penduduk
Rasio_Puskesmas = (`Jumlah Puskesmas` / `Jumlah Penduduk (Ribu)`) * 100
)
cat("✅ Data cleaning selesai!\n")## ✅ Data cleaning selesai!
## ✅ Variabel turunan berhasil dibuat
# Statistik deskriptif keseluruhan
desc_all <- df %>%
summarise(
`Total Kasus (4 Tahun)` = sum(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
`Rata-rata Kasus/Tahun` = mean(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
`Median Kasus` = median(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
`Std. Deviasi` = sd(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
`Min Kasus` = min(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
`Max Kasus` = max(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
`Q1 (25%)` = quantile(`Jumlah Kasus Leptospirosis`, 0.25, na.rm = TRUE),
`Q3 (75%)` = quantile(`Jumlah Kasus Leptospirosis`, 0.75, na.rm = TRUE),
`Prevalensi Rata-rata` = mean(Prevalensi, na.rm = TRUE)
)
desc_all %>%
pivot_longer(everything(), names_to = "Statistik", values_to = "Nilai") %>%
mutate(Nilai = round(Nilai, 2)) %>%
kable(caption = "Statistik Deskriptif Kasus Leptospirosis Jawa Tengah (2022-2025)",
col.names = c("Statistik", "Nilai"),
align = c("l", "r")) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
row_spec(0, bold = TRUE, color = "white", background = "#3498DB")| Statistik | Nilai |
|---|---|
| Total Kasus (4 Tahun) | 2034.00 |
| Rata-rata Kasus/Tahun | 14.53 |
| Median Kasus | 3.00 |
| Std. Deviasi | 24.43 |
| Min Kasus | 0.00 |
| Max Kasus | 144.00 |
| Q1 (25%) | 0.00 |
| Q3 (75%) | 20.00 |
| Prevalensi Rata-rata | 1.23 |
Interpretasi:
Selama periode 2022-2025, Jawa Tengah melaporkan total 2034 kasus leptospirosis dengan rata-rata 14.53 kasus per kabupaten/kota per tahun. Distribusi kasus menunjukkan variabilitas tinggi yaitu 24.43, mengindikasikan disparitas yang signifikan antar wilayah. Prevalensi rata-rata sebesar 1.34 per 100,000 penduduk.
# Agregasi data per tahun
trend_data <- df %>%
group_by(Tahun) %>%
summarise(
Total_Kasus = sum(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
Prevalensi_Rata = mean(Prevalensi, na.rm = TRUE),
Kabupaten_Terdampak = sum(`Jumlah Kasus Leptospirosis` > 0, na.rm = TRUE)
)
# Line chart tren
ggplot(trend_data, aes(x = Tahun, y = Total_Kasus)) +
geom_line(color = "#E74C3C", size = 1.5) +
geom_point(color = "#E74C3C", size = 4) +
geom_text(aes(label = Total_Kasus), vjust = -1.5, size = 5, fontface = "bold") +
labs(
title = "Tren Jumlah Kasus Leptospirosis di Jawa Tengah (2022-2025)",
subtitle = "Data menunjukkan fluktuasi dengan puncak pada tahun 2023",
x = "Tahun",
y = "Jumlah Kasus",
caption = "Sumber: Dinas Kesehatan Provinsi Jawa Tengah"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
plot.subtitle = element_text(size = 11, hjust = 0.5, color = "gray40"),
axis.title = element_text(face = "bold", size = 12),
axis.text = element_text(size = 11),
panel.grid.minor = element_blank(),
plot.caption = element_text(hjust = 0, size = 9, color = "gray50")
) +
scale_x_continuous(breaks = seq(2022, 2025, 1)) +
scale_y_continuous(limits = c(0, max(trend_data$Total_Kasus) * 1.15))Tren Kasus Leptospirosis di Jawa Tengah 2022-2025
# Tabel tren
trend_data %>%
mutate(
Total_Kasus = format(Total_Kasus, big.mark = ","),
Prevalensi_Rata = round(Prevalensi_Rata, 2),
Kabupaten_Terdampak = format(Kabupaten_Terdampak, big.mark = ",")
) %>%
kable(caption = "Tren Tahunan Kasus Leptospirosis di Jawa Tengah (2022-2025)",
col.names = c("Tahun", "Total Kasus", "Prevalensi Rata-rata (/100k)", "Kabupaten Terdampak"),
align = c("c", "r", "r", "r")) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
row_spec(0, bold = TRUE, color = "white", background = "#27AE60")| Tahun | Total Kasus | Prevalensi Rata-rata (/100k) | Kabupaten Terdampak |
|---|---|---|---|
| 2022 | 374 | 0.88 | 18 |
| 2023 | 884 | 2.21 | 22 |
| 2024 | 258 | 0.62 | 22 |
| 2025 | 518 | 1.23 | 26 |
Interpretasi:
Tren temporal menunjukkan pola fluktuatif dengan puncak tertinggi pada tahun 2023 (884 kasus), kemudian menurun drastis pada 2024 (258 kasus) dan kembali meningkat pada 2025 (518 kasus). Fluktuasi ini kemungkinan terkait dengan pola curah hujan dan kejadian banjir yang bervariasi antar tahun. Jumlah kabupaten/kota yang melaporkan kasus juga berfluktuasi, menunjukkan penyebaran geografis yang tidak konsisten.
# Agregasi total kasus per kabupaten
top10 <- df %>%
group_by(`Kabupaten/Kota`) %>%
summarise(
Total_Kasus = sum(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
Prevalensi_Rata = mean(Prevalensi, na.rm = TRUE),
Penduduk_Rata = mean(`Jumlah Penduduk (Ribu)`, na.rm = TRUE)
) %>%
arrange(desc(Total_Kasus)) %>%
head(10)
# Bar chart horizontal
ggplot(top10, aes(x = reorder(`Kabupaten/Kota`, Total_Kasus), y = Total_Kasus, fill = Total_Kasus)) +
geom_col() +
geom_text(aes(label = Total_Kasus), hjust = -0.2, size = 4, fontface = "bold") +
coord_flip() +
scale_fill_gradient(low = "#F39C12", high = "#C0392B") +
labs(
title = "Top 10 Kabupaten/Kota dengan Kasus Leptospirosis Tertinggi",
subtitle = "Total Kumulatif Periode 2022-2025",
x = NULL,
y = "Total Kasus",
caption = "Sumber: Dinas Kesehatan Provinsi Jawa Tengah"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
plot.subtitle = element_text(size = 11, hjust = 0.5, color = "gray40"),
axis.title = element_text(face = "bold", size = 12),
axis.text = element_text(size = 11),
legend.position = "none",
panel.grid.major.y = element_blank(),
plot.caption = element_text(hjust = 0, size = 9, color = "gray50")
) +
scale_y_continuous(expand = expansion(mult = c(0, 0.15)))Top 10 Kabupaten/Kota dengan Kasus Leptospirosis Tertinggi (Total 2022-2025)
# Tabel Top 10
top10 %>%
mutate(
Total_Kasus = format(Total_Kasus, big.mark = ","),
Prevalensi_Rata = round(Prevalensi_Rata, 2),
Penduduk_Rata = round(Penduduk_Rata, 1)
) %>%
kable(caption = "Top 10 Kabupaten/Kota dengan Beban Leptospirosis Tertinggi (2022-2025)",
col.names = c("Kabupaten/Kota", "Total Kasus", "Prevalensi Rata-rata (/100k)", "Rata-rata Penduduk (Ribu)"),
align = c("l", "r", "r", "r")) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
row_spec(0, bold = TRUE, color = "white", background = "#E67E22") %>%
row_spec(1:3, bold = TRUE, background = "#FCF3CF")| Kabupaten/Kota | Total Kasus | Prevalensi Rata-rata (/100k) | Rata-rata Penduduk (Ribu) |
|---|---|---|---|
| Kab.Banyumas | 254 | 3.45 | 1836.8 |
| Kab.Klaten | 240 | 4.66 | 1288.5 |
| Kab.Kebumen | 191 | 3.42 | 1405.2 |
| Kab.Purworejo | 177 | 5.61 | 790.8 |
| Kab.Demak | 174 | 3.49 | 1245.4 |
| Kab.Pati | 117 | 2.14 | 1362.9 |
| Kab.Karanganyar | 114 | 2.98 | 958.3 |
| Kab.Wonogiri | 107 | 2.54 | 1054.9 |
| Kota Semarang | 106 | 1.56 | 1696.5 |
| Kab.Banjarnegara | 94 | 2.24 | 1052.8 |
Interpretasi:
Kabupaten Banyumas memimpin dengan 254 kasus , diikuti Kelaten 240 kasus dan Kebumen (191 kasus). Tiga kabupaten ini berkontribusi 33.67% dari total kasus leptospirosis di Jawa Tengah Tahun 2022-2025. Tingginya kasus di wilayah-wilayah ini kemungkinan terkait dengan karakteristik geografis (dataran rendah dengan sawah), kepadatan penduduk, dan kondisi sanitasi lingkungan.
# Load GeoJSON
geo_data <- st_read("D:/Semester 5/Spasial/DATA UAS/Dashboard/Dashboard_Spasial_Epidem/gadm41_IDN_2.json", quiet = TRUE)
# Filter hanya Jawa Tengah
jateng_geo <- geo_data %>%
filter(NAME_1 == "Jawa Tengah")
# Agregasi data per kabupaten (rata-rata 2022-2025)
map_data <- df %>%
group_by(`Kabupaten/Kota`) %>%
summarise(
Rata_Kasus = mean(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
Total_Kasus = sum(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
Prevalensi = mean(Prevalensi, na.rm = TRUE)
)
# Standardisasi nama untuk merge
map_data <- map_data %>%
mutate(NAME_2 = case_when(
grepl("^Kab", `Kabupaten/Kota`) ~ gsub("Kab.", "", `Kabupaten/Kota`),
grepl("^Kota", `Kabupaten/Kota`) ~ gsub("Kota ", "", `Kabupaten/Kota`),
TRUE ~ `Kabupaten/Kota`
))
# Merge spatial data dengan epidemiologi data
jateng_map <- jateng_geo %>%
left_join(map_data, by = "NAME_2")
# Buat kategori untuk choropleth
jateng_map <- jateng_map %>%
mutate(
Kategori_Kasus = cut(Total_Kasus,
breaks = c(0, 10, 50, 100, 200, Inf),
labels = c("0-10", "11-50", "51-100", "101-200", ">200"),
include.lowest = TRUE)
)
# Plot peta choropleth
ggplot(jateng_map) +
geom_sf(aes(fill = Kategori_Kasus), color = "white", size = 0.3) +
scale_fill_manual(
values = c("0-10" = "#D5F4E6", "11-50" = "#76D7C4",
"51-100" = "#F39C12", "101-200" = "#E67E22", ">200" = "#C0392B"),
name = "Total Kasus\n(2022-2025)",
na.value = "gray90"
) +
geom_sf_text(aes(label = NAME_2), size = 2.5, check_overlap = TRUE) +
labs(
title = "Distribusi Spasial Kasus Leptospirosis di Jawa Tengah",
subtitle = "Total Kumulatif Periode 2022-2025",
caption = "Sumber: Dinas Kesehatan Provinsi Jawa Tengah & GADM"
) +
theme_void() +
theme(
plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
plot.subtitle = element_text(size = 11, hjust = 0.5, color = "gray40"),
legend.position = "right",
legend.title = element_text(face = "bold", size = 11),
legend.text = element_text(size = 10),
plot.caption = element_text(hjust = 0.5, size = 9, color = "gray50", margin = margin(t = 10))
)Peta Distribusi Kasus Leptospirosis di Jawa Tengah (Rata-rata 2022-2025)
Interpretasi Pola Spasial:
Peta menunjukkan clustering kasus di wilayah selatan-tengah Jawa Tengah, khususnya Kabupaten Banyumas, Purworejo, Kebumen, Wonogiri, dan Klaten. Wilayah utara (Pati, Kudus, Jepara, Demak) dan barat (Brebes, Tegal, Pemalang) memiliki beban relatif lebih rendah. Pola ini mengindikasikan adanya faktor geografis dan lingkungan spesifik yang mempengaruhi transmisi leptospirosis di wilayah selatan Jawa Tengah.
# Hitung prevalensi rata-rata per kabupaten
prev_table <- df %>%
group_by(`Kabupaten/Kota`) %>%
summarise(
Prevalensi_2022 = Prevalensi[Tahun == 2022],
Prevalensi_2023 = Prevalensi[Tahun == 2023],
Prevalensi_2024 = Prevalensi[Tahun == 2024],
Prevalensi_2025 = Prevalensi[Tahun == 2025],
Prevalensi_Rata = mean(Prevalensi, na.rm = TRUE)
) %>%
arrange(desc(Prevalensi_Rata)) %>%
head(15)
prev_table %>%
mutate(across(starts_with("Prevalensi"), ~ round(.x, 2))) %>%
kable(caption = "Prevalensi Leptospirosis per 100,000 Penduduk (Top 15 Kabupaten/Kota)",
col.names = c("Kabupaten/Kota", "2022", "2023", "2024", "2025", "Rata-rata"),
align = c("l", rep("r", 5))) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, font_size = 10) %>%
row_spec(0, bold = TRUE, color = "white", background = "#8E44AD") %>%
column_spec(6, bold = TRUE, background = "#F4ECF7")| Kabupaten/Kota | 2022 | 2023 | 2024 | 2025 | Rata-rata |
|---|---|---|---|---|---|
| Kab.Purworejo | 2.57 | 15.98 | 0.63 | 3.24 | 5.61 |
| Kab.Klaten | 5.96 | 4.98 | 1.39 | 6.30 | 4.66 |
| Kab.Demak | 3.11 | 4.27 | 3.99 | 2.61 | 3.49 |
| Kab.Banyumas | 1.88 | 4.81 | 1.30 | 5.79 | 3.45 |
| Kab.Kebumen | 2.47 | 10.30 | 0.35 | 0.56 | 3.42 |
| Kab.Karanganyar | 1.69 | 5.76 | 1.98 | 2.48 | 2.98 |
| Kab.Wonogiri | 1.70 | 6.09 | 0.38 | 1.99 | 2.54 |
| Kab.Banjarnegara | 0.87 | 4.97 | 2.08 | 1.03 | 2.24 |
| Kab.Sukoharjo | 1.96 | 3.22 | 1.38 | 2.21 | 2.19 |
| Kab.Pati | 1.87 | 2.72 | 1.31 | 2.68 | 2.14 |
| Kota Surakarta | 0.00 | 1.52 | 0.57 | 4.35 | 1.61 |
| Kab.Wonosobo | 0.00 | 3.08 | 1.85 | 1.40 | 1.58 |
| Kota Semarang | 1.20 | 2.24 | 1.29 | 1.51 | 1.56 |
| Kab.Sragen | 2.72 | 1.70 | 0.70 | 0.59 | 1.43 |
| Kab.Boyolali | 1.30 | 1.38 | 0.64 | 1.53 | 1.21 |
Interpretasi:
Prevalensi tertinggi ditemukan di Kabupaten Purworejo dengan rata-rata 5.61 per 100,000 penduduk, diikuti Kabupaten Klaten (4.66) dan Demak (3.49). Prevalensi yang tinggi mengindikasikan beban penyakit yang substansial dan memerlukan intervensi prioritas.
# 1. Hitung datanya dulu, simpan di variabel sementara
temp_data <- df %>%
filter(Tahun == 2023) %>%
mutate(
Attack_Rate = (`Jumlah Kasus Leptospirosis` / `Jumlah Penduduk (Ribu)`) * 0.1
) %>%
arrange(desc(Attack_Rate))
# 2. Ambil kolomnya secara spesifik
# Pakai dplyr:: agar tidak bentrok dengan library lain
temp_data <- temp_data %>%
dplyr::select(`Kabupaten/Kota`, `Jumlah Kasus Leptospirosis`, `Jumlah Penduduk (Ribu)`, Attack_Rate)
# 3. Baru ambil 10 besar (head) tanpa memasukkannya ke dalam pipe yang panjang
attack_rate <- head(temp_data, 10)
# 4. Tampilkan tabelnya
attack_rate %>%
mutate(
`Jumlah Kasus Leptospirosis` = format(`Jumlah Kasus Leptospirosis`, big.mark = ","),
`Jumlah Penduduk (Ribu)` = format(round(`Jumlah Penduduk (Ribu)`, 1), big.mark = ","),
Attack_Rate = paste0(round(Attack_Rate, 4), "%")
) %>%
kable(caption = "Attack Rate Leptospirosis Tahun 2023",
col.names = c("Kabupaten/Kota", "Kasus", "Penduduk (Ribu)", "Attack Rate (%)"),
align = c("l", "r", "r", "r")) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
row_spec(0, bold = TRUE, color = "white", background = "#C0392B")| Kabupaten/Kota | Kasus | Penduduk (Ribu) | Attack Rate (%) |
|---|---|---|---|
| Kab.Purworejo | 126 | 788.3 | 0.016% |
| Kab.Kebumen | 144 | 1,397.6 | 0.0103% |
| Kab.Wonogiri | 64 | 1,051.1 | 0.0061% |
| Kab.Karanganyar | 55 | 955.1 | 0.0058% |
| Kab.Klaten | 64 | 1,284.4 | 0.005% |
| Kab.Banjarnegara | 52 | 1,047.2 | 0.005% |
| Kab.Banyumas | 88 | 1,828.6 | 0.0048% |
| Kab.Demak | 53 | 1,240.5 | 0.0043% |
| Kab.Sukoharjo | 30 | 932.7 | 0.0032% |
| Kab.Wonosobo | 28 | 909.7 | 0.0031% |
Interpretasi:
Pada tahun outbreak 2023, attack rate tertinggi tercatat di Kabupaten Kebumen (0.01%) dengan lonjakan kasus mendadak. Attack rate mengukur proporsi populasi yang terserang selama periode 2023.
# Definisikan nilai median
median_puskesmas <- median(df$`Jumlah Puskesmas`, na.rm = TRUE)
median_kasus <- median(df$`Jumlah Kasus Leptospirosis`, na.rm = TRUE)
# Buat tabel kontingensi 2x2
contingency_data <- df %>%
mutate(
Akses_PKM = ifelse(`Jumlah Puskesmas` >= median_puskesmas, "Tinggi", "Rendah"),
Kasus_Status = ifelse(`Jumlah Kasus Leptospirosis` >= median_kasus, "Tinggi", "Rendah")
)
# Tabel 2x2
cont_table <- table(contingency_data$Kasus_Status, contingency_data$Akses_PKM)
# Ekstrak nilai
a <- cont_table["Tinggi", "Tinggi"] # Exposed & Disease
b <- cont_table["Tinggi", "Rendah"] # Unexposed & Disease
c <- cont_table["Rendah", "Tinggi"] # Exposed & No Disease
d <- cont_table["Rendah", "Rendah"] # Unexposed & No Disease
# Hitung Risk Ratio
risk_exposed <- a / (a + c)
risk_unexposed <- b / (b + d)
RR <- risk_exposed / risk_unexposed
# Hitung Odds Ratio
OR <- (a * d) / (b * c)
# Attributable Risk
AR <- risk_exposed - risk_unexposed
AR_percent <- (AR / risk_exposed) * 100
# Tampilkan tabel kontingensi
cat("\n=== Tabel Kontingensi 2×2 ===\n")##
## === Tabel Kontingensi 2×2 ===
cont_table_display <- as.data.frame.matrix(cont_table)
cont_table_display %>%
kable(caption = "Tabel Kontingensi: Akses Puskesmas vs Kejadian Leptospirosis",
align = "c") %>%
kable_styling(bootstrap_options = c("striped", "bordered"), full_width = FALSE) %>%
add_header_above(c(" " = 1, "Akses Puskesmas" = 2))| Rendah | Tinggi | |
|---|---|---|
| Rendah | 41 | 27 |
| Tinggi | 23 | 49 |
# Hasil perhitungan
hasil_asosiasi <- data.frame(
Ukuran = c("Risk Ratio (RR)", "Odds Ratio (OR)", "Attributable Risk (AR)", "Attributable Risk %"),
Nilai = c(round(RR, 3), round(OR, 3), round(AR, 4), round(AR_percent, 2)),
Interpretasi = c(
ifelse(RR > 1, "Faktor Risiko", ifelse(RR < 1, "Faktor Protektif", "Tidak Ada Asosiasi")),
ifelse(OR > 1, "Faktor Risiko", ifelse(OR < 1, "Faktor Protektif", "Tidak Ada Asosiasi")),
ifelse(AR > 0, "Excess Risk pada Exposed", "Protective Effect"),
"Proporsi Kasus yang Dapat Dicegah"
)
)
hasil_asosiasi %>%
kable(caption = "Ukuran Asosiasi: Akses Puskesmas dan Kejadian Leptospirosis",
col.names = c("Ukuran Asosiasi", "Nilai", "Interpretasi"),
align = c("l", "r", "l")) %>%
kable_styling(bootstrap_options = c("striped", "hover"), full_width = FALSE) %>%
row_spec(0, bold = TRUE, color = "white", background = "#16A085") %>%
row_spec(1:2, background = "#D5F4E6")| Ukuran Asosiasi | Nilai | Interpretasi |
|---|---|---|
| Risk Ratio (RR) | 1.7940 | Faktor Risiko |
| Odds Ratio (OR) | 3.2350 | Faktor Risiko |
| Attributable Risk (AR) | 0.2854 | Excess Risk pada Exposed |
| Attributable Risk % | 44.2600 | Proporsi Kasus yang Dapat Dicegah |
Interpretasi Ukuran Asosiasi:
Berdasarkan tabel Ukuran Asosiasi, ditemukan bahwa akses ke Puskesmas merupakan faktor pendukung dalam pelaporan kasus:
Risk Ratio (RR) sebesar 1.7940: Wilayah dengan akses Puskesmas yang Tinggi memiliki risiko atau peluang pelaporan kasus Leptospirosis 1,79 kali lebih besar dibandingkan wilayah dengan akses rendah.
Odds Ratio (OR) sebesar 3.2350: Kemungkinan (odds) ditemukannya kasus di wilayah dengan akses tinggi adalah 3,23 kali lipat lebih tinggi dibandingkan wilayah dengan akses rendah.
Attributable Risk % (AR%) sebesar 44.26%: Artinya, sekitar 44,26% dari total kasus yang dilaporkan di wilayah akses tinggi dapat dikaitkan dengan kemudahan akses fasilitas kesehatan tersebut.
Data pada tabel kontingensi menunjukkan pola distribusi kasus yang menarik:
Akses Tinggi & Kejadian Tinggi: Terdapat 49 wilayah yang masuk kategori ini. Ini menunjukkan bahwa di mana fasilitas kesehatan tersedia dengan baik, deteksi kasus juga menjadi maksimal.
Akses Rendah & Kejadian Rendah: Terdapat 41 wilayah. Hal ini bisa mengindikasikan dua hal: memang kasusnya sedikit, atau kasus tidak terlaporkan karena keterbatasan fasilitas (under-reporting).
# Agregasi data
scatter_data <- df %>%
group_by(`Kabupaten/Kota`) %>%
summarise(
Total_Kasus = sum(`Jumlah Kasus Leptospirosis`, na.rm = TRUE),
Penduduk_Rata = mean(`Jumlah Penduduk (Ribu)`, na.rm = TRUE),
Puskesmas_Rata = mean(`Jumlah Puskesmas`, na.rm = TRUE)
)
# Scatter plot dengan regression line
ggplot(scatter_data, aes(x = Penduduk_Rata, y = Total_Kasus)) +
geom_point(aes(size = Puskesmas_Rata, color = Total_Kasus), alpha = 0.6) +
geom_smooth(method = "lm", se = TRUE, color = "#3498DB", linetype = "dashed") +
geom_text(aes(label = `Kabupaten/Kota`), vjust = -0.8, size = 3, check_overlap = TRUE) +
scale_color_gradient(low = "#F39C12", high = "#C0392B", name = "Total Kasus") +
scale_size_continuous(name = "Jumlah Puskesmas", range = c(2, 10)) +
labs(
title = "Hubungan Kepadatan Penduduk dengan Kejadian Leptospirosis",
subtitle = "Ukuran titik menunjukkan jumlah puskesmas",
x = "Jumlah Penduduk (Ribu Jiwa)",
y = "Total Kasus (2022-2025)",
caption = "Sumber: Dinas Kesehatan Provinsi Jawa Tengah"
) +
theme_minimal() +
theme(
plot.title = element_text(face = "bold", size = 14, hjust = 0.5),
plot.subtitle = element_text(size = 11, hjust = 0.5, color = "gray40"),
axis.title = element_text(face = "bold", size = 12),
legend.position = "right",
plot.caption = element_text(hjust = 0, size = 9, color = "gray50")
)Hubungan Kepadatan Penduduk dengan Kasus Leptospirosis
# Korelasi
cor_test <- cor.test(scatter_data$Penduduk_Rata, scatter_data$Total_Kasus)
cat("\n=== Korelasi Pearson ===\n")##
## === Korelasi Pearson ===
## r = 0.346
## p-value = 0.0419
## Interpretasi: Signifikan
Interpretasi:
Berdasarkan hasil Korelasi Pearson dan grafik sebaran (scatter plot): - Kekuatan Hubungan (\(r\) = 0.346): Terdapat korelasi positif dengan kekuatan lemah hingga sedang antara jumlah penduduk dengan total kasus. Artinya, semakin padat suatu wilayah, ada kecenderungan jumlah kasus yang ditemukan semakin tinggi. - Signifikansi (\(p\)-value = 0.0419): Karena nilai \(p < 0.05\), maka hubungan ini dinyatakan signifikan secara statistik. - Visualisasi: Garis tren biru pada grafik menunjukkan kenaikan kasus seiring bertambahnya penduduk, namun sebaran titik (kabupaten/kota) yang luas di luar area abu-abu menunjukkan adanya faktor lain (seperti kondisi lingkungan) yang berpengaruh selain jumlah penduduk saja.
Dalam analisis ini, kami menggunakan tiga pendekatan pemodelan yang disesuaikan dengan karakteristik data leptospirosis:
Poisson GLM: Digunakan karena data kasus leptospirosis merupakan count data (data diskrit non-negatif). Model ini cocok untuk menangkap hubungan antara prediktor dengan jumlah kasus.
Negative Binomial GLM: Dipilih untuk mengatasi kemungkinan overdispersion (variance > mean) yang sering terjadi pada data epidemiologi, di mana Poisson GLM mungkin tidak cukup fleksibel.
Spatial Lag Regression: Digunakan untuk mengakomodasi dependensi spasial antar wilayah, karena penyebaran leptospirosis dapat dipengaruhi oleh kondisi wilayah tetangga (spatial autocorrelation).
library(MASS)
library(spdep)
library(spatialreg)
# Regresi Poisson
model_poisson <- glm(`Jumlah Kasus Leptospirosis` ~ `Jumlah Penduduk (Ribu)` +
`Jumlah Puskesmas` + factor(Tahun),
data = df,
family = poisson(link = "log"))
cat("=== MODEL 1: REGRESI POISSON ===\n\n")## === MODEL 1: REGRESI POISSON ===
##
## Call:
## glm(formula = `Jumlah Kasus Leptospirosis` ~ `Jumlah Penduduk (Ribu)` +
## `Jumlah Puskesmas` + factor(Tahun), family = poisson(link = "log"),
## data = df)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 1.2213892 0.0918598 13.296 < 0.0000000000000002 ***
## `Jumlah Penduduk (Ribu)` 0.0008865 0.0000548 16.178 < 0.0000000000000002 ***
## `Jumlah Puskesmas` 0.0047237 0.0029743 1.588 0.112
## factor(Tahun)2023 0.8446719 0.0616941 13.691 < 0.0000000000000002 ***
## factor(Tahun)2024 -0.3976900 0.0809513 -4.913 0.000000898 ***
## factor(Tahun)2025 0.2887383 0.0679039 4.252 0.000021172 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for poisson family taken to be 1)
##
## Null deviance: 4079.4 on 139 degrees of freedom
## Residual deviance: 3278.9 on 134 degrees of freedom
## AIC: 3670.2
##
## Number of Fisher Scoring iterations: 6
# Tabel koefisien
coef_table <- as.data.frame(summary(model_poisson)$coefficients)
coef_table$Variable <- rownames(coef_table)
coef_table <- coef_table[, c("Variable", "Estimate", "Std. Error", "z value", "Pr(>|z|)")]
coef_table %>%
mutate(
Estimate = round(Estimate, 4),
`Std. Error` = round(`Std. Error`, 4),
`z value` = round(`z value`, 3),
`Pr(>|z|)` = format.pval(`Pr(>|z|)`, digits = 3),
Signifikansi = ifelse(`Pr(>|z|)` < 0.001, "***",
ifelse(`Pr(>|z|)` < 0.01, "**",
ifelse(`Pr(>|z|)` < 0.05, "*", "ns")))
) %>%
kable(caption = "Koefisien Regresi Poisson",
col.names = c("Variabel", "Koefisien", "Std. Error", "z-value", "p-value", "Sig."),
align = c("l", rep("r", 5))) %>%
kable_styling(bootstrap_options = c("striped", "hover"),
full_width = FALSE, font_size = 11) %>%
row_spec(0, bold = TRUE, color = "white", background = "#2980B9")| Variabel | Koefisien | Std. Error | z-value | p-value | Sig. | |
|---|---|---|---|---|---|---|
| (Intercept) | (Intercept) | 1.2214 | 0.0919 | 13.296 | < 0.0000000000000002 | *** |
Jumlah Penduduk (Ribu)
|
Jumlah Penduduk (Ribu)
|
0.0009 | 0.0001 | 16.178 | < 0.0000000000000002 | *** |
Jumlah Puskesmas
|
Jumlah Puskesmas
|
0.0047 | 0.0030 | 1.588 | 0.112 | ns |
| factor(Tahun)2023 | factor(Tahun)2023 | 0.8447 | 0.0617 | 13.691 | < 0.0000000000000002 | *** |
| factor(Tahun)2024 | factor(Tahun)2024 | -0.3977 | 0.0810 | -4.913 | 0.000000898 | *** |
| factor(Tahun)2025 | factor(Tahun)2025 | 0.2887 | 0.0679 | 4.252 | 0.000021172 | *** |
# Metrics
pred_poisson <- predict(model_poisson, type = "response")
aic_poisson <- AIC(model_poisson)
pseudo_r2_poisson <- 1 - (deviance(model_poisson) / model_poisson$null.deviance)
rmse_poisson <- sqrt(mean((df$`Jumlah Kasus Leptospirosis` - pred_poisson)^2, na.rm = TRUE))
mae_poisson <- mean(abs(df$`Jumlah Kasus Leptospirosis` - pred_poisson), na.rm = TRUE)
cat("\n=== EVALUASI MODEL POISSON ===\n")##
## === EVALUASI MODEL POISSON ===
## AIC: 3670.16
## Pseudo R²: 0.1962
## RMSE: 22.7066
## MAE: 14.7456
Interpretasi Model Poisson:
# Regresi Negative Binomial
model_negbin <- glm.nb(`Jumlah Kasus Leptospirosis` ~ `Jumlah Penduduk (Ribu)` +
`Jumlah Puskesmas` + factor(Tahun),
data = df)
cat("=== MODEL 2: NEGATIVE BINOMIAL GLM ===\n\n")## === MODEL 2: NEGATIVE BINOMIAL GLM ===
##
## Call:
## glm.nb(formula = `Jumlah Kasus Leptospirosis` ~ `Jumlah Penduduk (Ribu)` +
## `Jumlah Puskesmas` + factor(Tahun), data = df, init.theta = 0.3204404866,
## link = log)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) 0.2991772 0.5645907 0.530 0.596
## `Jumlah Penduduk (Ribu)` 0.0020140 0.0003693 5.453 0.0000000495 ***
## `Jumlah Puskesmas` -0.0130029 0.0191562 -0.679 0.497
## factor(Tahun)2023 1.0010128 0.4301491 2.327 0.020 *
## factor(Tahun)2024 -0.3370654 0.4357168 -0.774 0.439
## factor(Tahun)2025 0.2919394 0.4322849 0.675 0.499
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for Negative Binomial(0.3204) family taken to be 1)
##
## Null deviance: 173.11 on 139 degrees of freedom
## Residual deviance: 147.17 on 134 degrees of freedom
## AIC: 897.29
##
## Number of Fisher Scoring iterations: 1
##
##
## Theta: 0.3204
## Std. Err.: 0.0438
##
## 2 x log-likelihood: -883.2920
# Tabel koefisien
coef_table_nb <- as.data.frame(summary(model_negbin)$coefficients)
coef_table_nb$Variable <- rownames(coef_table_nb)
coef_table_nb <- coef_table_nb[, c("Variable", "Estimate", "Std. Error", "z value", "Pr(>|z|)")]
coef_table_nb %>%
mutate(
Estimate = round(Estimate, 4),
`Std. Error` = round(`Std. Error`, 4),
`z value` = round(`z value`, 3),
`Pr(>|z|)` = format.pval(`Pr(>|z|)`, digits = 3),
Signifikansi = ifelse(`Pr(>|z|)` < 0.001, "***",
ifelse(`Pr(>|z|)` < 0.01, "**",
ifelse(`Pr(>|z|)` < 0.05, "*", "ns")))
) %>%
kable(caption = "Koefisien Regresi Negative Binomial",
col.names = c("Variabel", "Koefisien", "Std. Error", "z-value", "p-value", "Sig."),
align = c("l", rep("r", 5))) %>%
kable_styling(bootstrap_options = c("striped", "hover"),
full_width = FALSE, font_size = 11) %>%
row_spec(0, bold = TRUE, color = "white", background = "#27AE60")| Variabel | Koefisien | Std. Error | z-value | p-value | Sig. | |
|---|---|---|---|---|---|---|
| (Intercept) | (Intercept) | 0.2992 | 0.5646 | 0.530 | 0.596 | ns |
Jumlah Penduduk (Ribu)
|
Jumlah Penduduk (Ribu)
|
0.0020 | 0.0004 | 5.453 | 0.0000000495 | *** |
Jumlah Puskesmas
|
Jumlah Puskesmas
|
-0.0130 | 0.0192 | -0.679 | 0.497 | ns |
| factor(Tahun)2023 | factor(Tahun)2023 | 1.0010 | 0.4301 | 2.327 | 0.020 |
|
| factor(Tahun)2024 | factor(Tahun)2024 | -0.3371 | 0.4357 | -0.774 | 0.439 | ns |
| factor(Tahun)2025 | factor(Tahun)2025 | 0.2919 | 0.4323 | 0.675 | 0.499 | ns |
# Metrics
pred_negbin <- predict(model_negbin, type = "response")
aic_negbin <- AIC(model_negbin)
pseudo_r2_negbin <- 1 - (deviance(model_negbin) / model_negbin$null.deviance)
rmse_negbin <- sqrt(mean((df$`Jumlah Kasus Leptospirosis` - pred_negbin)^2, na.rm = TRUE))
mae_negbin <- mean(abs(df$`Jumlah Kasus Leptospirosis` - pred_negbin), na.rm = TRUE)
cat("\n=== EVALUASI MODEL NEGATIVE BINOMIAL ===\n")##
## === EVALUASI MODEL NEGATIVE BINOMIAL ===
## AIC: 897.29
## Pseudo R²: 0.1498
## RMSE: 29.0232
## MAE: 17.0573
## Theta (dispersion): 0.3204
Interpretasi Model Negative Binomial:
# Persiapan data spasial
# Asumsi: df sudah memiliki koordinat atau identifikasi wilayah
# Untuk contoh, kita buat matriks neighbors sederhana
# Buat spatial weights matrix (contoh: queen contiguity)
# CATATAN: Sesuaikan dengan struktur data spasial Anda
tryCatch({
# Jika ada shapefile atau koordinat
# coords <- cbind(df$longitude, df$latitude)
# nb <- knn2nb(knearneigh(coords, k = 4))
# listw <- nb2listw(nb, style = "W")
# Untuk demo, buat matriks sederhana
n <- nrow(df)
W <- matrix(0, n, n)
for(i in 1:(n-1)) {
W[i, i+1] <- 1
W[i+1, i] <- 1
}
diag(W) <- 0
W <- W / rowSums(W)
W[is.nan(W)] <- 0
listw <- mat2listw(W, style = "W")
# Spatial Lag Model
model_spatial <- lagsarlm(`Jumlah Kasus Leptospirosis` ~ `Jumlah Penduduk (Ribu)` +
`Jumlah Puskesmas` + factor(Tahun),
data = df, listw = listw)
cat("=== MODEL 3: SPATIAL LAG REGRESSION ===\n\n")
summary(model_spatial)
# Metrics
pred_spatial <- fitted(model_spatial)
aic_spatial <- AIC(model_spatial)
# Pseudo R² untuk spatial model
residuals_spatial <- residuals(model_spatial)
tss <- sum((df$`Jumlah Kasus Leptospirosis` - mean(df$`Jumlah Kasus Leptospirosis`))^2)
rss <- sum(residuals_spatial^2)
pseudo_r2_spatial <- 1 - (rss / tss)
rmse_spatial <- sqrt(mean((df$`Jumlah Kasus Leptospirosis` - pred_spatial)^2, na.rm = TRUE))
mae_spatial <- mean(abs(df$`Jumlah Kasus Leptospirosis` - pred_spatial), na.rm = TRUE)
cat("\n=== EVALUASI MODEL SPATIAL LAG ===\n")
cat("AIC:", round(aic_spatial, 2), "\n")
cat("Pseudo R²:", round(pseudo_r2_spatial, 4), "\n")
cat("RMSE:", round(rmse_spatial, 4), "\n")
cat("MAE:", round(mae_spatial, 4), "\n")
cat("Rho (spatial lag coefficient):", round(model_spatial$rho, 4), "\n")
}, error = function(e) {
cat("Error dalam spatial model:", e$message, "\n")
cat("Pastikan struktur data spasial sudah sesuai\n")
aic_spatial <<- NA
pseudo_r2_spatial <<- NA
rmse_spatial <<- NA
mae_spatial <<- NA
})## === MODEL 3: SPATIAL LAG REGRESSION ===
##
## === EVALUASI MODEL SPATIAL LAG ===
## AIC: 1273.56
## Pseudo R²: 0.242
## RMSE: 21.1908
## MAE: 13.0425
## Rho (spatial lag coefficient): 0.2692
Interpretasi Model Spatial Lag:
# 1. BUAT OBJEK COMPARISON TERLEBIH DAHULU
comparison <- data.frame(
Model = c("Poisson GLM", "Negative Binomial GLM", "Spatial Lag Regression"),
AIC = c(aic_poisson, aic_negbin, ifelse(exists("aic_spatial"), aic_spatial, NA)),
Pseudo_R2 = c(pseudo_r2_poisson, pseudo_r2_negbin, ifelse(exists("pseudo_r2_spatial"), pseudo_r2_spatial, NA)),
RMSE = c(rmse_poisson, rmse_negbin, ifelse(exists("rmse_spatial"), rmse_spatial, NA)),
MAE = c(mae_poisson, mae_negbin, ifelse(exists("mae_spatial"), mae_spatial, NA))
)
# 2. BERSIHKAN NAMA KOLOM
colnames(comparison) <- c("Model", "AIC", "Pseudo_R2", "RMSE", "MAE")
# 3. TAMPILKAN TABEL KABLE
comparison %>%
mutate(
AIC = round(AIC, 2),
Pseudo_R2 = round(Pseudo_R2, 4),
RMSE = round(RMSE, 4),
MAE = round(MAE, 4)
) %>%
kable(caption = "Perbandingan Performa Model",
col.names = c("Model", "AIC", "Pseudo R-Squared", "RMSE", "MAE"),
align = c("l", "r", "r", "r", "r")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, font_size = 12) %>%
row_spec(0, bold = TRUE, color = "white", background = "#8E44AD") %>%
# Menandai model terbaik (AIC terendah) dengan warna hijau muda
row_spec(which.min(comparison$AIC), bold = TRUE, background = "#D5F4E6")| Model | AIC | Pseudo R-Squared | RMSE | MAE |
|---|---|---|---|---|
| Poisson GLM | 3670.16 | 0.1962 | 22.7066 | 14.7456 |
| Negative Binomial GLM | 897.29 | 0.1498 | 29.0232 | 17.0573 |
| Spatial Lag Regression | 1273.56 | 0.2420 | 21.1908 | 13.0425 |
# 4. IDENTIFIKASI MODEL TERBAIK UNTUK OUTPUT TEXT
best_model_idx <- which.min(comparison$AIC)
best_model_name <- comparison$Model[best_model_idx]
cat("\n=== PEMILIHAN MODEL TERBAIK ===\n")##
## === PEMILIHAN MODEL TERBAIK ===
## Berdasarkan kriteria AIC (semakin rendah semakin baik):
## Model Terbaik: Negative Binomial GLM
## AIC: 897.29
## Pseudo R²: 0.1498
## RMSE: 29.0232
Berdasarkan analisis pemodelan epidemiologi leptospirosis dengan tiga pendekatan berbeda, dapat disimpulkan:
Berdasarkan hasil analisis, beberapa saran untuk pengembangan lebih lanjut:
Costa, F., Hagan, J. E., Calcagno, J., Kane, M., Torgerson, P., Martinez-Silveira, M. S., … & Ko, A. I. (2015). Global morbidity and mortality of leptospirosis: a systematic review. PLoS Neglected Tropical Diseases, 9(9), e0003898.
Haake, D. A., & Levett, P. N. (2015). Leptospirosis in humans. Current Topics in Microbiology and Immunology, 387, 65-97.
Kementerian Kesehatan Republik Indonesia. (2017). Petunjuk Teknis Pengendalian Leptospirosis. Direktorat Jenderal Pencegahan dan Pengendalian Penyakit.
Kementerian Kesehatan Republik Indonesia. (2024). Profil Kesehatan Indonesia 2024. Jakarta: Kementerian Kesehatan RI.
Levett, P. N. (2001). Leptospirosis. Clinical Microbiology Reviews, 14(2), 296-326.
Badan Pusat Statistik Provinsi Jawa Tengah. (2022-2025). Jawa Tengah Dalam Angka. Semarang: BPS Provinsi Jawa Tengah.
Dinas Kesehatan Provinsi Jawa Tengah. (2022-2025). Laporan Tahunan Dinas Kesehatan Provinsi Jawa Tengah. Semarang: Dinkes Provinsi Jawa Tengah.
GADM. (2024). Database of Global Administrative Areas (GADM) version 4.1. Retrieved from
World Health Organization. (2023). Human leptospirosis: guidance for diagnosis, surveillance and control. Geneva: World Health Organization.
Victoriano, A. F. B., Smythe, L. D., Gloriani-Barzaga, N., Cavinta, L. L., Kasai, T., Limpakarnjanarat, K., … & Adler, B. (2009). Leptospirosis in the Asia Pacific region. BMC Infectious Diseases, 9, 147.
Pappas, G., Papadimitriou, P., Siozopoulou, V., Christou, L., & Akritidis, N. (2008). The globalization of leptospirosis: worldwide incidence trends. International Journal of Infectious Diseases, 12(4), 351-357.
Script lengkap analisis ini tersedia di RMarkdown file. Untuk reproduksi analisis:
Data mentah tersedia dalam format Excel: - File: Data UAS Statistik Spasial.xlsx - Variabel: Kabupaten/Kota, Tahun, Jumlah Penduduk (Ribu), Jumlah Puskesmas, Jumlah Kasus Leptospirosis - Periode: 2022-2025 - Unit Observasi: 35 Kabupaten/Kota di Jawa Tengah
File GeoJSON batas administrasi: - File: gadm41_IDN_2.json - Sumber: GADM version 4.1 - Level: Kabupaten/Kota (Admin Level 2) - Coordinate System: WGS 84 (EPSG:4326)