IDENTITAS

Farhan Alkarimi - 140610230028

ABSTRAK

Malaria masih menjadi tantangan kesehatan masyarakat di Indonesia, termasuk di wilayah perkotaan seperti Provinsi DKI Jakarta. Padahal, melalui Tujuan Pembangunan Berkelanjutan (Sustainable Development Goals/SDGs) poin ke-3, dunia menargetkan pengakhiran epidemi malaria pada tahun 2030. Penelitian ini bertujuan untuk menggambarkan situasi epidemiologi malaria di Provinsi DKI Jakarta periode 2016–2025 melalui pendekatan analisis spasial dan temporal, serta memprediksi kecenderungan kejadian malaria pada tahun berikutnya.

Penelitian ini menggunakan desain studi epidemiologi deskriptif dengan pendekatan ekologi deret waktu. Data sekunder diperoleh dari sistem surveilans Dinas Kesehatan Provinsi DKI Jakarta, meliputi jumlah kasus malaria dan data penduduk. Analisis dilakukan dengan menghitung incidence rate (IR), memetakan distribusi spasial antarwilayah, menganalisis tren temporal, serta melakukan pemodelan deret waktu menggunakan metode Holt–Winters untuk memprediksi IR malaria tahun 2026.

Hasil penelitian menunjukkan bahwa kejadian malaria di Provinsi DKI Jakarta mengalami fluktuasi dengan tren peningkatan yang cukup tajam sejak tahun 2022, terutama pada wilayah Jakarta Selatan dan Jakarta Timur. Distribusi kasus bersifat tidak merata antarwilayah dan menunjukkan adanya konsentrasi spasial di wilayah tertentu. Hasil pemodelan deret waktu memperkirakan bahwa malaria masih berpotensi terjadi sepanjang tahun 2026 dengan pola musiman yang jelas, meskipun tingkat ketidakpastian prediksi masih cukup tinggi.

Kesimpulannya, malaria di Provinsi DKI Jakarta masih merupakan masalah kesehatan masyarakat yang memerlukan perhatian serius. Pendekatan epidemiologi berbasis spasial dan temporal menjadi penting sebagai dasar perencanaan program surveilans, pencegahan, dan pengendalian malaria yang sejalan dengan upaya pencapaian SDG 3, khususnya target eliminasi malaria pada tahun 2030.

Kata kunci: Malaria, epidemiologi, incidence rate, pemetaan penyakit, SDGs, DKI Jakarta

BAB 1 - PENDAHULUAN

1.1 Latar Belakang

Dalam kegiatan sehari-hari, malaria masih menjadi penyakit menular yang berkontribusi terhadap keberjalanan hidup masyarakat. Di Indonesia, terkhususnya provinsi DKI Jakarta, angka kasus malaria cenderung meningkat di beberapa tahun terakhir. Padahal WHO menargetkan melalui SDG ketiga, yakni Good Health and Well-being, penyakit malaria berakhir pada tahun 2030. Selain itu provinsi DKI Jakarta memiliki karakteristik lingkungan yang kompleks. Kepadatan penduduk, perubahan guna lahan serta akses layanan kesehatan memungkinkan terpengaruhnya penyebaran penyakit secara spasial dan temporal.

Oleh karena itu, pada laporan ini saya melakukan penggambaran melalui pendekatan epidemiologi spasial untuk mengidentifikasi variasi risiko antar wilayah terkait penyebaran malaria. Hasil analisis tersebut akan disajikan dalam bentuk visualisasi dashboard sehingga pembaca dapat memperoleh informasi dengan lebih interaktif. Penelitian ini diharapkan dapat membantu penggambaran epidemiologi malaria dan menyoroti wilayah yang butuh penanganan tertentu.

1.2 Rumusan Masalah

Berdasarkan latar belakang tersebut, permasalahan yang dikaji dalam penelitian ini dapat dirumuskan sebagai berikut:

  1. Bagaimana gambaran epidemiologi malaria berdasarkan ukuran epidemiologi yang digunakan?

  2. Wilayah mana yang menunjukkan peningkatan kejadian malaria?

  3. bagaimana gambaran malaria di tahun depan?

1.3 Tujuan Penelitian

1.3.1 Tujuan Umum

Mengetahui dan menyajikan gambaran epidemiologi malaria di Provinsi DKI Jakarta menggunakan pendekatan analisis epidemiologi spasial dan temporal.

1.3.2 Tujuan Khusus

  1. Mendeskripsikan gambaran epidemiologi malaria di provinsi DKI Jakarta

  2. Menganalisis pola distribusi spasial dan tren

  3. Menvisualisasikan sebaran resiko malaria secara spasial

BAB 2 - TINJAUAN PUSTAKA

2.1 Konsep Dasar Epidemiologi

Epidemiologi adalah ilmu yang mempelajari distribusi kesehatan pada populasi tertentu. Pada kasus ini, saya menggunakan kejadian malaria di DKI Jakarta. Untuk itu, dapat dibuatkan segitiga epidemiologi dan diperoleh :

  1. Agent

    Penyebab disini adalah parasit plasmodium melalui gigitan nyamuk Anopheles.

  2. Host

    Host disini adalah manusia dengan tingkat kerentanannya. Faktor ini bisa berbeda disetiap orang berdasarkan umur, imun, dan lainnya.

  3. Enviroment

    Lingkungan yang mendukung interaksi antara host dan agent. Faktor ini meliputi kondisi iklim, habitat nyamuk, kepadatan penduduk dan karakteristik wilayah lainnya.

2.2 Ukuran Asosiasi Epidemiologi

Untuk menggambarkan malaria disini kami menggunakan ukuran Incidence Rate (IR). Ukuran ini memberikan definisi tentang risiko terjadi kasus alaria di suatu populasi dalam satu waktu tertentu. Ukuran ini dapat dihitung dengan rumus :

\[ \text{Incidence Rate (IR)} = \frac{\text{Jumlah Kasus Baru}}{\text{Jumlah Penduduk}} \times 10{,}000{,}000 \]

Selain itu saya juga menggunakan indikator absolut yakni jumlah kasus, yang menunjukkan total kasus malaria pada suatu wilayah dan periode.

2.3 Desain Studi Epidemiologi

Penelitian ini menggunakan desain studi observasional ekologi dengan pendekatan deret waktu (ecological time series study). Unit analisis meliputi kabupaten/kota di Provinsi DKI Jakarta untuk analisis spasial, serta incidence rate malaria tingkat provinsi untuk analisis temporal. Data yang digunakan merupakan data agregat rutin surveilans malaria, yang dianalisis secara deskriptif untuk menggambarkan distribusi spasial dan tren temporal kejadian malaria antarwilayah dan antarperiode waktu.

2.4 Pemodelan Time Series

Analisis deret waktu (time series analysis) digunakan untuk mempelajari pola kejadian malaria dari waktu ke waktu serta memprediksi kecenderungan kejadian pada periode mendatang. Metode ini relevan dalam epidemiologi karena mampu menangkap komponen tren dan musiman yang umum terjadi pada penyakit menular.

