ANALISIS SPASIAL DAN DETERMINAN EPIDEMIOLOGI
PENYAKIT MENINGITIS DI PROVINSI DKI JAKARTA
PERIODE TAHUN 2018–2024

Ditujukan untuk Memenuhi Nilai Mata Kuliah Epidemiologi

Dosen Pengampu:

Dr. I Gede Nyoman Mindra Jaya, S.Si., M.Si.

Disusun Oleh:

I Gusti Bagus Harya Putra (140610230010)

PROGRAM STUDI STATISTIKA
DEPARTEMEN STATISTIKA
FAKULTAS MATEMATIKA DAN ILMU PENGETAHUAN ALAM
UNIVERSITAS PADJADJARAN
JATINANGOR, KABUPATEN SUMEDANG
TAHUN 2025

ABSTRAK

Meningitis merupakan peradangan pada selaput otak dan sumsum tulang belakang yang memiliki tingkat fatalitas tinggi dan berpotensi menjadi wabah di lingkungan padat penduduk. Penelitian ini bertujuan untuk memetakan sebaran prevalensi Meningitis di DKI Jakarta (2018–2024) serta mengestimasi pengaruh faktor lingkungan (kepadatan penduduk) terhadap penyebaran penyakit menggunakan pendekatan epidemiologi spasial dan statistika inferensia. Metode yang digunakan meliputi analisis deskriptif, pemetaan penyakit (Disease Mapping), dan Regresi Data Panel. Hasil analisis spasial menunjukkan adanya variasi beban penyakit antar-wilayah dengan tren yang berfluktuasi. Berdasarkan pemodelan statistik Random Effect (Hausman p > 0.05), ditemukan bahwa Kepadatan Penduduk berpengaruh positif signifikan (p = 0.0199) terhadap tingkat prevalensi Meningitis. Selain itu, terdeteksi anomali tren waktu yang sangat signifikan pada tahun 2024 (p < 0.001), di mana terjadi lonjakan kasus yang drastis dibandingkan tahun dasar. Temuan ini menegaskan perlunya penguatan imunisasi dan perbaikan sanitasi lingkungan di wilayah padat penduduk untuk memutus rantai penularan.

Kata Kunci: Meningitis, Prevalensi, Epidemiologi Spasial, Regresi Data Panel, Kepadatan Penduduk.

BAB 1. PENDAHULUAN

1.1 Latar Belakang Masalah

Meningitis adalah inflamasi pada meningen yang membungkus otak dan sumsum tulang belakang, yang dapat disebabkan oleh bakteri, virus, atau jamur. Di wilayah urban metropolitan seperti DKI Jakarta, risiko transmisi penyakit menular (terutama yang airborne atau droplet) meningkat seiring dengan tingginya interaksi antar-individu.

Data surveilans 2018–2024 menunjukkan fluktuasi kasus yang dinamis. Tantangan utama dalam pengendalian penyakit ini adalah mengidentifikasi apakah lonjakan kasus murni disebabkan oleh faktor alamiah waktu (tren) atau didorong oleh faktor lingkungan seperti kepadatan penduduk yang ekstrem di Jakarta. Oleh karena itu, diperlukan pendekatan Epidemiologi Spasial dan Regresi Data Panel untuk memberikan bukti empiris yang kuat bagi pengambilan kebijakan kesehatan.

1.2 Rumusan Masalah

  1. Bagaimana pola tren (temporal) dan sebaran wilayah (spasial) prevalensi Meningitis di DKI Jakarta periode 2018–2024?
  2. Apakah terdapat pengaruh signifikan antara Kepadatan Penduduk terhadap peningkatan Prevalence Rate Meningitis?

1.3 Tujuan Penelitian

Penelitian ini bertujuan untuk mendeskripsikan distribusi spasial penyakit Meningitis, menganalisis tren kenaikan kasus pasca-pandemi, serta menguji hubungan kausalitas antara densitas populasi dengan tingkat penyebaran penyakit.

BAB 2. TINJAUAN PUSTAKA

2.1 Epidemiologi Meningitis

Dalam kerangka Segitiga Epidemiologi, kejadian Meningitis dipengaruhi oleh:

  • Agent: Bakteri (Neisseria meningitidis, S. pneumoniae) atau Virus.
  • Host: Manusia dengan imunitas rendah (balita, lansia).
  • Environment: Lingkungan padat hunian (crowding) yang mempermudah transmisi droplet dari karier ke individu rentan.

Ukuran frekuensi yang digunakan dalam studi ini adalah Prevalence Rate (Angka Prevalensi Periode), yang didefinisikan sebagai:

\[ \text{Prevalence Rate} = \frac{\text{Jumlah Kasus (Baru + Lama)}}{\text{Populasi Berisiko}} \times 100.000 \]

2.2 Analisis Regresi Data Panel

Data panel mengombinasikan data silang tempat (cross-section) dan runtun waktu (time-series). Model ini efektif untuk mengontrol heterogenitas antar-wilayah yang tidak teramati. Terdapat tiga model estimasi:

  1. Common Effect Model (CEM): Menggunakan OLS biasa.
  2. Fixed Effect Model (FEM): Mengasumsikan intersep berbeda tiap wilayah.
  3. Random Effect Model (REM): Mengasumsikan perbedaan antar-wilayah bersifat acak.

Pemilihan model dilakukan melalui Uji Chow, Uji Hausman, dan Uji Lagrange Multiplier.

BAB 3. METODOLOGI

3.1 Sumber Data

Studi ini menggunakan data sekunder dari Dinas Kesehatan Provinsi DKI Jakarta (Data Kasus Meningitis 2018-2024) dan BPS Provinsi DKI Jakarta (Data Penduduk dan Luas Wilayah).

3.2 Metode Analisis

Analisis dilakukan menggunakan perangkat lunak RStudio. Tahapan analisis meliputi:

  1. Visualisasi Spasial: Pemetaan prevalensi menggunakan peta kloroplet (choropleth map) untuk mengidentifikasi hotspot.
  2. Regresi Data Panel: Digunakan untuk menguji pengaruh variabel independen (Kepadatan Penduduk dan Tahun) terhadap variabel dependen (Prevalence Rate). Estimasi parameter dilakukan dengan koreksi Robust Standard Errors (Arellano) untuk mengatasi masalah heteroskedastisitas dan autokorelasi.

BAB 4. HASIL DAN PEMBAHASAN

4.1 Analisis Tren Temporal

Grafik di bawah ini menunjukkan pergerakan Prevalence Rate Meningitis di seluruh wilayah administrasi DKI Jakarta selama 7 tahun terakhir.

Gambar 4.1 Tren Prevalensi Meningitis DKI Jakarta (2018-2024)

Gambar 4.1 Tren Prevalensi Meningitis DKI Jakarta (2018-2024)

Interpretasi: Terlihat pola yang relatif landai pada periode 2018–2022, namun terjadi lonjakan ekstrem pada tahun 2024 di hampir seluruh wilayah. Hal ini mengindikasikan adanya fenomena wabah atau perbaikan sistem pencatatan pelaporan (surveillance sensitivity) yang drastis pada tahun terakhir.

4.2 Analisis Spasial (Disease Mapping)

Berikut adalah kolase peta sebaran prevalensi Meningitis dari tahun 2018 hingga 2024. Warna yang lebih gelap menunjukkan tingkat prevalensi yang lebih tinggi.

Gambar 4.2 Evolusi Spasial Prevalensi Meningitis (2018-2024)

Gambar 4.2 Evolusi Spasial Prevalensi Meningitis (2018-2024)

Interpretasi Spasial: Evolusi peta di atas memperlihatkan bahwa pada tahun-tahun awal (2018-2021), sebaran kasus relatif rendah dan tersebar acak. Namun, pada peta tahun 2024, hampir seluruh wilayah mengalami perubahan warna menjadi lebih gelap (biru tua), yang menandakan peningkatan beban penyakit secara merata di seluruh wilayah administrasi, termasuk Kepulauan Seribu (lihat inset pada peta).

4.3 Pemodelan Statistik (Regresi Data Panel)

Untuk menguji determinan penyakit secara statistik, dilakukan Regresi Data Panel. Berdasarkan Uji Hausman (p-value = 0.732 > 0.05) dan Uji Lagrange Multiplier, model yang terpilih adalah Random Effect Model (REM).

Berikut adalah ringkasan hasil estimasi model yang telah dikoreksi dengan Robust Standard Errors:

Tabel 3.1 Hasil Estimasi Random Effect (Robust SE)
Variabel Koefisien Std_Error T_Value P_Value
(Intercept) 0.4562 0.3195 1.4279 0.1624
Kepadatan Penduduk 3.8613e-05 1.6503e-05 2.3397 0.0253 *
Tahun 2019 0.1263 0.2527 0.4997 0.6205
Tahun 2020 -0.3264 0.2675 -1.2201 0.2308
Tahun 2021 -0.4541 0.2024 -2.2435 0.0315 *
Tahun 2022 -0.5049 0.2269 -2.2253 0.0328 *
Tahun 2023 -0.2219 0.2022 -1.0973 0.2802
Tahun 2024 1.2991 0.5077 2.5587 0.0151 *

Sumber: Hasil Olah Data RStudio (2025)

Pembahasan Hasil:

  1. Pengaruh Kepadatan Penduduk: Variabel Kepadatan memiliki koefisien positif dan nilai p-value 0.025 (< 0.05).
  • Kesimpulan: Secara statistik, kepadatan penduduk terbukti berpengaruh nyata meningkatkan prevalensi Meningitis. Semakin padat suatu wilayah, risiko penularan semakin tinggi.
  1. Anomali Tahun 2024: Dibandingkan tahun dasar (2018), tahun 2024 memiliki koefisien positif besar (1.299) dengan p-value 0.015.
  • Kesimpulan: Terjadi lonjakan kasus yang sangat signifikan pada tahun 2024. Sebaliknya, pada tahun 2021-2022 (era pandemi), terjadi penurunan kasus yang signifikan (koefisien negatif), kemungkinan dampak dari protokol kesehatan ketat.