Penelitian ini menggunakan metode Holt–Winters Exponential Smoothing, yang merupakan pengembangan dari exponential smoothing dengan mempertimbangkan tiga komponen utama, yaitu:

  1. Level, yang merepresentasikan nilai rata-rata kejadian pada waktu tertentu.

  2. Trend, yang menggambarkan arah perubahan kejadian dari waktu ke waktu

  3. Seasonality, yang menangkap pola musiman yang berulang secara periodik

Model Holt–Winters dengan komponen musiman aditif digunakan untuk memprediksi Incidence Rate malaria tahun 2026 berdasarkan data historis sebelumnya. Pemilihan model ini didasarkan pada kemampuannya dalam menangani data deret waktu dengan pola musiman yang relatif stabil.

Hasil prediksi diharapkan dapat memberikan gambaran awal mengenai kecenderungan kejadian malaria di masa mendatang serta menjadi dasar pendukung dalam perencanaan dan evaluasi program pengendalian malaria.

BAB 3. METODOLOGI

3.1 Jenis dan Rancangan Penelitian

Penelitian ini merupakan studi epidemiologi deskriptif dengan pendekatan ekologi deret waktu. Pendekatan ini digunakan untuk menggambarkan situasi malaria di Provinsi DKI Jakarta berdasarkan data kasus dan incidence rate pada periode pengamatan. Analisis dilakukan untuk memetakan distribusi spasial antar kabupaten/kota, mengevaluasi tren temporal kejadian malaria, serta mengidentifikasi wilayah dengan tingkat risiko relatif lebih tinggi.

3.2 Sumber Data

Penelitian ini menggunakan data sekunder yang diperoleh dari seksi surveilans Dinkes DKI Jakarta yang berisikan jumlah kasus baik yang dirawat ataupun meninggal. Selain itu saya juga menggunakan data spasial (shapefile) sebagai peta digitas batas administrasi wilayah.

3.3 Variabel Penelitian

Penelitian ini menggunakan data total kasus per bulan di setiap kabupaten/kota yang ada di provinsi DKI Jakarta dari tahun 2016 hingga 2025. Dengan ini kami menentukan incidence rate dengan rumus sebelumnya, sehingga diperoleh dua variabel yakni total kasus dan incidence rate.

Tabel berikut merangkum variabel yang digunakan dalam penelitian ini :

Nama Variabel Satuan / Kategori Keterangan
Jumlah kasus Malaria Kasus (orang) Total kasus Malaria yang dilaporkan per kabupaten/kota
Incidence Rate kasus per 10.000.000 penduduk per tahun Jumlah kasus per banyak penduduk pada suatu periode pengamatan tertentu

3.4 Metode Analisis Data

Analisis dilakukan secara sistematis menggunakan R studio melalui tahapan :

  1. Pemprosesan data, disini dilakukan import data, cleaning data dan persiapan tabel data
  2. Epidemiologi : menghitung ukuran epidemiologi seperti incidence rate. Kemudian dilakukan visualisasi trend dan peta sebaran
  3. Inferensi : prediksi menggunakan time series analysis

BAB 4 - HASIL DAN PEMBAHASAN

4.1 Gambaran Umum Situasi Malaria di Jawa Barat

Bagian ini menyajikan tabel data awal dan gambaran datanya.

Untuk wilayah yang digunakan terdiri dari 6 wilayah yakni Jakarta Pusat, Jakarta Timur, Jakarta Selatan, Jakarta Barat, Jakarta Utara dan Kepulauan Seribu. Untuk tahun dimulai dari 2016 hingga 2025

Dari data ini dapat peroleh hasil pemetaan tiap tahunnya. Semakin kuat gelap warna daerah, maka semakin tinggi kasus di daerah terebut. Hasilnya adalah sebagai berikut

4.1.1 Tahun 2016

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2016, wilayah Jakarta Timur merupakan wilayah dengan jumlah kasus terbanyak di DKI Jakarta. Dapat dilihat juga pada bulan Juli terjadi lonjakan kasus pada wilayah tersebut.

4.1.2 Tahun 2017

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2017, wilayah Jakarta Timur masih menjadi wilayah dengan jumlah kasus terbanyak di DKI Jakarta. Dapat dilihat juga pada pola trend yakni bulan April total kasusnya mencapai 6 orang dan 4 orang pada bulan Juni.

4.1.3 Tahun 2018

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2018, wilayah Jakarta Timur masih menjadi wilayah dengan jumlah kasus terbanyak di DKI Jakarta. Pada pola trend dapat dilihat adanya peningkatan kasus pada Jakarta Timur, Jakarta Selatan dan Jakarta Barat.

4.1.4 Tahun 2019

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2019, wilayah Jakarta Timur masih menjadi wilayah dengan jumlah kasus terbanyak di DKI Jakarta. Sama hal dengan sebelumnya yakni wilayah Jakarta timur mencapai titik jumlah kasus tertinggi yakni sebanyak 8 orang pada bulan September.

4.1.5 Tahun 2020

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2020, wilayah Jakarta Timur masih menjadi wilayah dengan jumlah kasus terbanyak di DKI Jakarta. Dapat dilihat juga bahwa kasus Malaria di wilayah lain sudah mengalami penurunan. Dari plotnya dapat dilihat pula bahwa Wilayah Jakarta Timur memiliki pola trend tinggi dibanding wilayah lainnya.

4.1.6 Tahun 2021

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2021, wilayah Jakarta Timur masih menjadi wilayah dengan jumlah kasus terbanyak di DKI Jakarta. Pada plot trend dapat dilihat bahwa wilayah Jakarta Timur dan Jakarta Selatan memberikan kasus baru.

4.1.7 Tahun 2022

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2022, wilayah Jakarta Timur masih menjadi wilayah dengan jumlah kasus terbanyak di DKI Jakarta. Dapat dilihat juga pada pola trend bahwa terjadi peningkatan kasus untuk setiap wilayah yang ada dengan Jakarta Timur masih memberikan kasus yang paling tinggi.

4.1.8 Tahun 2023

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2023, wilayah Jakarta Timur masih menjadi wilayah dengan jumlah kasus terbanyak di DKI Jakarta. Dapat dilihat juga pada pola trend bahwa hampir setiap wilayah memberikan kontribusi dalam kasus malaria

4.1.9 Tahun 2024

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2024, wilayah dengan kasus tertinggi berpindah pada provinsi Jakarta Selatan. Dapat dilihat juga pada plot trent bahwa pada bulan Desember 2024 terjadi lonjakan ekstrim yang awalnya 5 orang pada bulan November menjadi 22 orang pada bulan Desember.

4.1.10 Tahun 2025

Berdasarkan peta dan trend kasus yang ada dapat dilihat bahwa pada tahun 2025, wilayah dengan kasus tertinggi masih pada provinsi Jakarta Selatan. Dapat dilihat juga pada plot trend bahwa pada bulan Areil hingga September 2025 terjadi kenaikan kasus lebih dari 10 hingga 25 orang.