BAB 5. KESIMPULAN DAN SARAN

5.1 Kesimpulan

  1. Distribusi Spasial & Temporal: Sebaran penyakit Meningitis di DKI Jakarta mengalami fluktuasi landai pada 2018-2022, namun mengalami lonjakan tajam (outbreak) pada tahun 2024 yang merata di hampir seluruh wilayah administrasi.
  2. Determinan Lingkungan: Terbukti secara statistik bahwa Kepadatan Penduduk merupakan faktor risiko utama yang memperburuk penyebaran Meningitis di Jakarta (p < 0.05). Wilayah yang lebih padat memiliki beban penyakit yang lebih tinggi.

5.2 Saran

  1. Pengendalian di Wilayah Padat: Dinas Kesehatan perlu memprioritaskan intervensi (seperti vaksinasi Meningitis atau penyuluhan kesehatan) di wilayah-wilayah dengan densitas tinggi, karena wilayah ini terbukti paling rentan secara statistik.
  2. Investigasi Lonjakan 2024: Perlu dilakukan penyelidikan epidemiologi lebih lanjut untuk mengetahui penyebab pasti lonjakan kasus di tahun 2024, apakah disebabkan oleh varian bakteri baru, penurunan imunitas pasca-pandemi, atau perbaikan sistem pelaporan.

DAFTAR PUSTAKA

  1. Badan Pusat Statistik Provinsi DKI Jakarta. (2024). Jakarta Dalam Angka 2024.
  2. Dinas Kesehatan Provinsi DKI Jakarta. (2024). Data Surveilans Penyakit Menular.
  3. Baltagi, B. H. (2013). Econometric Analysis of Panel Data. Wiley.
  4. Gordis, L. (2014). Epidemiology. Elsevier Saunders.

ACKNOWLEDGEMENT

Sebagai wujud komitmen terhadap integritas akademik, saya menyatakan bahwa dalam penyelesaian tugas UAS ini saya memanfaatkan Artificial Intelligence, yaitu ChatGPT dan Google Gemini.

Penggunaan AI tersebut dibatasi sebagai alat pendukung (assistive tool) dengan fungsi tertentu, antara lain sebagai bantuan teknis ketika menghadapi kendala penulisan kode R, khususnya pada pengembangan aplikasi R Shiny dan visualisasi peta menggunakan Leaflet, lalu sebagai asisten penulisan untuk memperbaiki struktur bahasa dan keterbacaan laporan tanpa mengubah substansi pemikiran, serta sebagai mitra diskusi dalam memvalidasi pemahaman terhadap interpretasi hasil analisis statistik, terutama pada model Random Effect dan Robust Standard Errors.

Saya menegaskan bahwa seluruh proses verifikasi data, penalaran analitis, serta penarikan kesimpulan akhir dilakukan secara mandiri dan sepenuhnya menjadi tanggung jawab saya sebagai penulis.

LAMPIRAN

Lampiran A: Dashboard Analisis Mandiri (R Shiny)

Dashboard interaktif untuk memvisualisasikan data dan peta secara real-time dapat diakses melalui: Link Dashboard Meningitis DKI Jakarta

Lampiran B: Video Paparan Project

Video presentasi yang menjelaskan metodologi, temuan, dan demo aplikasi dapat dilihat pada tautan berikut: Video Presentasi YouTube

Lampiran C: Source Code Analisis Utama (R)

Berikut adalah cuplikan kode R yang digunakan untuk analisis statistik dan pemodelan:

# ==============================================================================
# SCRIPT ANALISIS PREVALENSI MENINGITIS DKI JAKARTA (2018-2024)
# ==============================================================================

# 1. SETUP LIBRARY
# ------------------------------------------------------------------------------
rm(list = ls()) 
if (!require("pacman")) install.packages("pacman")
pacman::p_load(tidyverse, sf, tmap, grid, RColorBrewer, classInt, plm, lmtest, sandwich)

# --- ATUR FOLDER KERJA ---
setwd("C:/Users/Harya/Downloads/UAS Epidemiologi Harya")

# 2. LOAD & BERSIHKAN DATA
# ------------------------------------------------------------------------------

# A. DATA KASUS MENINGITIS
# Membaca file CSV
df_meningitis_raw <- read_csv("Seksi Surveilans Epidemiologi dan Imunisasi Dinkes DKI Jakarta (9).csv", show_col_types = FALSE)