4.2 Peningkatan Kasus dari Tahun ke Tahun

Pada tahun 2016, jumlah kasus Malaria di DKI Jakarta tercatat sebanyak 45 kasus dengan Jakarta Timur menyumbang pasien terbanyak. Tahun berikutnya, terjadi peningkatan sebesar 44,4% yakni menjadi 65 kasus pada tahun 2017. Hal ini sama dengan tahun 2018 yang juga menyumbang 65 kasus. Pada tahun 2019 terjadi penurunan menjadi 56 kasus dan tahun 2020 juga terjadi penurunan kembali menjadi 49 orang. Hal yang sama juga terjadi pada 2021 seanyak 49 orang.

Selanjutnya pada 2022 terjadi lonjakan yang cukup tinggi yakni sebesar 46,9% menjadi 72 kasus. Dilanjutkan lonjakan pada tahun 2023 menjadi 107 kasus, kemudian tahun 2024 menjadi 168 kasus dengan peningkatan 57% dari sebelumnya. Terakhir pada 2025 terdapat 267 kasus. Hal ini mungkin terjadi karena setelah pandemi covid-19 banyak fasilitas kesehatan yang lebih gencar terhadap kesehatan. Dibanding sejak pasca pandemi (2022) hingga tahun 2025, terjadi peningkatan sebesar 270%.

Tahun Total Kasus Kenaikan dibanding Tahun Sebelumnya (%)
2016 45 0.0
2017 65 44.4
2018 65 0.0
2019 56 -13.8
2020 49 -12.5
2021 49 0.0
2022 72 46.9
2023 107 48.6
2024 168 57.0
2025 267 58.9

4.3 Penyebaran Proporsi tahun 2025

Diagram proporsi menunjukkan bahwa kasus malaria di Provinsi DKI Jakarta terkonsentrasi pada wilayah tertentu. Jakarta Selatan merupakan kontributor terbesar dengan proporsi 46,8% dari total kasus malaria, diikuti oleh Jakarta Timur sebesar 28,8%. Dua wilayah ini secara kumulatif menyumbang lebih dari tiga perempat total kasus, mengindikasikan adanya konsentrasi spasial kejadian malaria di bagian selatan dan timur DKI Jakarta.

Sebaliknya, Jakarta Pusat menyumbang 10,5% kasus, sedangkan Jakarta Barat dan Jakarta Utara masing-masing hanya berkontribusi 7,49% dan 6,37%. Kepulauan Seribu tidak mencatat kasus malaria (0%) pada periode pengamatan. Pola distribusi ini menegaskan adanya ketimpangan beban penyakit antarwilayah, yang penting sebagai dasar penentuan wilayah prioritas dalam upaya surveilans, pencegahan, dan pengendalian malaria di Provinsi DKI Jakarta

4.4 Pemodelan Time Series

Bagian ini menganalisis tentang prediksi insidence rate provinsi DKI Jakarta pada tahun 2026 berdasarkan data historis. Pada pola data terlihat adanya pola musiman yang jelas sehingga analisis dilakukan menggunakan eksponensial smoothing yakni Holt Winters dan Seasonal ARIMA. Dari perhitungan diperoleh hasil

Holt–Winters menunjukkan pola prediksi IR malaria tahun 2026 yang lebih berfluktuasi dan musiman, dengan nilai relatif lebih rendah di awal tahun dan peningkatan tajam pada pertengahan tahun, khususnya bulan Juli (IR ≈ 3,16). Pola ini mencerminkan sensitivitas Holt–Winters terhadap musiman historis, sehingga model ini menekankan adanya potensi lonjakan kasus pada bulan-bulan tertentu akibat faktor musiman seperti curah hujan atau kondisi lingkungan.

Sebaliknya, SARIMA menghasilkan prediksi yang lebih stabil dan konsisten sepanjang tahun dengan rentang IR sekitar 2,2–2,6, meskipun tetap menunjukkan peningkatan pada akhir tahun (Desember ≈ 2,99). Hal ini menunjukkan bahwa SARIMA lebih menekankan ketergantungan waktu dan pola jangka panjang, sehingga cenderung meredam fluktuasi ekstrem dan memberikan gambaran risiko malaria yang relatif merata antarbulan.

Secara keseluruhan, Holt–Winters lebih cocok untuk mendeteksi puncak musiman, sedangkan SARIMA lebih sesuai untuk proyeksi tren yang stabil, sehingga keduanya saling melengkapi dalam menggambarkan dinamika risiko malaria tahun 2026.

4.5 DISKUSI

Hasil analisis menunjukan bahwa pola insidensi malaria tidak konstan selama periode waktu. Wilayah Jakarta Timur dan Jakarta Selatan menjadi wilayah dengan tingkat kasus yang tinggi di DKI Jakarta sedangkan wilayah Kepulauan Seribu malah memiliki total kasus yang sangat sedikit. Berdasarkan plot awal data, dapat dilihat bahwa terjadi peningkatan yang signifikan pada tahun 2024 dan 2025 yang mencapai 2 kali dari tahun-tahun sebelumnya. Ini menjadi hal yang perlu diperhatikan kedepannya mengingat bahwa 2030 harapannya adalah eliminasi malaria di dunia.

Pada hasil forecast dari model time series dapat dilihat bahwa adanya potensi peningkatan risiko malaria pada periode tertentu di tahun 2026. Temuan ini menegaskan bahwa DKI Jakarta masih butuh perhatian khusus dalam penanganan Malaria. Pada penelitian ini dilakukan identifikasi wilayah dan periode berisiko tinggi. Harapannya ini dapat mendukung upaya epidemiologi dalam penentuan prioritas kebijakan.

BAB 5 - KESIMPULAN DAN SARAN

5.1 Kesimpulan

Berdasarkan hasil analisis dan pembahasan, dapat disimpulkan bahwa :

  1. Kejadian Malaria di DKI Jakarta menunjukkan trend fluktuatif dengan peningkatan signifikan dari tahun 2022 hingga 2025
  2. Melalui inciddence rate Malaria, dapat digambarkan bahwa adanya perbedaan antar wilayah dengan Jakarta Timur dan Jakarta Selatan memberikan pasien yang banyak sedangkan Kepulauan Seribu hampir konsisten tidak ada penderita.
  3. Hasil prediksi insidence rate menggunakan metode Holt-Winters dan SARIMA memperkirakan bahwa malaria memiliki potensi yang besar untuk terjadi di 2026 mengingat 3 tahun terakhir terjadi peningkatan yang signifikan. Temuan ini menegaskan perlunya upaya penanganan Malaria di DKI Jakarta.

5.2 Saran