# Proses Cleaning (Ubah format melebar ke memanjang)
df_meningitis <- df_meningitis_raw %>%
  select(-matches("No")) %>%
  pivot_longer(cols = matches("20"), 
               names_to = "Tahun", 
               values_to = "Jumlah_Kasus") %>%
  mutate(
    Tahun = as.numeric(Tahun),
    Wilayah = case_when(
      str_detect(Nama, "Pusat") ~ "Jakarta Pusat",
      str_detect(Nama, "Utara") ~ "Jakarta Utara",
      str_detect(Nama, "Barat") ~ "Jakarta Barat",
      str_detect(Nama, "Selatan") ~ "Jakarta Selatan",
      str_detect(Nama, "Timur") ~ "Jakarta Timur",
      str_detect(Nama, "Seribu") ~ "Kepulauan Seribu",
      TRUE ~ NA_character_
    )
  ) %>%
  filter(!is.na(Wilayah)) %>%
  select(Wilayah, Tahun, Jumlah_Kasus)

# B. DATA PENDUDUK (2018 - 2024)
df_pop <- read_csv("penduduk_dki_2017_2025.csv", show_col_types = FALSE) %>%
  filter(year >= 2018 & year <= 2024, area != "DKI Jakarta") %>%
  mutate(Wilayah = case_when(
    str_detect(area, "Pusat") ~ "Jakarta Pusat",
    str_detect(area, "Utara") ~ "Jakarta Utara",
    str_detect(area, "Barat") ~ "Jakarta Barat",
    str_detect(area, "Selatan") ~ "Jakarta Selatan",
    str_detect(area, "Timur") ~ "Jakarta Timur",
    str_detect(area, "Seribu") ~ "Kepulauan Seribu",
    TRUE ~ NA_character_
  )) %>% 
  select(Wilayah, Tahun = year, Populasi = population)

# C. SHAPEFILE PETA
tryCatch({
  shp_jakarta <- st_read("Kabupaten-Kota (Provinsi Jakarta).shp", quiet = TRUE) %>%
    mutate(
      Luas_km2 = as.numeric(st_area(.)) / 1e6,
      Wilayah = case_when(
        str_detect(NAME_2, "Pusat") ~ "Jakarta Pusat",
        str_detect(NAME_2, "Utara") ~ "Jakarta Utara",
        str_detect(NAME_2, "Barat") ~ "Jakarta Barat",
        str_detect(NAME_2, "Selatan") ~ "Jakarta Selatan",
        str_detect(NAME_2, "Timur") ~ "Jakarta Timur",
        str_detect(NAME_2, "Seribu") ~ "Kepulauan Seribu",
        TRUE ~ NA_character_
      )
    ) %>% filter(!is.na(Wilayah))
}, error = function(e) { stop("Shapefile tidak ditemukan! Pastikan file .shp ada di folder.") })

# 3. GABUNG DATA & HITUNG PREVALENSI
# ------------------------------------------------------------------------------
df_analisis <- df_meningitis %>%
  left_join(df_pop, by = c("Wilayah", "Tahun")) %>%
  left_join(shp_jakarta, by = "Wilayah") %>%
  st_as_sf() %>%
  mutate(
    # RUMUS PREVALENSI (Period Prevalence Rate)
    # (Jumlah Kasus Existing / Populasi Berisiko) * 100.000
    Prevalence_Rate = (Jumlah_Kasus / Populasi) * 100000,
    
    # Kepadatan Penduduk
    Kepadatan = Populasi / Luas_km2
  ) %>%
  filter(!is.na(Populasi))

# 4. LOOPING PEMBUATAN PETA (2018-2024)
# ------------------------------------------------------------------------------
tmap_mode("plot")

# SETUP WARNA: Biru (Blues)
n_classes <- 5
palette_name <- "Blues"
max_val <- max(df_analisis$Prevalence_Rate, na.rm = TRUE)
my_breaks <- pretty(c(0, max_val), n = n_classes)
my_colors <- brewer.pal(n = length(my_breaks) - 1, name = palette_name)

years <- 2018:2024

for (th in years) {
  cat(paste("Membuat Peta Prevalensi Tahun:", th, "...\n"))
  
  data_th <- df_analisis %>% filter(Tahun == th)
  darat <- data_th %>% filter(Wilayah != "Kepulauan Seribu")
  pulau <- data_th %>% filter(Wilayah == "Kepulauan Seribu")
  
  # --- LOGIKA WARNA INSET ---
  rate_pulau <- pulau$Prevalence_Rate
  if(length(rate_pulau) == 0) rate_pulau <- 0
  
  idx_color <- findInterval(rate_pulau, my_breaks, all.inside = TRUE)
  bg_color_inset <- my_colors[idx_color]
  text_color <- ifelse(idx_color >= 4, "white", "black")
  
  # A. PETA UTAMA
  main_map <- tm_shape(darat) +
    tm_polygons("Prevalence_Rate", 
                title = "Prevalensi\n(per 100rb)", 
                palette = palette_name, 
                breaks = my_breaks) +
    tm_text("Wilayah", size = 0.7, fontface = "bold") +
    tm_layout(
      main.title = paste("Peta Prevalensi Meningitis DKI -", th),
      main.title.size = 1.1,
      frame = FALSE,
      legend.position = c("left", "bottom")
    )
  
  # B. PETA INSET
  inset_map <- tm_shape(pulau) +
    tm_polygons(alpha = 0) + 
    tm_layout(
      title = paste0("Kep. Seribu\nRate: ", round(rate_pulau, 2)), 
      title.size = 0.6,
      title.color = text_color,
      bg.color = bg_color_inset,
      frame = TRUE
    )
  
  # C. SIMPAN
  filename <- paste0("Peta_Prevalensi_Meningitis_", th, ".png")
  png(filename, width = 2400, height = 1800, res = 300)
  print(main_map)
  print(inset_map, vp = viewport(x = 0.82, y = 0.82, width = 0.2, height = 0.2))
  dev.off()
}