Berdasarkan hasil temuan tersebut, saran yang dapat diberikan adalah :

  1. Pengelola Kesehatan DKI Jakarta perlu menetapkan wilayah prioritas pengendalian mengingat terjadinya lonjakan hingga lebih dari 200% kasus saat pandemi.
  2. Penelitian selanjutnya disarakan menggunakan metode pemodelan yang lebih kompleks dan akurat untuk meningkatkna kualitas prediksi kejadian malaria
  3. Hasil analisis ini dapat digunakan sebagai perencaaan program kesehatan. Oleh karena itu diharapkan kepada pemegang kebijakan untuk mempertimbangkannya demi mendukung percapaian target SDG 3 yakni eliminasi kasus malaria tahun 2030.

5.3 Penutup

Hasil penelitian saya diharap dapat menjadi bahan rujukan bagi perencanaan program pengendalian Malaria di DKI Jakarta. Pengambilan keputusan tidak lagi berdasarkan apa yang dirasakan subjektif, tapi dapat diambil melalui pertimbangan data aktual. Dengan pemanfaatan informasi akurat, semoga upaya pencegahan dan pengendalian Malaria dapat dilakukan lebih efektif dan berkelanjutan.

Daftar Pustaka

  • Jaya, I. G. N. M. (2025). Epidemiologi.

  • Centers for Disease Control and Prevention (CDC). (2023). Malaria: Epidemiology and Risk Factors. Atlanta: CDC.

  • Kementerian Kesehatan Republik Indonesia. (2022). Pedoman Nasional Penanggulangan Malaria. Jakarta: Kemenkes RI.

  • Kementerian Kesehatan Republik Indonesia. (2023). Profil Kesehatan Indonesia Tahun 2022. Jakarta: Kemenkes RI.

  • Lawson, A. B. (2018). Bayesian Disease Mapping: Hierarchical Modeling in Spatial Epidemiology (3rd ed.). Boca Raton: CRC Press.

  • Rothman, K. J., Greenland, S., & Lash, T. L. (2021). Modern Epidemiology (4th ed.). Philadelphia: Wolters Kluwer.

  • Shumway, R. H., & Stoffer, D. S. (2017). Time Series Analysis and Its Applications: With R Examples (4th ed.). New York: Springer.

  • World Health Organization (WHO). (2022). World Malaria Report 2022. Geneva: World Health Organization.

  • World Health Organization (WHO). (2023). Global Technical Strategy for Malaria 2016–2030. Geneva: World Health Organization.

  • United Nations. (2015). Transforming Our World: The 2030 Agenda for Sustainable Development. New York: United Nations.

  • Dinas Kesehatan Provinsi DKI Jakarta. (2025). Seksi Surveilans Epidemiologi dan Imunisasi – Surveilans Dinkes DKI Jakarta [Laman web]. Diakses dari https://surveilans-dinkes.jakarta.go.id/sarsbaru/index.php

Lampiran

Lampiran B : Peran AI dalam Pengerjaan Project

Dalam pembuatan project ini, saya dibantu dengan kecerdasan buatan seperti ChatGPT dan Gemini AI. Peran utamanya adalah

  1. Membantu penyusunan syntax di dashboard
  2. Membantu menganalisis dan memecahkan masalah error pada syntax R
  3. Memberikan beberapa panduan adaptasi syntax terhadap hal yang diinginkan.
  4. Membantu validasi serta menemukan sumber bacaan yang dapat memecahkan kebingungan selama tahap penyusunan dan analisis.

Penggunakan AI bersifat sebagai support terhadap kesulitan, bukan pengganti analisis data inti dan penulisan laporan. Semua keputusan, interpretasi, konten sepenuhnya dikerjakan oleh penulis dan tanggung jawab penulis

Lampiran C: Kode Aplikasi Dashboard Interaktif Malaria DKI Jakarta

Tampilan kode lengkap dari file app.R yang digunakan untuk membuat dashboard interaktif.

## # ===============================================
## # UAS Epidemiologi - script R Shiny
## # ===============================================
## 
## # -----------------------------------------------
## 
## library(shiny)
## library(leaflet)
## library(dplyr)
## library(readxl)
## library(plotly)
## library(DT)
## library(sf)
## library(geodata)
## library(stringr)
## library(viridis)
## library(htmltools)
## library(webshot2)
## library(htmlwidgets)
## library(ggplot2)
## library(scales)
## library(bslib)
## library(thematic)
## library(shinyWidgets)
## library(shinycssloaders)
## library(forcats)
## library(glue)
## library(tibble)
## library(tidyr)
## library(purrr)
## library(igraph)
## library(readr)
## # library(forecast) # Pastikan forecast juga dipanggil karena digunakan di server (baris 528)
## 
## thematic::thematic_on()
## 
## lab_si <- scales::label_number(scale_cut = scales::cut_si(""))
## 
## clean_label <- function(s) {
##   s <- toupper(trimws(as.character(s)))
##   s |>
##     str_replace("^KAB\\.?\\s+", "KABUPATEN ") |>
##     str_replace("^KOT\\.?\\s+", "KOTA ") |>
##     str_replace("\\s+", " ")
## }
## 
## make_key <- function(s) {
##   s |>
##     clean_label() |>
##     str_replace_all("[^A-Z0-9 ]", "") |>
##     str_replace_all("\\s+", "_")
## }
## 
## # ----------------------------------------------------
## # LOAD PETA DKI JAKARTA 
## dki_map <- st_read(
##   "Kabupaten-Kota (Provinsi Jakarta).geojson",
##   quiet = TRUE
## )
## names(dki_map)
## 
## dki_map <- dki_map |>
##   mutate(
##     kab = make_key(NAME_2)
##   ) |>
##   st_transform(4326)
## 
## std_cols <- function(x) {
##   names(x) <- names(x) |>
##     tolower() |>
##     stringr::str_replace_all("\\s+|/|\\(|\\)", "_") |>
##     stringr::str_replace_all("__+", "_") |>
##     
##     # lokasi
##     stringr::str_replace_all(
##       "kabupaten.*kota|kabupaten_kota|kab_kota|kabkot|nama_kabupaten_kota|lokasi|wilayah",
##       "lokasi"
##     ) |>
##     
##     # kasus
##     stringr::str_replace_all(
##       "^kasus$|jumlah_kasus|kasus_total|total_kasus|jumlah_kasus_malaria|kasus_malaria",
##       "total_kasus"
##     ) |>
##     
##     # incidence rate
##     stringr::str_replace_all(
##       "incidence.*rate|inc_rate|ir|angka_insidens|insidence_rate",
##       "incidence_rate"
##     ) |>
##     
##     # waktu
##     stringr::str_replace_all("^year$|^tahun_*$", "tahun") |>
##     stringr::str_replace_all("^month$|bulan_*$", "bulan")
##   
##   names(x)
##   x
## }
## 
## # -----------------------------------------------------------
## # import excel
## path_malaria <- "Malaria UAS.xlsx"
## mal_raw <- read_xlsx("Malaria UAS.xlsx") |> std_cols()
## names(mal_raw)
## stopifnot(
##   all(c("lokasi","tahun","bulan","total_kasus","incidence_rate") %in% names(mal_raw))
## )
## 
## mal_df <- mal_raw |>
##   transmute(
##     lokasi         = clean_label(lokasi),
##     tahun          = as.integer(tahun),
##     bulan          = match(
##       tolower(bulan),
##       c("januari","februari","maret","april","mei","juni",
##         "juli","agustus","september","oktober","november","desember")
##     ),
##     total_kasus    = as.integer(total_kasus),
##     incidence_rate = as.numeric(incidence_rate),
##     join_key       = make_key(lokasi)
##   ) |>
##   filter(between(tahun, 2016, 2025))
## 
## df <- mal_df
## years  <- sort(unique(mal_df$tahun))
## months <- 1:12
## kab_list <- sort(unique(df$lokasi))
## make_rollup <- function(y, m) {
##   mal_df |>
##     filter(tahun == y, bulan == m) |>
##     group_by(join_key, lokasi) |>
##     summarise(
##       kasus = sum(total_kasus, na.rm = TRUE),
##       ir    = mean(incidence_rate, na.rm = TRUE),
##       .groups = "drop"
##     )
## }
## sum_tahunan <- mal_df |>
##   group_by(tahun) |>
##   summarise(
##     total_kasus = sum(total_kasus, na.rm = TRUE),
##     avg_ir      = mean(incidence_rate, na.rm = TRUE),
##     .groups = "drop"
##   ) |>
##   arrange(tahun) |>
##   mutate(yoy = (total_kasus - lag(total_kasus)) / lag(total_kasus))
## 
## # ====================================================
## # Theme 
## # ====================================================
## app_theme <- bslib::bs_theme(
##   version      = 5,
##   primary      = "#6C5CE7",
##   secondary    = "#00C2FF",
##   success      = "#00D8A0",
##   info         = "#3EC1D3",
##   warning      = "#F6C667",
##   danger       = "#FF6B6B",
##   base_font    = bslib::font_google("Inter"),
##   heading_font = bslib::font_google("Poppins"),
##   "border-radius"       = ".9rem",
##   "btn-border-radius"   = ".9rem",
##   "body-bg"    = "#ffffff",
##   "body-color" = "#212529",
##   "card-bg"    = "#ffffff"
## )
## 
## dark_theme <- bslib::bs_theme(
##   version      = 5,
##   bg           = "#0b1220",
##   fg           = "#E6EEF6",
##   primary      = "#8A7BFF",
##   secondary    = "#00C2FF",
##   success      = "#00D8A0",
##   info         = "#3EC1D3",
##   warning      = "#F6C667",
##   danger       = "#FF6B6B",
##   base_font    = bslib::font_google("Inter"),
##   heading_font = bslib::font_google("Poppins"),
##   "border-radius"       = ".9rem",
##   "btn-border-radius"   = ".9rem",
##   "body-bg"    = "#0b1220",
##   "body-color" = "#E6EEF6",
##   "card-bg"    = "#0f1724"
## )
## 
## # ===================================
## # UI 
## # ==================================
## 
## ui <- bslib::page_navbar(
##   fillable = FALSE,
##   title = "Kasus Malaria DKI Jakarta 2016–2025",
##   theme = app_theme,
## 
##   # -------------------------------------
##   #  SIDEBAR 
##   sidebar = bslib::sidebar(
##     open  = TRUE,
##     width = 360,
##     
##     tags$h6("Filter Waktu"),
##     sliderInput(
##       "tahun", "Tahun",
##       min = min(years), max = max(years),
##       value = max(years), step = 1,
##       animate = animationOptions(interval = 2500, loop = TRUE)
##     ),
##     
##     shinyWidgets::pickerInput(
##       "bulan", "Bulan",
##       choices = setNames(
##         1:12,
##         c("Januari","Februari","Maret","April","Mei","Juni",
##           "Juli","Agustus","September","Oktober","November","Desember")
##       ),
##       selected = 1:12,
##       multiple = TRUE,
##       options = list(
##         `actions-box` = TRUE,
##         `selected-text-format` = "count > 3",
##         `count-selected-text` = "{0} bulan dipilih"
##       )
##     ),
##     
##     tags$hr(),
##     
##     tags$h6("Wilayah & Metrik"),
##     shinyWidgets::pickerInput(
##       "kab", "Kab/Kota",
##       choices = kab_list,
##       multiple = TRUE,
##       options = list(`live-search` = TRUE, `actions-box` = TRUE)
##     ),
##     
##     shinyWidgets::radioGroupButtons(
##       "metric", "Metrik",
##       choices = c("Kasus" = "cases", "Incidence Rate" = "ir"),
##       selected = "cases",
##       justified = TRUE,
##       width = "100%"
##     ),
##     
##     # Tambahkan ini di dalam sidebar, di bawah metric radio buttons
##     shinyWidgets::radioGroupButtons(
##       "model_type", "Pilih Metode Forecast",
##       choices = c("Holt-Winters" = "hw", "Auto-ARIMA" = "arima"),
##       selected = "hw",
##       justified = TRUE,
##       status = "primary",
##       width = "100%"
##     ),
##     
##     tags$hr(),
##     
##     shinyWidgets::prettyToggle(
##       "dark_mode",
##       label_on  = "Gelap",
##       label_off = "Terang",
##       icon_on   = icon("moon"),
##       icon_off  = icon("sun"),
##       plain = TRUE
##     ),
##     tags$hr(),
##     
##     tags$h6("Dokumen Pendukung"),
##     
##     tags$a(
##       href = "https://drive.google.com/file/d/1FsTSUH0YaW_Crgx2T1fb11gH3V8Z6DLw/view?usp=sharing",
##       target = "_blank",
##       class = "btn btn-primary w-100",
##       style = "margin-bottom: 10px;",
##       " Buka Laporan Tertulis"
##     )
##   ),
##   
##   # -----------------------------------------
##   # DASHBOARD 
##   bslib::nav_panel(
##     "📊 Dashboard",
##     
##     bslib::layout_columns(
##       col_widths = c(3,3,3,3),
##       
##       value_box(
##         "Total Kasus",
##         textOutput("kpi_total"),
##         showcase = icon("virus"),
##         theme = value_box_theme(bg = "#E74C3C", fg = "white")
##       ),
##       
##       value_box(
##         "Kasus Tahun Terpilih",
##         textOutput("kpi_year"),
##         showcase = icon("calendar"),
##         theme = value_box_theme(bg = "#F39C12", fg = "white")
##       ),
##       
##       value_box(
##         "Perbandingan dengan Tahun Sebelumnya",
##         textOutput("kpi_yoy"),
##         showcase = icon("chart-line"),
##         theme = value_box_theme(bg = "#2ECC71", fg = "white")
##       ),
##       
##       value_box(
##         "Wilayah Tertinggi",
##         textOutput("kpi_top"),
##         showcase = icon("location-dot"),
##         theme = value_box_theme(bg = "#3498DB", fg = "white")
##       )
##     ),
##     
##     br(),
##     
##     bslib::card(
##       bslib::card_header("Peta Sebaran"),
##       leafletOutput("map")
##     ),
##     
##     br(),
##     
##     bslib::layout_columns(
##       col_widths = c(6,6),
##       
##       bslib::card(
##         bslib::card_header("Top 3 Wilayah Risiko"),
##         plotlyOutput("rankTop")
##       ),
##       
##       bslib::card(
##         bslib::card_header("Proporsi Kasus"),
##         plotlyOutput("pie_proporsi")
##       )
##     ),
##     
##     br(),
##     
##     bslib::card(
##       bslib::card_header("Tren Tahunan"),
##       plotlyOutput("trend_plot")
##     )
##   ),
##   # ------------------------------------------
##   # LAPORAN EPIDEMIOLOGI
##   bslib::nav_panel(
##     "📑 Laporan Epidemiologi",
##     
##     bslib::layout_columns(
##       col_widths = c(6,6),
##       
##       bslib::card(
##         bslib::card_header("1. Segitiga Epidemiologi"),
##         plotOutput("epi_triangle", height = 300),
##         tags$hr(),
##         uiOutput("epi_text")
##       ),
##       
##       bslib::card(
##         bslib::card_header("3. Desain Studi & Metodologi"),
##         uiOutput("metodologi_text")
##       )
##     ),
##     
##     br(),
##     
##     bslib::layout_columns(
##       col_widths = c(6,6),
##       
##       bslib::card(
##         bslib::card_header("2. Ukuran Epidemiologi"),
##         tableOutput("ukuran_epi")
##       ),
##       
##       bslib::card(
##         bslib::card_header("4. Prediksi Incidence Rate Tahun Berikutnya"),
##         plotlyOutput("forecast_plot"),
##         tags$hr(),
##         tableOutput("forecast_table")
##       )
##     )
##   ),
##   # -------------------------------------------
##   # TABEL DATA 
##   bslib::nav_panel(
##     "📋 Tabel Data",
##     
##     bslib::card(
##       bslib::card_header("Data Kasus Malaria DKI Jakarta"),
##       DT::DTOutput("table_data")
##     )
##   )
## )
## 
## # ============================================
## # server
## # ============================================
## server <- function(input, output, session) {
##   # -------------------------------------------
##   # Theme
##   observeEvent(input$dark_mode, {
##     
##     if (isTRUE(input$dark_mode)) {
##       session$setCurrentTheme(dark_theme)
##     } else {
##       session$setCurrentTheme(app_theme)
##     }
##     
##   }, ignoreInit = TRUE)
##   
##   dff <- reactive({
##     df |>
##       filter(
##         tahun == input$tahun,
##         bulan %in% input$bulan,
##         if (length(input$kab) > 0) lokasi %in% input$kab else TRUE
##       )
##   })
##   
##   map_data <- reactive({
##     
##     df |>
##       filter(
##         tahun == input$tahun,
##         bulan %in% input$bulan
##       ) |>
##       group_by(join_key) |>
##       summarise(
##         kasus = sum(total_kasus, na.rm = TRUE),
##         ir    = mean(incidence_rate, na.rm = TRUE),
##         .groups = "drop"
##       ) |>
##       right_join(dki_map, by = c("join_key" = "kab")) |>
##       st_as_sf()
##   })
##   
##   # -------------------------------------------------------
##   # KPI 
##   output$kpi_total <- renderText({
##     format(sum(df$total_kasus, na.rm = TRUE), big.mark = ",")
##   })
##   
##   output$kpi_total_sub <- renderText({
##     "Seluruh periode"
##   })
##   
##   output$kpi_year <- renderText({
##     format(sum(dff()$total_kasus, na.rm = TRUE), big.mark = ",")
##   })
##   
##   output$kpi_year_sub <- renderText({
##     paste("Tahun", input$tahun)
##   })
##   
##   output$kpi_yoy <- renderText({
##     prev <- df |> filter(tahun == input$tahun - 1)
##     if (nrow(prev) == 0) return("NA")
##     
##     now  <- sum(dff()$total_kasus, na.rm = TRUE)
##     past <- sum(prev$total_kasus, na.rm = TRUE)
##     
##     paste0(round((now - past)/past * 100, 1), "%")
##   })
##   
##   output$kpi_top <- renderText({
##     dff() |>
##       group_by(lokasi) |>
##       summarise(val = if (input$metric == "ir")
##         mean(incidence_rate) else sum(total_kasus)) |>
##       slice_max(val) |>
##       pull(lokasi)
##   })
##   
##   output$kpi_top_sub <- renderText({
##     ifelse(input$metric == "ir", "IR tertinggi", "Kasus tertinggi")
##   })
##   
##   # --------------------------------------------------
##   # Map
##   output$map <- renderLeaflet({
##     
##     req(map_data())
##     
##     nilai <- if (input$metric == "ir") {
##       map_data()$ir
##     } else {
##       map_data()$kasus
##     }
##     
##     pal <- colorNumeric(
##       palette = "YlOrRd",
##       domain  = nilai,
##       na.color = "#f0f0f0"
##     )
##     
##     leaflet(map_data()) |>
##       addProviderTiles("CartoDB.Positron") |>
##       addPolygons(
##         fillColor   = ~pal(if (input$metric == "ir") ir else kasus),
##         fillOpacity = 0.85,
##         color       = "white",
##         weight      = 1,
##         label = ~paste0(
##           "<b>", NAME_2, "</b><br>",
##           "Kasus: ", ifelse(is.na(kasus), 0, kasus), "<br>",
##           "IR: ", round(ir, 2)
##         )
##       ) |>
##       addLegend(
##         pal = pal,
##         values = nilai,
##         title = ifelse(input$metric == "ir",
##                        "Incidence Rate",
##                        "Total Kasus")
##       )
##   })
##   
##   # ------------------------------------------
##   # TOP 3
##   output$rankTop <- renderPlotly({
##     
##     p <- dff() |>
##       group_by(lokasi) |>
##       summarise(
##         val = if (input$metric == "ir")
##           mean(incidence_rate, na.rm = TRUE)
##         else
##           sum(total_kasus, na.rm = TRUE),
##         .groups = "drop"
##       ) |>
##       slice_max(val, n = 3) |>
##       ggplot(aes(x = reorder(lokasi, val), y = val, fill = lokasi)) +
##       geom_col(show.legend = FALSE) +
##       coord_flip() +
##       labs(x = NULL, y = NULL)
##     
##     ggplotly(p)
##   })
##   # ---------------------------------------
##   # PIE 
##   output$pie_proporsi <- renderPlotly({
##     dff() |>
##       group_by(lokasi) |>
##       summarise(val = sum(total_kasus)) |>
##       plot_ly(labels = ~lokasi, values = ~val, type = "pie", hole = 0.6)
##   })
##   
##   # --------------------------------------------------
##   # TREN 
##   output$trend_plot <- renderPlotly({
##     
##     trend_df <- df |>
##       filter(
##         tahun == input$tahun,
##         if (length(input$kab) > 0) lokasi %in% input$kab else TRUE
##       ) |>
##       group_by(bulan, lokasi) |>
##       summarise(
##         val = if (input$metric == "ir")
##           mean(incidence_rate, na.rm = TRUE)
##         else
##           sum(total_kasus, na.rm = TRUE),
##         .groups = "drop"
##       ) |>
##       mutate(
##         bulan_label = factor(
##           bulan,
##           levels = 1:12,
##           labels = c(
##             "Jan","Feb","Mar","Apr","Mei","Jun",
##             "Jul","Agu","Sep","Okt","Nov","Des"
##           )
##         )
##       )
##     
##     p <- ggplot(
##       trend_df,
##       aes(
##         x = bulan_label,
##         y = val,
##         color = lokasi,
##         group = lokasi,
##         text = paste0(
##           "<b>", lokasi, "</b><br>",
##           "Bulan: ", bulan_label, "<br>",
##           ifelse(input$metric == "ir",
##                  "Incidence Rate: ",
##                  "Total Kasus: "),
##           round(val, 2)
##         )
##       )
##     ) +
##       geom_line(linewidth = 1.3) +
##       geom_point(size = 2.5) +
##       labs(
##         title = paste(
##           "Pola Bulanan",
##           ifelse(input$metric == "ir",
##                  "Incidence Rate",
##                  "Total Kasus"),
##           "Tahun", input$tahun
##         ),
##         x = "Bulan",
##         y = ifelse(
##           input$metric == "ir",
##           "Incidence Rate",
##           "Total Kasus"
##         ),
##         color = "Wilayah"
##       ) +
##       theme_minimal(base_size = 13) +
##       theme(
##         legend.position = "right",
##         plot.title = element_text(face = "bold")
##       )
##     
##     ggplotly(p, tooltip = "text") |>
##       layout(
##         hovermode = "closest",
##         legend = list(
##           title = list(text = "<b>Wilayah</b>")
##         )
##       )
##   })
##   # ----------------------------------------------
##   # Segitiga Epidemiologi 
##   output$epi_triangle <- renderPlot({
##     
##     par(mar = c(1,1,1,1))
##     
##     plot(
##       c(0, 1), c(0, 1),
##       type = "n", axes = FALSE, xlab = "", ylab = ""
##     )
##     
##     # garis penghubung
##     segments(0.5, 0.7, 0.2, 0.25, lwd = 2, col = "grey40")
##     segments(0.5, 0.7, 0.8, 0.25, lwd = 2, col = "grey40")
##     segments(0.2, 0.25, 0.8, 0.25, lwd = 2, col = "grey40")
##     
##     # kotak AGENT
##     rect(0.38, 0.72, 0.62, 0.88, col = "#E74C3C", border = NA)
##     text(0.5, 0.8, "AGENT", col = "white", font = 2, cex = 1.2)
##     
##     # kotak HOST
##     rect(0.05, 0.15, 0.35, 0.35, col = "#3498DB", border = NA)
##     text(0.2, 0.25, "HOST", col = "white", font = 2, cex = 1.2)
##     
##     # kotak ENVIRONMENT
##     rect(0.65, 0.15, 0.95, 0.35, col = "#2ECC71", border = NA)
##     text(0.8, 0.25, "ENVIRONMENT", col = "white", font = 2, cex = 1.2)
##     
##     # kotak MALARIA (tengah)
##     rect(0.38, 0.38, 0.62, 0.55, col = "#F1C40F", border = NA)
##     text(0.5, 0.465, "MALARIA", col = "black", font = 2, cex = 1.1)
##     
##   })
##   
##   # ----------------------------------------------
##   output$epi_text <- renderUI({
##     HTML("
##   <p style='margin-top:6px;'>
##   <b>Agent:</b> Agen penyebab malaria adalah <i>Plasmodium spp.</i> yang ditularkan melalui
##   gigitan nyamuk <i>Anopheles</i>.
##   </p>
## 
##   <p>
##   <b>Host:</b> Pejamu adalah penduduk DKI Jakarta yang memiliki tingkat kerentanan berbeda
##   berdasarkan usia, status imunitas, dan mobilitas.
##   </p>
## 
##   <p>
##   <b>Environment:</b> Lingkungan perkotaan dengan kepadatan penduduk tinggi,
##   urbanisasi, dan mobilitas yang intensif berperan dalam meningkatkan risiko penularan.
##   </p>
## 
##   <p>
##   <b>Interaksi:</b> Penyakit malaria terjadi akibat interaksi dinamis antara agen,
##   pejamu, dan lingkungan dalam konteks wilayah perkotaan.
##   </p>
##   ")
##   })
##   
##   # ------------------------------------------------------
##   # Desain Studi dan Metodologi
##   output$metodologi_text <- renderUI({
##     HTML("
##   <b>Desain Studi:</b>
##   Studi observasional ekologi dengan pendekatan deret waktu (ecological time series study).<br>
## 
##   <b>Unit Analisis:</b>
##   Kabupaten/Kota di Provinsi DKI Jakarta (untuk analisis spasial),
##   serta incidence rate Provinsi DKI Jakarta (untuk pemodelan deret waktu).<br>
## 
##   <b>Metodologi Analisis:</b>
##   Analisis deskriptif dilakukan untuk menggambarkan distribusi spasial dan temporal kasus malaria.
##   Pemodelan deret waktu digunakan untuk memprediksi <i>incidence rate</i> bulanan tahun 2026
##   menggunakan metode Exponential Smoothing (ETS) dengan komponen musiman
##   (Holt–Winters).<br>
## 
##   <b>Keterbatasan Studi (Bias & Confounding):</b>
##   <ul>
##     <li>
##       <b>Bias seleksi:</b> Studi ini menggunakan data agregat wilayah sehingga tidak seluruh
##       karakteristik individu dalam populasi dapat terwakili secara merata.
##     </li>
##     <li>
##       <b>Bias informasi:</b> Kemungkinan terjadi salah klasifikasi kasus atau ketidaklengkapan
##       pencatatan data, yang dapat memengaruhi estimasi incidence rate.
##     </li>
##     <li>
##       <b>Confounding:</b> Faktor lain seperti kondisi iklim, kepadatan penduduk, mobilitas,
##       dan akses layanan kesehatan tidak dianalisis secara langsung sehingga berpotensi
##       memengaruhi hubungan yang diamati.
##     </li>
##   </ul>
## 
##   <b>Rasional:</b>
##   Meskipun memiliki keterbatasan, desain ekologi deret waktu sesuai untuk mengevaluasi
##   pola temporal dan musiman penyakit menular pada tingkat populasi, serta mendukung
##   perencanaan kesehatan masyarakat.
##   ")
##   })
##   
##   # -------------------------------------------------
##   # UKURAN EPIDEMIOLOGI
##   output$ukuran_epi <- renderTable({
##     
##     data.frame(
##       `Nama Ukuran` = c(
##         "Jumlah Kasus",
##         "Incidence Rate"
##       ),
##       
##       Pengertian = c(
##         "Jumlah total kasus malaria yang tercatat pada wilayah dan periode waktu tertentu.",
##         "Ukuran frekuensi kejadian malaria yang menunjukkan jumlah kasus baru per 100.000 penduduk dalam periode tertentu."
##       ),
##       
##       Rumus = c(
##         "Jumlah seluruh kasus malaria",
##         "(Jumlah kasus baru / Jumlah penduduk) × 100.000"
##       ),
##       
##       `Contoh Interpretasi` = c(
##         "Jika tercatat 120 kasus malaria pada tahun tertentu, maka terdapat 120 penderita malaria yang dilaporkan pada periode tersebut.",
##         "Incidence rate sebesar 5 berarti terdapat 5 kasus malaria baru per 100.000 penduduk dalam periode pengamatan."
##       ),
##       
##       check.names = FALSE
##     )
##     
##   }, 
##   striped = TRUE, bordered = TRUE, hover = TRUE, spacing = "m")
##   
##   # -------------------------------------------------
##   # Pemodelan
##   ts_bulanan <- reactive({
##     df %>%
##       group_by(tahun, bulan) %>%
##       summarise(
##         ir = mean(incidence_rate, na.rm = TRUE),
##         .groups = "drop"
##       ) %>%
##       arrange(tahun, bulan)
##   })
##   hw_model <- reactive({
##     
##     d <- ts_bulanan()
##     
##     train <- d %>% filter(tahun <= 2025)
##     
##     ts_train <- ts(
##       train$ir,
##       start = c(min(train$tahun), min(train$bulan)),
##       frequency = 12
##     )
##     
##     fit_hw <- HoltWinters(
##       ts_train,
##       seasonal = "additive"
##     )
##     
##     fc_2026 <- forecast::forecast(fit_hw, h = 12)
##     
##     list(
##       ts_train = ts_train,
##       fit = fit_hw,
##       forecast = fc_2026
##     )
##   })
##   mape_hw <- reactive({
##     
##     d <- ts_bulanan()
##     
##     train <- d %>% filter(tahun <= 2024)
##     test  <- d %>% filter(tahun == 2025)
##     
##     ts_train <- ts(
##       train$ir,
##       start = c(min(train$tahun), min(train$bulan)),
##       frequency = 12
##     )
##     
##     ts_test <- ts(
##       test$ir,
##       start = c(2025, 1),
##       frequency = 12
##     )
##     
##     fit_hw <- HoltWinters(
##       ts_train,
##       seasonal = "additive"
##     )
##     
##     fc_test <- forecast::forecast(fit_hw, h = 12)
##     
##     mape <- mean(
##       abs((ts_test - fc_test$mean) / ts_test),
##       na.rm = TRUE
##     ) * 100
##     
##     round(mape, 2)
##   })
##   arima_model <- reactive({
##     d <- ts_bulanan()
##     ts_data <- ts(
##       d$ir, 
##       start = c(min(d$tahun), min(d$bulan)), 
##       frequency = 12
##     )
##     
##     # auto.arima dengan paksaan seasonal dan lambda auto
##     fit_arima <- forecast::auto.arima(
##       ts_data, 
##       seasonal = TRUE, 
##       stepwise = FALSE,   
##       approximation = FALSE, 
##       lambda = "auto"     
##     )
##     
##     fc_arima <- forecast::forecast(fit_arima, h = 12)
##     list(ts_train = ts_data, forecast = fc_arima)
##   })
##   
##   output$forecast_plot <- renderPlotly({
##     obj_hw <- hw_model()
##     obj_arima <- arima_model()
##     
##     plot_ly() %>%
##       add_lines(
##         x = time(obj_hw$ts_train),
##         y = as.numeric(obj_hw$ts_train),
##         name = "Observed (Data Asli)",
##         line = list(color = "#2c3e50", width = 2)
##       ) %>%
##       add_lines(
##         x = time(obj_hw$forecast$mean),
##         y = as.numeric(obj_hw$forecast$mean),
##         name = "Forecast 2026: Holt-Winters",
##         line = list(dash = "dash", color = "#e67e22", width = 2)
##       ) %>%
##       add_lines(
##         x = time(obj_arima$forecast$mean),
##         y = as.numeric(obj_arima$forecast$mean),
##         name = "Forecast 2026: SARIMA", # Label diperbarui
##         line = list(dash = "dot", color = "#9b59b6", width = 3)
##       ) %>%
##       layout(
##         title = list(text = "<b>Perbandingan Model Prediksi IR 2026</b>", x = 0.5),
##         xaxis = list(title = "Tahun"),
##         yaxis = list(title = "Incidence Rate"),
##         legend = list(orientation = "h", x = 0.5, xanchor = "center", y = -0.2),
##         hovermode = "x unified"
##       )
##   })
##   output$forecast_table <- renderTable({
##     fc_hw <- hw_model()$forecast
##     fc_arima <- arima_model()$forecast
##     
##     data.frame(
##       Bulan = month.abb,
##       `Prediksi Holt-Winters` = round(as.numeric(fc_hw$mean), 3),
##       `Prediksi SARIMA`       = round(as.numeric(fc_arima$mean), 3), # Nama kolom diperbarui
##       `Selisih (SARIMA-HW)`   = round(as.numeric(fc_arima$mean) - as.numeric(fc_hw$mean), 3),
##       `Lower 95% (SARIMA)`    = round(as.numeric(fc_arima$lower[,2]), 3),
##       `Upper 95% (SARIMA)`    = round(as.numeric(fc_arima$upper[,2]), 3)
##     )
##   }, striped = TRUE, bordered = TRUE, hover = TRUE, spacing = "m")
##   
##   # -------------------------------------
##   # OUTPUT TABEL DATA
##   output$table_data <- DT::renderDT({
##     
##     dat <- df %>%
##       mutate(
##         Bulan = factor(
##           bulan,
##           levels = 1:12,
##           labels = c(
##             "Januari","Februari","Maret","April","Mei","Juni",
##             "Juli","Agustus","September","Oktober","November","Desember"
##           )
##         )
##       ) %>%
##       select(
##         Lokasi = lokasi,
##         Tahun  = tahun,
##         Bulan,
##         `Jumlah Kasus` = total_kasus,
##         `Incidence Rate` = incidence_rate
##       )
##     
##     DT::datatable(
##       dat,
##       options = list(
##         pageLength = 60,
##         scrollX = TRUE,
##         autoWidth = TRUE,
##         dom = "Bfrtip",
##         buttons = c("copy", "csv", "excel", "pdf", "print")
##       ),
##       extensions = "Buttons",
##       rownames = FALSE
##     ) %>%
##       DT::formatRound(
##         columns = "Incidence Rate",
##         digits = 4
##       )
##   })
## }
## 
## # ===================================
## # END STATISTIK DESKRIPTIF 
## # ===================================
## shinyApp(ui, server)