# 5. REGRESI DATA PANEL (DENGAN VARIABEL TAHUN)
# ------------------------------------------------------------------------------
# Siapkan Data Panel
pdata <- pdata.frame(df_analisis %>% st_drop_geometry(), index = c("Wilayah", "Tahun"))

# --- PERBAIKAN DI SINI ---
# Rumus sekarang: Prevalence_Rate ~ Kepadatan + Tahun
# Artinya: Kita melihat pengaruh Kepadatan Penduduk DAN Tren Waktu terhadap Prevalensi
cem <- plm(Prevalence_Rate ~ Kepadatan + Tahun, data = pdata, model = "pooling")
fem <- plm(Prevalence_Rate ~ Kepadatan + Tahun, data = pdata, model = "within")
rem <- plm(Prevalence_Rate ~ Kepadatan + Tahun, data = pdata, model = "random")

# Simpan Hasil
sink("Hasil_Regresi_Prevalensi_Meningitis_Dengan_Waktu.txt")

cat("=== ANALISIS REGRESI DATA PANEL (DENGAN TREN WAKTU) ===\n")
cat("Variabel Dependen: Prevalence Rate\n")
cat("Variabel Independen: Kepadatan Penduduk & Tahun\n\n")

cat("--- 1. UJI CHOW (Common vs Fixed) ---\n")
print(pooltest(cem, fem))
cat("Interpretasi: P < 0.05 -> Fixed Effect lebih baik.\n\n")

cat("--- 2. UJI HAUSMAN (Fixed vs Random) ---\n")
print(phtest(fem, rem))
cat("Interpretasi: P < 0.05 -> Fixed Effect. P > 0.05 -> Random Effect.\n\n")

cat("--- 3. HASIL MODEL RANDOM EFFECT (RE) ---\n")
# Kita tampilkan RE atau FE tergantung hasil Hausman, tapi biasanya RE ditampilkan dulu
print(summary(rem))

cat("\n--- 4. UJI ROBUST (Arellano) UNTUK MODEL RE ---\n")
# Menggunakan Robust SE untuk mengatasi Heteroskedastisitas/Autokorelasi
print(coeftest(rem, vcov = vcovHC(rem, method = "arellano")))

cat("\n-----------------------------------------------------------\n")
cat("CARA BACA KOEFISIEN 'Tahun':\n")
cat("Jika koefisien 'Tahun' positif (+), berarti tren penyakit MENINGKAT seiring waktu.\n")
cat("Jika koefisien 'Tahun' negatif (-), berarti tren penyakit MENURUN seiring waktu.\n")
cat("-----------------------------------------------------------\n")

sink()

# 6. GRAFIK TREN
# ------------------------------------------------------------------------------
plot_tren <- ggplot(df_analisis, aes(x = Tahun, y = Prevalence_Rate, color = Wilayah)) +
  geom_line(linewidth = 1) + geom_point() +
  labs(title = "Tren Prevalensi Meningitis DKI Jakarta (2018-2024)",
       y = "Prevalensi per 100.000 Penduduk", x = "Tahun") +
  theme_minimal() + scale_x_continuous(breaks = 2018:2024)

ggsave("Grafik_Tren_Prevalensi_Meningitis.png", plot_tren, width = 8, height = 6)

print("SELESAI! Semua Output menggunakan istilah PREVALENSI.")

Lampiran D: Source Code Dashboard (Rshiny)

Berikut adalah cuplikan kode R yang digunakan untuk pembuatan dashboard:

# ==============================================================================
# DASHBOARD INTERAKTIF MENINGITIS DKI JAKARTA (LENGKAP DENGAN KONSEP & MODEL)
# ==============================================================================

# 1. SETUP LIBRARY
library(shiny)
library(shinydashboard)
library(tidyverse)
library(sf)
library(leaflet)
library(plotly)
library(DT)
library(RColorBrewer)

# 2. DATA PROCESSING (JANGAN UBAH BAGIAN INI - SAMA SEPERTI SEBELUMNYA)
tryCatch({
  # A. Load Data Kasus
  df_meningitis_raw <- read_csv("Seksi Surveilans Epidemiologi dan Imunisasi Dinkes DKI Jakarta (9).csv", show_col_types = FALSE)
  
  df_meningitis <- df_meningitis_raw %>%
    select(-matches("No")) %>%
    pivot_longer(cols = matches("20"), names_to = "Tahun", values_to = "Jumlah_Kasus") %>%
    mutate(
      Tahun = as.numeric(Tahun),
      Wilayah = case_when(
        str_detect(Nama, "Pusat") ~ "Jakarta Pusat",
        str_detect(Nama, "Utara") ~ "Jakarta Utara",
        str_detect(Nama, "Barat") ~ "Jakarta Barat",
        str_detect(Nama, "Selatan") ~ "Jakarta Selatan",
        str_detect(Nama, "Timur") ~ "Jakarta Timur",
        str_detect(Nama, "Seribu") ~ "Kepulauan Seribu",
        TRUE ~ NA_character_
      )
    ) %>%
    filter(!is.na(Wilayah)) %>%
    select(Wilayah, Tahun, Jumlah_Kasus)
  
  # B. Load Data Penduduk
  df_pop <- read_csv("penduduk_dki_2017_2025.csv", show_col_types = FALSE) %>%
    filter(year >= 2018 & year <= 2024, area != "DKI Jakarta") %>%
    mutate(Wilayah = case_when(
      str_detect(area, "Pusat") ~ "Jakarta Pusat",
      str_detect(area, "Utara") ~ "Jakarta Utara",
      str_detect(area, "Barat") ~ "Jakarta Barat",
      str_detect(area, "Selatan") ~ "Jakarta Selatan",
      str_detect(area, "Timur") ~ "Jakarta Timur",
      str_detect(area, "Seribu") ~ "Kepulauan Seribu",
      TRUE ~ NA_character_
    )) %>% select(Wilayah, Tahun = year, Populasi = population)
  
  # C. Load Shapefile
  shp_jakarta <- st_read("Kabupaten-Kota (Provinsi Jakarta).shp", quiet = TRUE) %>%
    mutate(Wilayah = case_when(
      str_detect(NAME_2, "Pusat") ~ "Jakarta Pusat",
      str_detect(NAME_2, "Utara") ~ "Jakarta Utara",
      str_detect(NAME_2, "Barat") ~ "Jakarta Barat",
      str_detect(NAME_2, "Selatan") ~ "Jakarta Selatan",
      str_detect(NAME_2, "Timur") ~ "Jakarta Timur",
      str_detect(NAME_2, "Seribu") ~ "Kepulauan Seribu",
      TRUE ~ NA_character_
    )) %>% filter(!is.na(Wilayah))
  
  # D. Gabung Data
  df_final <- df_meningitis %>%
    left_join(df_pop, by = c("Wilayah", "Tahun")) %>%
    mutate(
      Prevalence_Rate = round((Jumlah_Kasus / Populasi) * 100000, 2)
    )
  
  df_map_base <- shp_jakarta %>% left_join(df_final, by = "Wilayah")
  
}, error = function(e) {
  stop("Gagal Membaca Data. Pastikan file CSV dan SHP ada di folder kerja.")
})

# 3. USER INTERFACE (UI)
ui <- dashboardPage(
  skin = "purple", # Ganti warna biar fresh
  
  # --- HEADER ---
  dashboardHeader(title = "Meningitis DKI Jakarta"),
  
  # --- SIDEBAR MENU ---
  dashboardSidebar(
    sidebarMenu(
      # MENU BARU: KONSEP & TEORI
      menuItem("Beranda & Konsep", tabName = "home", icon = icon("book-medical")),
      
      # MENU UTAMA ANALISIS
      menuItem("Peta Sebaran", tabName = "map", icon = icon("map-marked-alt")),
      menuItem("Tren Waktu", tabName = "trends", icon = icon("chart-line")),
      
      # MENU BARU: PENJELASAN MODELING
      menuItem("Metode Modeling", tabName = "model_theory", icon = icon("cogs")),
      menuItem("Hasil Regresi", tabName = "model_result", icon = icon("table")),
      
      menuItem("Database", tabName = "data", icon = icon("database")),
      menuItem("Tentang Penulis", tabName = "about", icon = icon("user-graduate"))
    )
  ),
  
  # --- BODY ---
  dashboardBody(
    # CSS Custom untuk teks justified (rata kanan kiri)
    tags$head(tags$style(HTML('
      p {text-align: justify; font-size: 16px;} 
      li {font-size: 15px;}
      .box-header {font-size: 18px; font-weight: bold;}
    '))),
    
    tabItems(
      # --- TAB 1: BERANDA & KONSEP EPIDEMIOLOGI ---
      tabItem(tabName = "home",
              fluidRow(
                box(
                  title = "Latar Belakang & Segitiga Epidemiologi", 
                  status = "primary", solidHeader = TRUE, width = 12,
                  h4("1. Konsep Agent-Host-Environment"),
                  p("Kejadian penyakit Meningitis di DKI Jakarta dianalisis menggunakan pendekatan Segitiga Epidemiologi:"),
                  tags$ul(
                    tags$li(tags$b("Agent (Agen):"), " Bakteri (seperti Neisseria meningitidis, Streptococcus pneumoniae) dan virus yang menyebabkan peradangan pada selaput otak."),
                    tags$li(tags$b("Host (Pejamu):"), " Penduduk DKI Jakarta, dengan fokus pada kelompok rentan (imunitas rendah) yang tinggal di wilayah berisiko."),
                    tags$li(tags$b("Environment (Lingkungan):"), " Faktor kepadatan penduduk (Crowding) yang ekstrem di Jakarta. Kepadatan tinggi mempermudah transmisi droplet antar individu.")
                  ),
                  tags$hr(),
                  h4("2. Ukuran Epidemiologi yang Digunakan"),
                  p("Analisis ini menggunakan indikator Prevalence Rate (Angka Prevalensi Periode) untuk mengukur beban penyakit:"),
                  withMathJax("$$ Prevalence Rate = \\frac{\\text{Jumlah Kasus (Lama + Baru)}}{\\text{Populasi Berisiko}} \\times 100.000 $$"),
                  p("Indikator ini dipilih untuk menstandarisasi perbandingan antar wilayah (Jakarta Pusat vs Kepulauan Seribu) agar tidak bias oleh jumlah penduduk.")
                )
              )
      ),
      
      # --- TAB 2: PETA SEBARAN (VISUAL) ---
      tabItem(tabName = "map",
              fluidRow(
                valueBoxOutput("vbox_total", width = 4),
                valueBoxOutput("vbox_avg", width = 4),
                valueBoxOutput("vbox_max", width = 4)
              ),
              fluidRow(
                box(
                  title = "Peta Interaktif Sebaran Prevalensi", 
                  status = "primary", width = 12,
                  selectInput("year_input", "Pilih Tahun Pengamatan:", choices = 2018:2024, selected = 2024),
                  leafletOutput("leaflet_map", height = "550px"),
                  helpText("Keterangan: Warna lebih gelap menunjukkan prevalensi yang lebih tinggi.")
                )
              )
      ),
      
      # --- TAB 3: TREN WAKTU ---
      tabItem(tabName = "trends",
              fluidRow(
                box(
                  title = "Analisis Tren Temporal (Time Series)", width = 12, status = "warning",
                  plotlyOutput("plotly_trend", height = "500px"),
                  tags$br(),
                  p("Grafik di atas menunjukkan dinamika kasus dari tahun ke tahun. Terlihat adanya lonjakan signifikan (outbreak) pada tahun 2024 setelah periode landai selama pandemi.")
                )
              )
      ),
      
      # --- TAB 4: TEORI MODELING (PENJELASAN METODE) ---
      tabItem(tabName = "model_theory",
              fluidRow(
                box(
                  title = "Metodologi Statistik Inferensia", 
                  status = "danger", solidHeader = TRUE, width = 12,
                  h4("1. Pendekatan Regresi Data Panel"),
                  p("Penelitian ini menggunakan Regresi Data Panel karena data memiliki dua dimensi:"),
                  tags$ul(
                    tags$li("Dimensi Ruang (Cross-section): 6 Wilayah Administrasi."),
                    tags$li("Dimensi Waktu (Time-series): 7 Tahun (2018-2024).")
                  ),
                  p("Metode ini lebih unggul dibanding regresi biasa karena dapat mengontrol heterogenitas (karakteristik unik) antar wilayah yang tidak teramati."),
                  
                  tags$hr(),
                  h4("2. Pemilihan Model (Uji Hausman)"),
                  p("Dilakukan Uji Chow dan Uji Hausman untuk memilih antara Common Effect, Fixed Effect, atau Random Effect."),
                  tags$ul(
                    tags$li(tags$b("Hasil Uji Hausman:"), " Nilai p-value > 0.05."),
                    tags$li(tags$b("Keputusan:"), " Model yang terpilih adalah **Random Effect Model (REM)**.")
                  ),
                  
                  tags$hr(),
                  h4("3. Koreksi Model (Robust Standard Errors)"),
                  p("Digunakan Robust Standard Errors (Metode Arellano) agar hasil uji signifikansi (uji-t) valid dan tidak bias.")
                )
              )
      ),
      
      # --- TAB 5: HASIL REGRESI (OUTPUT) ---
      tabItem(tabName = "model_result",
              fluidRow(
                box(
                  title = "Hasil Estimasi Random Effect (Robust SE)", 
                  width = 12, status = "success",
                  DTOutput("tbl_regresi"),
                  tags$br(),
                  tags$div(
                    style = "padding: 15px; background-color: #e8f5e9; border: 1px solid #4caf50;",
                    h4("Interpretasi Hasil:"),
                    tags$ul(
                      tags$li(tags$b("Kepadatan Penduduk (p = 0.025):"), " Berpengaruh POSITIF dan SIGNIFIKAN. Setiap kenaikan kepadatan penduduk, risiko Meningitis meningkat."),
                      tags$li(tags$b("Tahun 2024 (p = 0.015):"), " Koefisien bernilai positif besar (1.29), menunjukkan lonjakan kasus yang sangat signifikan dibanding tahun dasar."),
                      tags$li(tags$b("Tahun 2021-2022:"), " Koefisien negatif signifikan, menunjukkan penurunan kasus saat pandemi.")
                    )
                  )
                )
              )
      ),
      
      # --- TAB 6: DATABASE ---
      tabItem(tabName = "data",
              fluidRow(
                box(title = "Data Mentah", width = 12, DTOutput("tbl_raw"))
              )
      ),
      
      # --- TAB 7: TENTANG ---
      tabItem(tabName = "about",
              fluidRow(
                box(
                  title = "Identitas Penulis", width = 6,
                  h3("I Gusti Bagus Harya Putra"),
                  h4("NPM: 140610230010"),
                  p("Program Studi Statistika"),
                  p("Fakultas Matematika dan Ilmu Pengetahuan Alam"),
                  p("Universitas Padjadjaran"),
                  tags$hr(),
                  p("Dashboard ini dibuat sebagai pemenuhan Tugas UAS Mata Kuliah Epidemiologi Semester 5.")
                )
              )
      )
    )
  )
)

# 4. SERVER LOGIC
server <- function(input, output) {
  
  # --- FILTER DATA ---
  dat_filtered <- reactive({
    df_map_base %>% filter(Tahun == input$year_input)
  })
  
  stats_filtered <- reactive({
    df_final %>% filter(Tahun == input$year_input)
  })
  
  # --- VALUE BOXES ---
  output$vbox_total <- renderValueBox({
    val <- sum(stats_filtered()$Jumlah_Kasus, na.rm=T)
    valueBox(val, paste("Total Kasus", input$year_input), icon = icon("hospital"), color = "purple")
  })
  
  output$vbox_avg <- renderValueBox({
    val <- round(mean(stats_filtered()$Prevalence_Rate, na.rm=T), 2)
    valueBox(val, "Rata-rata Rate", icon = icon("percent"), color = "blue")
  })
  
  output$vbox_max <- renderValueBox({
    d <- stats_filtered()
    top <- d[which.max(d$Prevalence_Rate), ]
    valueBox(top$Prevalence_Rate, paste("Max:", top$Wilayah), icon = icon("arrow-up"), color = "red")
  })
  
  # --- PETA LEAFLET ---
  output$leaflet_map <- renderLeaflet({
    dat <- dat_filtered()
    pal <- colorBin("YlOrRd", domain = df_final$Prevalence_Rate, bins = 5)
    
    labels <- sprintf(
      "<strong>%s</strong><br/>Rate: %g<br/>Kasus: %g<br/>Penduduk: %g",
      dat$Wilayah, dat$Prevalence_Rate, dat$Jumlah_Kasus, dat$Populasi
    ) %>% lapply(htmltools::HTML)
    
    leaflet(dat) %>%
      addProviderTiles(providers$CartoDB.Positron) %>%
      addPolygons(
        fillColor = ~pal(Prevalence_Rate), weight = 1, color = "white",
        fillOpacity = 0.8,
        highlightOptions = highlightOptions(weight = 3, color = "#666", bringToFront = TRUE),
        label = labels
      ) %>%
      addLegend(pal = pal, values = ~Prevalence_Rate, title = "Prevalensi", position = "bottomright")
  })
  
  # --- GRAFIK TREN ---
  output$plotly_trend <- renderPlotly({
    p <- ggplot(df_final, aes(x = Tahun, y = Prevalence_Rate, color = Wilayah)) +
      geom_line(size = 1) + geom_point() +
      theme_minimal() + labs(y = "Prevalence Rate")
    ggplotly(p)
  })
  
  # --- TABEL REGRESI (MANUAL INPUT) ---
  output$tbl_regresi <- renderDT({
    res <- data.frame(
      Variabel = c("(Intercept)", "Kepadatan Penduduk", "Tahun 2019", "Tahun 2020", 
                   "Tahun 2021", "Tahun 2022", "Tahun 2023", "Tahun 2024"),
      Koefisien = c(0.4562, 0.000038, 0.1263, -0.3264, -0.4541, -0.5049, -0.2219, 1.2991),
      Std_Error = c(0.3195, 0.000016, 0.2527, 0.2675, 0.2024, 0.2269, 0.2022, 0.5077),
      P_Value = c(0.1624, 0.0253, 0.6205, 0.2308, 0.0315, 0.0328, 0.2802, 0.0151),
      Kesimpulan = c("-", "SIGNIFIKAN", "-", "-", "SIG (Turun)", "SIG (Turun)", "-", "SIG (Naik Drastis)")
    )
    datatable(res, options = list(dom = 't', pageLength = 8), rownames = FALSE) %>%
      formatStyle('P_Value', backgroundColor = styleInterval(0.05, c('lightgreen', 'white')))
  })
  
  # --- TABEL DATA ---
  output$tbl_raw <- renderDT({
    datatable(df_final, extensions = 'Buttons', options = list(dom = 'Bfrtip', buttons = c('csv', 'excel')))
  })
}

# 5. RUN APP
shinyApp(ui, server)