pkgs <- c("bit64","svglite","dplyr","tidyr","stringr","forcats","ggplot2","scales","patchwork","ggrepel","gt")
invisible(lapply(pkgs, function(p){ if(!requireNamespace(p,quietly=TRUE))
  install.packages(p,quiet=TRUE,repos="https://cloud.r-project.org")
  suppressPackageStartupMessages(library(p,character.only=TRUE)) }))
BUNDLE  <- "mental_jkn_aggregates.rds"
A  <- readRDS(BUNDLE)
## coerce postgres integer64 -> numeric (safe for gt/ggplot)
fix64 <- function(x){
  if(is.data.frame(x)){ x[] <- lapply(x, function(c) if(inherits(c,"integer64")) as.numeric(c) else c); x }
  else if(is.list(x)) lapply(x, fix64)
  else if(inherits(x,"integer64")) as.numeric(x) else x }
A  <- fix64(A)
pt <- A$pt
OUT_DIR <- "outputs"; if(!dir.exists(OUT_DIR)) dir.create(OUT_DIR)

## ---- house style (palet terkunci) ----
NAVY<-"#1e3a5f"; BLUE<-"#2d5a9e"; RED<-"#dc2626"; AMBER<-"#d97706"
TEAL<-"#0f766e"; GREY<-"#6b7280"; GREEN<-"#16a34a"; PURPLE<-"#7c3aed"; ORANGE<-"#ea580c"
COLS6 <- c(NAVY,BLUE,TEAL,AMBER,RED,PURPLE)
GRP_COLS <- c("SMI – Skizofrenia/Psikotik (F20–29)"=NAVY,"SMI – Bipolar (F31)"=PURPLE,
  "SUD – Gangguan Zat (F10–19)"=RED,"Mood/Depresi (F30,F32–39)"=BLUE,"Ansietas/Stres (F40–48)"=TEAL,
  "Organik/Demensia (F00–09)"=GREY,"Perilaku/Kepribadian (F50–69)"=ORANGE,
  "Perkembangan/Anak (F70–98)"=AMBER,"Lainnya"="#9ca3af")
LVL_COLS <- c("FKTP (Primer)"=TEAL,"FKRTL Rawat Jalan"=BLUE,"FKRTL Rawat Inap"=NAVY)
ISL_COLS <- c("Jawa"=NAVY,"Sumatera"=BLUE,"Sulawesi"=TEAL,"Kalimantan"=AMBER,"Bali-Nusra"=PURPLE,"Maluku-Papua"=RED)

th <- function(b=11) theme_minimal(base_size=b) + theme(
  plot.title=element_text(color=NAVY,face="bold",size=b+2,margin=margin(b=4),family="serif"),
  plot.subtitle=element_text(color=GREY,size=b-1,lineheight=1.3),
  plot.caption=element_text(color=GREY,size=b-3,hjust=1),
  plot.background=element_rect(fill="white",color=NA),
  panel.background=element_rect(fill="#f9fafb",color=NA),
  panel.border=element_rect(color="#e5e7eb",fill=NA,linewidth=0.4),
  panel.grid.major=element_line(color="#e5e7eb",linewidth=0.3), panel.grid.minor=element_blank(),
  legend.position="bottom", strip.background=element_rect(fill=NAVY,color=NA),
  strip.text=element_text(color="white",face="bold",size=b-1))

gfmt <- function(g) g |>
  gt::tab_options(heading.background.color=NAVY, heading.title.font.size=gt::px(13),
    column_labels.background.color=BLUE, column_labels.font.weight="bold", column_labels.font.size=gt::px(11),
    row.striping.include_table_body=TRUE, row.striping.background_color="#f0f4ff",
    table.border.top.color=NAVY, table.border.top.width=gt::px(3), table.width=gt::pct(100),
    data_row.padding=gt::px(5), source_notes.font.size=gt::px(10)) |>
  gt::tab_style(style=gt::cell_text(color="white",weight="bold"),
    locations=gt::cells_column_labels(gt::everything()))

CAP <- "Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)"
fmt <- function(x) formatC(round(x), format="d", big.mark=",")
yrx <- function() scale_x_continuous(breaks=2015:2024, labels=function(x) paste0("'",substr(x,3,4)))

Unit analisis (penting — tercantum di tiap tabel/figur). Dokumen ini memakai 3 unit berbeda — perhatikan badge · Unit: … pada judul tabel & subjudul/sumbu figur: (1) Pasien unik = orang, dihitung sekali (prevalensi, demografi, peta, mortalitas, Pareto, ekuitas); (2) Kunjungan/Klaim = per layanan, satu pasien bisa banyak (volume utilisasi, tipologi, biaya, INA-CBG, komorbiditas); (3) Episode rawat inap/discharge = per perawatan inap (LOS, FUH, readmisi). Mis. Tabel L0.2 = pasien unik (tiap orang sekali, di kelompok diagnostik terberatnya), bukan total kunjungan.

Cara baca dokumen. Setiap angka populasi adalah proyeksi nasional tertimbang (PSTV15) dari data sampel; angka sampel mentah dilaporkan terpisah bila relevan. Definisi kunjungan jiwa = kode ICD-10 F00–F99 di diagnosis masuk/primer/sekunder ATAU poli jiwa (lihat Definisi kunjungan jiwa & tipologi di Layer 0 — penting karena FKL17A “primer” sering kode Z09 follow-up). Data klaim hanya menggambarkan populasi yang terlayani — bukan prevalensi sejati (lihat Treatment Gap).

Peta Pilar (navigasi): Fondasi (kohort, definisi, tipologi, treatment gap) · A Beban & Demografi · B FKTP (Layanan Primer) · C FKRTL (Rujukan/RS) · D Inter — Rujukan & Konektivitas · E Geografi Member↔︎Faskes · F Proses, Kontinuitas & Outcome · G Komorbiditas Jiwa–Fisik · H Ekonomi · I Ekuitas.
Alur kunjungan dipisah jelas: B=primer, C=rujukan/RS, D=perpindahan antar-faskes, E=geografi tempat tinggal↔︎faskes.

1 Layer 0 — Fondasi: kohort, definisi kasus, & treatment gap

⓪ Fondasi · Alur Kohort (STROBE) · Definisi F-code · Stratifikasi Diagnostik · Treatment Gap

Inti: Mendefinisikan populasi analisis (peserta cohort Mental yang punya ≥1 klaim diagnosis jiwa F00–F99), stratifikasi diagnostik berbasis keparahan, dan kerangka treatment gap — pengingat bahwa klaim JKN hanya menangkap kasus yang sampai ke fasilitas.
Sumber & desain: Data Sampel BPJS Kesehatan 2015–2024, cohort Mental; identifikasi pasien via PSTV01; bobot nasional PSTV15; demografi via codebook resmi (PSTV05 jenis kelamin, PSTV08 segmentasi, PSTV07 kelas, PSTV09 provinsi tempat tinggal, PSTV18 tahun meninggal).

cf <- A$cohort_flow
flow <- data.frame(
  Tahap=c("Cohort Mental (peserta tersampel)","Punya ≥1 klaim FKRTL (semua sebab)",
          "Pasien dengan ≥1 klaim F-code di FKRTL","Pasien dengan ≥1 klaim F-code di FKTP",
          "KOHORT ANALISIS — ≥1 klaim F-code (FKTP/FKRTL)"),
  `Pasien (sampel mentah)`=c(cf$member_cohort,cf$any_fkrtl_claim,cf$fkrtl_fcode_pts,cf$fktp_fcode_pts,cf$analytic_cohort),
  check.names=FALSE)
gt::gt(flow) |>
  gt::tab_header(title=gt::md("**Tabel L0.1 — Alur Pembentukan Kohort (STROBE)** · _Unit: Pasien unik (sampel)_"),
    subtitle=gt::md("_Angka sampel mentah (pasien unik), cohort Mental BPJS 2015–2024_")) |>
  gt::fmt_number(columns=2, decimals=0, use_seps=TRUE) |>
  gt::data_color(columns=2, colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel L0.1 — Alur Pembentukan Kohort (STROBE) · Unit: Pasien unik (sampel)
Angka sampel mentah (pasien unik), cohort Mental BPJS 2015–2024
Tahap Pasien (sampel mentah)
Cohort Mental (peserta tersampel) 136,769
Punya ≥1 klaim FKRTL (semua sebab) 115,531
Pasien dengan ≥1 klaim F-code di FKRTL 102,812
Pasien dengan ≥1 klaim F-code di FKTP 92,643
KOHORT ANALISIS — ≥1 klaim F-code (FKTP/FKRTL) 122,372
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)

1.1 Tabel 1 — Karakteristik Sampel (FKTP · FKRTL · Overall · Populasi Umum)

Karakteristik pasien jiwa (FKTP, FKRTL, Overall = kohort F-code) dibandingkan populasi JKN umum (Populasi Umum = sample reguler BPJS, ~2,6 juta peserta mewakili seluruh peserta JKN). Ini menunjukkan siapa yang terlayani jiwa relatif terhadap populasi umum. Angka = % per kolom (tertimbang). “Kelompok Diagnostik” kosong (“—”) untuk Populasi Umum (tak punya diagnosis jiwa).
n1 <- A$table1_n
gt::gt(A$table1, groupname_col="char", rowname_col="level") |>
  gt::tab_header(title=gt::md("**Tabel 1 — Karakteristik Pasien Jiwa vs Populasi JKN Umum** · _Unit: Pasien unik (tertimbang), % per kolom_"),
    subtitle=gt::md(sprintf("_FKTP n=%s · FKRTL n=%s · Overall n=%s · Populasi Umum n=%s (peserta sampel)_",
      formatC(n1$raw[n1$kolom=="FKTP"],format="d",big.mark=","),
      formatC(n1$raw[n1$kolom=="FKRTL"],format="d",big.mark=","),
      formatC(n1$raw[n1$kolom=="Overall"],format="d",big.mark=","),
      formatC(n1$raw[n1$kolom=="GeneralPop"],format="d",big.mark=",")))) |>
  gt::cols_label(FKTP="FKTP %", FKRTL="FKRTL %", Overall="Overall %", GeneralPop="Populasi Umum %") |>
  gt::fmt_number(columns=c(FKTP,FKRTL,Overall,GeneralPop), decimals=1) |>
  gt::sub_missing(columns=everything(), missing_text="—") |>
  gt::data_color(columns=Overall, colors=scales::col_numeric(c("#eef2ff","#1e3a5f"),domain=NULL)) |>
  gt::data_color(columns=GeneralPop, colors=scales::col_numeric(c("#f0fdf4","#16a34a"),domain=NULL)) |>
  gt::tab_source_note(gt::md(paste(CAP,"| Populasi Umum = sample reguler BPJS (semua peserta JKN); Overall = kohort jiwa F-code; FKTP/FKRTL = pengguna layanan"))) |> gfmt()
Tabel 1 — Karakteristik Pasien Jiwa vs Populasi JKN Umum · Unit: Pasien unik (tertimbang), % per kolom
FKTP n=92,643 · FKRTL n=102,812 · Overall n=122,372 · Populasi Umum n=2,590,751 (peserta sampel)
FKTP % FKRTL % Overall % Populasi Umum %
Jenis Kelamin
Perempuan 56.7 56.6 56.7 48.8
Laki-laki 43.3 43.4 43.3 51.2
Kelompok Usia
18–39 40.8 35.8 36.4 37.1
40–59 27.9 27.3 28.2 27.7
<18 20.9 23.5 22.1 18.5
≥60 10.4 13.4 13.3 16.7
Segmentasi (Membership)
PBI APBN 31.4 27.1 29.5 41.3
PPU 23.7 24.7 24.3 23.2
PBPU (Mandiri) 21.7 23.9 22.0 11.6
PBI APBD 19.4 19.1 19.4 20.1
Bukan Pekerja 3.7 5.2 4.8 3.9
Kelas Rawat
Kelas III 67.4 63.9 65.3 70.1
Kelas I 19.4 21.8 20.8 16.3
Kelas II 13.2 14.3 13.9 13.6
Pulau
Jawa 61.0 61.0 61.0 54.2
Sumatera 18.9 18.4 18.7 20.7
Sulawesi 7.6 7.7 7.7 7.6
Kalimantan 6.8 6.9 6.7 5.7
Bali-Nusra 4.9 5.0 4.9 5.4
Maluku-Papua 0.8 1.0 1.0 6.4
Kelompok Diagnostik
SMI – Skizofrenia/Psikotik (F20–29) 48.8 39.8 40.5
Ansietas/Stres (F40–48) 18.5 20.0 21.2
Perkembangan/Anak (F70–98) 16.7 21.3 19.1
Mood/Depresi (F30,F32–39) 7.3 7.8 7.4
Organik/Demensia (F00–09) 2.5 6.2 5.6
Perilaku/Kepribadian (F50–69) 3.1 2.0 3.5
SMI – Bipolar (F31) 2.3 2.3 2.0
SUD – Gangguan Zat (F10–19) 0.7 0.5 0.7
Lainnya 0.0 0.0
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | Populasi Umum = sample reguler BPJS (semua peserta JKN); Overall = kohort jiwa F-code; FKTP/FKRTL = pengguna layanan
Key takeaway (vs populasi umum): Pasien jiwa lebih perempuan (56,7% vs 48,8%), lebih muda, dan — penting — lebih sedikit dari segmen termiskin (PBI APBN 29,5% vs 41,3% populasi umum), lebih banyak mandiri/PBPU (22% vs 11,6%) → sinyal akses jiwa condong ke yang mampu bayar. Geografis sangat timpang: Jawa 61% vs 54%, Maluku-Papua 1,0% vs 6,4% → wilayah timur jauh under-served untuk kesehatan jiwa.

1.2 Stratifikasi diagnostik (diagnosis paling berat per pasien)

Aturan stratifikasi

Tiap pasien diberi satu kelompok primer = diagnosis F-code paling berat yang pernah tercatat, dengan prioritas klinis: SMI-Skizofrenia (F20–29) › SMI-Bipolar (F31) › SUD (F10–19) › Mood/Depresi (F30,F32–39) › Ansietas (F40–48) › Organik (F00–09) › Perilaku/Kepribadian (F50–69) › Perkembangan/Anak (F70–98). Tab: Total kumulatif (hati-hati — over-state tahun-seed) vs Per Tahun.

1.2.1 Total (kumulatif)

sp <- A$strata_patient |> mutate(grp=as.character(grp))
gt::gt(sp) |>
  gt::cols_label(grp="Kelompok Diagnostik Primer", weighted="Pasien (tertimbang)",
                 raw="Pasien (sampel)", pct_w="Proporsi (%)") |>
  gt::tab_header(title=gt::md("**Tabel L0.2 — Distribusi Kelompok Diagnostik Primer** · _Unit: Pasien unik (tertimbang)_")) |>
  gt::fmt_number(columns=c(weighted,raw),decimals=0,use_seps=TRUE) |>
  gt::data_color(columns=weighted, colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel L0.2 — Distribusi Kelompok Diagnostik Primer · Unit: Pasien unik (tertimbang)
Kelompok Diagnostik Primer Pasien (tertimbang) Pasien (sampel) Proporsi (%)
SMI – Skizofrenia/Psikotik (F20–29) 1,071,302 45,211 40.5
Ansietas/Stres (F40–48) 560,869 29,087 21.2
Perkembangan/Anak (F70–98) 506,310 22,279 19.1
Mood/Depresi (F30,F32–39) 195,198 13,591 7.4
Organik/Demensia (F00–09) 146,973 5,915 5.6
Perilaku/Kepribadian (F50–69) 92,069 3,516 3.5
SMI – Bipolar (F31) 53,818 2,050 2.0
SUD – Gangguan Zat (F10–19) 17,614 713 0.7
Lainnya 189 10 0.0
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
sp2 <- sp |> mutate(grp=fct_reorder(grp,weighted))
ggplot(sp2, aes(weighted, grp, fill=grp)) +
  geom_col(width=.72) +
  geom_text(aes(label=paste0(fmt(weighted)," (",pct_w,"%)")), hjust=-0.05, size=3, color=NAVY, fontface="bold") +
  scale_fill_manual(values=GRP_COLS, guide="none") +
  scale_x_continuous(labels=label_number(scale_cut=cut_short_scale()),
                     expand=expansion(mult=c(0,.18)), limits=c(0,NA)) +
  labs(title="Beban Gangguan Jiwa Terlayani JKN menurut Kelompok Diagnostik · Unit: pasien unik",
       subtitle="Pasien unik tertimbang (proyeksi nasional), kohort kumulatif 2015–2024",
       x="Pasien (tertimbang)", y=NULL, caption=CAP) + th()

1.2.2 Per Tahun

py <- A$prev_year |> dplyr::filter(!is.na(grp)) |> dplyr::mutate(grp=factor(as.character(grp), levels=A$meta$rank_lab))
ggplot(py, aes(yr, wt_pts, fill=grp)) + geom_area(alpha=.9, color="white", linewidth=.2) +
  scale_fill_manual(values=GRP_COLS, name=NULL) +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()), expand=expansion(mult=c(0,.05))) +
  guides(fill=guide_legend(nrow=3)) +
  labs(title="Kelompok Diagnostik Terlayani per Tahun (tertimbang) · Unit: pasien unik/tahun",
       subtitle="Komposisi tiap tahun (pasien unik per tahun, bukan kumulatif). ⚠ Tahun terkini over-state (artefak seed) — lihat Validasi Desain Sampel.",
       x=NULL, y="Pasien jiwa (tertimbang)", caption=CAP) + th()

1.3 Definisi kunjungan jiwa & tipologi (penting)

Bagaimana sebuah kunjungan disebut “kunjungan jiwa”

Verifikasi field menunjukkan FKL15A “diagnosis masuk” = diagnosis klinis sebenarnya (mis. F20 Schizophrenia), sedangkan FKL17A “diagnosis primer” 99% berisi kode Z (Z09 “follow-up”, administratif) untuk kunjungan kontrol. Karena itu kunjungan dihitung kunjungan jiwa bila kode F (F00–F99) muncul di diagnosis masuk, primer, atau sekunder (SDX), ATAU dilayani di poli jiwa (FKL11: JIW/JWA/PSK). Definisi ini menangkap kontrol rutin psikiatri (ber-primer Z09) dan komorbiditas jiwa pada kunjungan fisik — yang akan hilang bila hanya memakai diagnosis primer.

vt <- A$visit_typology |> mutate(pct=round(100*wt/sum(wt),1),
  vtype=stringr::str_remove(vtype,"^Mental: "))
gt::gt(vt) |>
  gt::cols_label(vtype="Tipe kunjungan jiwa (FKRTL)",raw="Kunjungan (sampel)",wt="Kunjungan (tertimbang)",pct="%") |>
  gt::tab_header(title=gt::md("**Tabel L0.4 — Tipologi Kunjungan Jiwa menurut Intensitas/Sumber Kode** · _Unit: Kunjungan FKRTL (tertimbang)_")) |>
  gt::fmt_number(columns=c(raw,wt),decimals=0,use_seps=TRUE) |>
  gt::data_color(columns=wt,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(paste(CAP,"| terapi aktif=primer F (psikoterapi); kontrol=masuk F + primer Z09; sekunder=F di SDX; poli jiwa=tanpa kode F"))) |> gfmt()
Tabel L0.4 — Tipologi Kunjungan Jiwa menurut Intensitas/Sumber Kode · Unit: Kunjungan FKRTL (tertimbang)
Tipe kunjungan jiwa (FKRTL) Kunjungan (sampel) Kunjungan (tertimbang) %
kontrol/pemeliharaan (masuk F) 1,129,827 24,950,319 73.8
komorbid sekunder (SDX F) 327,777 6,530,758 19.3
terapi aktif (primer F) 113,763 2,197,085 6.5
poli jiwa (tanpa kode F) 9,103 144,531 0.4
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | terapi aktif=primer F (psikoterapi); kontrol=masuk F + primer Z09; sekunder=F di SDX; poli jiwa=tanpa kode F
LV <- c("Mental: terapi aktif (primer F)","Mental: kontrol/pemeliharaan (masuk F)",
        "Mental: komorbid sekunder (SDX F)","Mental: poli jiwa (tanpa kode F)")
vty <- A$visit_typology_year |> filter(vtype %in% LV) |>
  mutate(vtype=factor(stringr::str_remove(vtype,"^Mental: "),
                      levels=stringr::str_remove(LV,"^Mental: ")))
ggplot(vty, aes(yr, wt, fill=vtype)) + geom_area(position="fill", color="white", linewidth=.2) +
  annotate("rect", xmin=2016.5, xmax=2019.5, ymin=0, ymax=1, fill=NA, color=RED, linetype="dashed", linewidth=.5) +
  annotate("text", x=2018, y=1.04, label="patahan koding 2017–2019", color=RED, size=2.8, fontface="italic") +
  scale_fill_manual(values=c("terapi aktif (primer F)"=GREEN,"kontrol/pemeliharaan (masuk F)"=BLUE,
    "komorbid sekunder (SDX F)"=AMBER,"poli jiwa (tanpa kode F)"=GREY), name=NULL) +
  yrx() + scale_y_continuous(labels=scales::percent, expand=expansion(mult=c(0,.06))) +
  guides(fill=guide_legend(nrow=2)) +
  labs(title="Komposisi Tipe Kunjungan Jiwa FKRTL per Tahun · Unit: kunjungan",
       subtitle="Proporsi kunjungan. ⚠ Patahan 2017–2019 = kemungkinan perubahan koding/struktur data, bukan murni tren klinis.",
       x=NULL, y="Proporsi kunjungan", caption=CAP) + th()

Key takeaway tipologi: Hanya 6.5% kunjungan jiwa FKRTL terkode terapi aktif (psikoterapi); mayoritas (73.8%) terkode kontrol/pemeliharaan, dan 19.3% komorbiditas jiwa pada kunjungan fisik. Pola ini sebagian mencerminkan praktik koding (kode Z09 vs kode terapi spesifik), bukan murni intensitas klinis — perhatikan patahan 2018–2019 pada figur (kemungkinan perubahan koding/struktur data). Tetap mengindikasikan layanan lebih banyak pemeliharaan/refill daripada terapi intensif, tetapi besarannya jangan ditafsir sebagai “kualitas terapi menurun”.

1.4 Treatment gap — klaim hanya menangkap yang terlayani

Keterbatasan utama (wajib diingat di seluruh dokumen). Angka di bawah adalah kasus yang sampai ke fasilitas dan diklaimkan ke JKN. Prevalensi gangguan jiwa sejati di masyarakat jauh lebih tinggi — mayoritas tidak pernah masuk sistem (stigma, akses, layanan komunitas/keagamaan/tradisional, pasung di rumah yang tak terlihat di klaim). Klaim TIDAK dapat mengestimasi prevalensi sejati.

## Benchmark prevalensi komunitas (Riskesdas 2018) vs terlayani (proyeksi tertimbang)
POP_ADULT <- 190e6  # perkiraan penduduk >=15 th Indonesia (~190 juta)
served_dep  <- A$strata_patient$weighted[A$strata_patient$grp=="Mood/Depresi (F30,F32–39)"]
served_smi  <- A$strata_patient$weighted[grepl("Skizofrenia",A$strata_patient$grp)]
gap <- tibble::tibble(
  Indikator=c("Depresi (penduduk ≥15 th)","Gangguan jiwa berat / Skizofrenia-psikotik"),
  `Prevalensi komunitas (Riskesdas 2018)`=c("6,1%","0,7% rumah tangga (≈1,8‰ penduduk)"),
  `Perkiraan kasus nasional`=c(fmt(0.061*POP_ADULT),fmt(0.0018*POP_ADULT)),
  `Terlayani JKN (kumulatif, tertimbang)`=c(fmt(served_dep),fmt(served_smi)),
  `Rasio terlayani (ilustratif)`=c(paste0(round(100*served_dep/(0.061*POP_ADULT),1),"%"),
                                   paste0(round(100*served_smi/(0.0018*POP_ADULT),1),"%")))
gt::gt(gap) |>
  gt::tab_header(title=gt::md("**Tabel L0.3 — Triangulasi Treatment Gap (ilustratif)** · _Unit: Pasien (kumulatif, tertimbang)_"),
    subtitle=gt::md("_Terlayani-kumulatif JKN vs prevalensi komunitas; benchmark Riskesdas 2018_")) |>
  gt::tab_source_note(gt::md("Benchmark: Riskesdas 2018 (depresi ≥15 th 6,1%; gangguan jiwa berat 7‰ rumah tangga). Penyebut populasi & sifat kumulatif berbeda dari prevalensi titik komunitas — angka rasio bersifat ilustratif, bukan estimasi gap presisi.")) |> gfmt()
Tabel L0.3 — Triangulasi Treatment Gap (ilustratif) · Unit: Pasien (kumulatif, tertimbang)
Terlayani-kumulatif JKN vs prevalensi komunitas; benchmark Riskesdas 2018
Indikator Prevalensi komunitas (Riskesdas 2018) Perkiraan kasus nasional Terlayani JKN (kumulatif, tertimbang) Rasio terlayani (ilustratif)
Depresi (penduduk ≥15 th) 6,1% 11,590,000 195,198 1.7%
Gangguan jiwa berat / Skizofrenia-psikotik 0,7% rumah tangga (≈1,8‰ penduduk) 342,000 1,071,302 313.2%
Benchmark: Riskesdas 2018 (depresi ≥15 th 6,1%; gangguan jiwa berat 7‰ rumah tangga). Penyebut populasi & sifat kumulatif berbeda dari prevalensi titik komunitas — angka rasio bersifat ilustratif, bukan estimasi gap presisi.
Key takeaway L0: Kohort analisis mencakup 122,372 pasien sampel dengan diagnosis jiwa F-code. Skizofrenia/psikotik (SMI) dan ansietas/mood mendominasi. Catatan komposisi: kelompok Perkembangan/Anak (F70–98) ~19% dan ±15% pasien berusia <10 tahun — sebagian besar beban ini neurodevelopmental (autisme/ADHD/disabilitas intelektual), bukan psikiatri klasik; pisahkan saat membandingkan ke prevalensi depresi/skizofrenia komunitas. Triangulasi Riskesdas menunjukkan treatment gap besar, terutama depresi.

2 Pilar A — Beban Penyakit & Demografi

① Pilar 1 · Prevalensi Terlayani · Insidensi · Demografi (Tabel 1) · Distribusi Geografis
Pertanyaan: Seberapa besar beban gangguan jiwa yang terlayani JKN, bagaimana trennya, profil demografinya, dan sebarannya secara geografis.

2.1 Validasi desain sampel — kohort vs reguler (WAJIB dibaca sebelum tren)

Isu desain sampel (krusial — menentukan analisis mana yang sahih). Cohort mental adalah tarikan INDIVIDU yang diperkaya & di-seed pada tahun frame (bukan sampel rumah tangga). Verifikasi langsung di DB: cohort mental = 1.00 individu/rumah-tangga (vs reguler 2.43 = sampel household sejati), seed tahun 2023, dan hanya 1.1% overlap dengan reguler. Akibatnya tren per-tahun/kumulatif kohort = artefak konstruksi sampel (over-state tahun-seed). Tren & rate populasi yang sahih harus diambil dari reguler (sampel 1% rumah tangga, kontinu). Kohort tetap dipakai untuk kedalaman cross-section (kaskade, komorbiditas, biaya, ekuitas relatif).

xd <- A$xcheck$design
dtab <- tibble::tibble(
  Indikator=c("Individu (sampel)","Rumah tangga","Individu per rumah tangga","Overlap dgn reguler","Tahun seed sampel"),
  `Kohort Mental`=c(scales::comma(xd$cohort_indiv), scales::comma(xd$cohort_hh), sprintf("%.2f",xd$cohort_per_hh), paste0(xd$overlap_pct,"%"), xd$seed_year),
  `Reguler (household)`=c(scales::comma(xd$reguler_indiv), scales::comma(xd$reguler_hh), sprintf("%.2f",xd$reguler_per_hh), "—", "kontinu"))
gt::gt(dtab) |> gt::tab_header(title=gt::md("**Tabel L0.1b — Diagnostik Desain Sampel: Kohort vs Reguler** · _Unit: peserta sampel_"),
  subtitle=gt::md("_Kohort = enriched individual draw (1 indiv/RT, seed-year); Reguler = household sample (tren tak-bias)_")) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel L0.1b — Diagnostik Desain Sampel: Kohort vs Reguler · Unit: peserta sampel
Kohort = enriched individual draw (1 indiv/RT, seed-year); Reguler = household sample (tren tak-bias)
Indikator Kohort Mental Reguler (household)
Individu (sampel) 136,769 2,590,751
Rumah tangga 136,107 1,065,281
Individu per rumah tangga 1.00 2.43
Overlap dgn reguler 1.1%
Tahun seed sampel 2023 kontinu
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
cmp <- dplyr::bind_rows(
  A$xcheck$trend_reguler |> dplyr::transmute(yr, N=as.numeric(wt), sampel="Reguler (household, TAK-BIAS)"),
  A$xcheck$trend_cohort  |> dplyr::transmute(yr, N=as.numeric(wt), sampel="Kohort (enriched, seed → bias)")) |>
  dplyr::filter(yr>=2015, yr<=2024)
ggplot(cmp, aes(yr, N, color=sampel)) + geom_line(linewidth=1.1) + geom_point(size=2) +
  annotate("rect", xmin=A$xcheck$design$seed_year-0.5, xmax=2024.5, ymin=0, ymax=Inf, fill=AMBER, alpha=.10) +
  scale_color_manual(values=c("Reguler (household, TAK-BIAS)"=NAVY,"Kohort (enriched, seed → bias)"=AMBER), name=NULL) +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()), limits=c(0,NA), expand=expansion(mult=c(0,.1))) +
  guides(color=guide_legend(nrow=2)) +
  labs(title="Divergensi Tren: Kohort vs Reguler (pasien jiwa terlayani FKRTL/tahun) · Unit: pasien unik/tahun",
       subtitle=sprintf("Cocok ~tahun-seed (%s), divergen tajam di tahun terkini — kohort over-state, reguler = tren sahih. Pakai REGULER untuk tren.", A$xcheck$design$seed_year),
       x=NULL, y="Pasien jiwa FKRTL (tertimbang)", caption=CAP) + th()

Implikasi: Tren prevalensi/insidensi kohort di bawah over-state tahun terkini (artefak seed 2023). Garis reguler (NAVY) = tren tak-bias (naik halus, dip COVID). Baca semua tren kohort sebagai “kohort terlayani anchored ~2023”, dan rujuk garis reguler untuk arah sebenarnya. Served-rate spasial & gradien SES (Pilar I) kini disajikan basis reguler (numerator+denominator sefrekuensi).

2.2 Ukuran epidemiologi dasar (insidensi, prevalensi, kumulatif)

Definisi & denominator

Prevalensi terlayani (periode, tahunan) = pasien unik dengan ≥1 klaim F-code pada tahun tsb. · Insidensi terlayani = pasien dengan kontak F-code pertama pada tahun tsb (washout berbasis riwayat dalam dataset; 2015 left-censored → campuran insiden+prevalen, ditandai). · Kumulatif teridentifikasi = akumulasi pasien unik yang pernah teridentifikasi. · Populasi aktif = kumulatif − kematian kumulatif (kematian in-hospital FKL14=3; undercount → aktif = batas atas). · Denominator rate = jumlah peserta JKN per tahun (BPJS Kesehatan/DJSN, akhir tahun, ≈) — karena klaim hanya timbul dari peserta JKN dan bobot PSTV15 memproyeksikan ke populasi peserta. Rate dinyatakan per 100.000 peserta JKN.

Peringatan interpretasi tren (penting). Kohort sampel ini berbasis frame kepesertaan terkini (snapshot 2023–2024), sehingga: (1) tahun-tahun awal under-observed (peserta yang keluar JKN/meninggal sebelum sampling tak terlihat — left-truncation); (2) banyak pasien tampak “baru” di 2023–2024 karena akrual/perluasan sampel, bukan kasus insiden sejati (insidensi terlayani 2024 = 96,8% dari prevalen — tidak masuk akal secara epidemiologis). Akibatnya tren insidensi/prevalensi naik berlebihan. Yang paling andal: level cross-sectional 2024 (tahun frame, paling lengkap) dan plateau insidensi-terlayani 2016–2021 (~20–26/100k). Lonjakan 2022–2024 sebagian besar artefak konstruksi sampel, bukan kenaikan insidensi.

## Denominator peserta JKN per tahun (juta; BPJS Kesehatan/DJSN, akhir tahun, perkiraan)
denom <- tibble::tibble(
  yr  = 2015:2024,
  jkn = c(156.79,171.94,187.98,208.05,224.15,222.46,235.72,248.77,267.31,277.86)*1e6,
  pop = c(255.6,258.7,261.9,265.0,268.1,270.2,272.7,275.8,278.7,281.6)*1e6)
inc <- pt |> dplyr::count(yr=first_yr, wt=w, name="incident_wt") |> dplyr::filter(yr>=2015, yr<=2024)
prev <- A$prev_year_total |> dplyr::select(yr, prevalent_wt=wt_pts)
deaths <- A$mort_inhosp |> dplyr::transmute(yr, deaths_wt=wt_deaths)
epi <- inc |> dplyr::left_join(prev,by="yr") |> dplyr::left_join(deaths,by="yr") |>
  dplyr::left_join(denom,by="yr") |> dplyr::arrange(yr) |>
  dplyr::mutate(
    deaths_wt   = dplyr::coalesce(deaths_wt,0),
    cum_ident   = cumsum(incident_wt),
    cum_deaths  = cumsum(deaths_wt),
    aktif       = cum_ident - cum_deaths,
    inc_100k    = round(incident_wt/jkn*1e5,1),
    prev_100k   = round(prevalent_wt/jkn*1e5,1),
    yoy_prev    = round((prev_100k-dplyr::lag(prev_100k))/dplyr::lag(prev_100k)*100,1),
    YoY         = dplyr::if_else(is.na(yoy_prev),"—",paste0(ifelse(yoy_prev>0,"+",""),yoy_prev,"%")))
write.csv(epi, file.path(OUT_DIR,"T1_0_epidemiologi_dasar.csv"), row.names=FALSE)
ep <- epi |> dplyr::transmute(Tahun=yr, `Kasus baru (tertimbang)`=incident_wt,
  `Prevalen terlayani (tertimbang)`=prevalent_wt, `Kumulatif teridentifikasi`=cum_ident,
  `Insidensi /100k JKN`=inc_100k, `Prevalensi /100k JKN`=prev_100k, `YoY prevalensi`=YoY)
gt::gt(ep) |>
  gt::tab_header(title=gt::md("**Tabel 1.0 — Ukuran Epidemiologi Gangguan Jiwa Terlayani JKN** · _Unit: Pasien unik (tertimbang)_"),
    subtitle=gt::md("_Tertimbang PSTV15; rate per 100.000 peserta JKN; 2015 left-censored_")) |>
  gt::fmt_number(columns=c(`Kasus baru (tertimbang)`,`Prevalen terlayani (tertimbang)`,`Kumulatif teridentifikasi`),decimals=0,use_seps=TRUE) |>
  gt::fmt_number(columns=c(`Insidensi /100k JKN`,`Prevalensi /100k JKN`),decimals=1) |>
  gt::data_color(columns=`Prevalensi /100k JKN`,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::data_color(columns=`Insidensi /100k JKN`,colors=scales::col_numeric(c("#ecfdf5","#16a34a"),domain=NULL)) |>
  gt::tab_style(style=gt::cell_fill(color="#fef9c3"),locations=gt::cells_body(rows=Tahun==2015)) |>
  gt::tab_source_note(gt::md(paste(CAP,"| Denominator: peserta JKN akhir tahun (BPJS Kesehatan/DJSN, ≈). Baris 2015 disorot = left-censored (insidensi overestimate)."))) |> gfmt()
Tabel 1.0 — Ukuran Epidemiologi Gangguan Jiwa Terlayani JKN · Unit: Pasien unik (tertimbang)
Tertimbang PSTV15; rate per 100.000 peserta JKN; 2015 left-censored
Tahun Kasus baru (tertimbang) Prevalen terlayani (tertimbang) Kumulatif teridentifikasi Insidensi /100k JKN Prevalensi /100k JKN YoY prevalensi
2015 83,807 82,736 83,807 53.5 52.8
2016 37,467 107,345 121,273 21.8 62.4 +18.2%
2017 42,096 139,061 163,369 22.4 74.0 +18.6%
2018 45,568 173,114 208,938 21.9 83.2 +12.4%
2019 49,989 211,997 258,927 22.3 94.6 +13.7%
2020 47,837 243,519 306,764 21.5 109.5 +15.8%
2021 68,073 302,343 374,837 28.9 128.3 +17.2%
2022 139,341 444,318 514,178 56.0 178.6 +39.2%
2023 527,079 1,032,023 1,041,257 197.2 386.1 +116.2%
2024 1,603,084 1,653,357 2,644,341 576.9 595.0 +54.1%
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | Denominator: peserta JKN akhir tahun (BPJS Kesehatan/DJSN, ≈). Baris 2015 disorot = left-censored (insidensi overestimate).
er <- epi |> dplyr::select(yr, `Insidensi terlayani`=inc_100k, `Prevalensi terlayani`=prev_100k) |>
  tidyr::pivot_longer(-yr, names_to="ukuran", values_to="rate")
ggplot(er, aes(yr, rate, color=ukuran)) +
  annotate("rect", xmin=2021.5, xmax=2024.5, ymin=0, ymax=Inf, fill=AMBER, alpha=.10) +
  annotate("text", x=2023, y=max(er$rate)*0.55, label="zona akrual sampel\n(insidensi overestimate)",
           color=AMBER, size=3, fontface="italic", lineheight=.9) +
  geom_line(linewidth=1.1) + geom_point(size=2) +
  geom_text(data=dplyr::filter(er, yr %in% c(2016,2021,2024)), aes(label=rate),
            vjust=-0.8, size=2.8, fontface="bold", show.legend=FALSE) +
  scale_color_manual(values=c("Insidensi terlayani"=TEAL,"Prevalensi terlayani"=NAVY), name=NULL) +
  yrx() + scale_y_continuous(limits=c(0,NA), expand=expansion(mult=c(0,.14))) +
  labs(title="Insidensi & Prevalensi Gangguan Jiwa Terlayani JKN, per 100.000 Peserta · Unit: pasien unik /100k",
       subtitle="Numerator tertimbang PSTV15 / peserta JKN tahunan. Tren naik berlebihan (left-truncation + akrual sampel); 2016–2021 plateau insidensi paling interpretable, 2024 = level cross-sectional terandal.",
       x=NULL, y="Per 100.000 peserta JKN", caption=CAP) + th()

cm <- epi |> dplyr::select(yr, `Kumulatif teridentifikasi`=cum_ident, `Populasi aktif (≈)`=aktif) |>
  tidyr::pivot_longer(-yr, names_to="Status", values_to="N")
ggplot(cm, aes(yr, N, fill=Status)) +
  geom_col(data=dplyr::filter(cm,Status=="Kumulatif teridentifikasi"), fill=BLUE, alpha=.25, width=.7) +
  geom_line(aes(color=Status), linewidth=1.1) + geom_point(aes(color=Status), size=2) +
  geom_text(data=dplyr::filter(cm, yr==2024), aes(label=label_number(scale_cut=cut_short_scale())(N), color=Status),
            hjust=-0.1, size=3, fontface="bold", show.legend=FALSE) +
  scale_color_manual(values=c("Kumulatif teridentifikasi"=NAVY,"Populasi aktif (≈)"=GREEN), name=NULL) +
  scale_fill_manual(values=c("Kumulatif teridentifikasi"=BLUE), guide="none") +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()), limits=c(0,NA), expand=expansion(mult=c(0,.15))) +
  labs(title="Populasi Kumulatif Pasien Gangguan Jiwa Teridentifikasi JKN · Unit: pasien unik",
       subtitle="Kumulatif teridentifikasi vs populasi aktif (kumulatif − kematian in-hospital; kematian undercount → aktif = batas atas)",
       x=NULL, y="Pasien (tertimbang)", caption=CAP) + th()

2.3 Insidensi & prevalensi menurut kelompok diagnostik (2024)

jkn24 <- denom$jkn[denom$yr==2024]
gr24 <- A$prev_year |> dplyr::filter(yr==2024, !is.na(grp)) |> dplyr::mutate(grp=as.character(grp),
  prev_100k=round(wt_pts/jkn24*1e5,1)) |> dplyr::arrange(dplyr::desc(prev_100k)) |>
  dplyr::select(grp, wt_pts, prev_100k)
gt::gt(gr24) |>
  gt::cols_label(grp="Kelompok Diagnostik", wt_pts="Prevalen 2024 (tertimbang)", prev_100k="Prevalensi /100k JKN") |>
  gt::tab_header(title=gt::md("**Tabel 1.0b — Prevalensi Terlayani 2024 menurut Kelompok Diagnostik** · _Unit: Pasien unik (tertimbang)_")) |>
  gt::fmt_number(columns=wt_pts,decimals=0,use_seps=TRUE) |>
  gt::fmt_number(columns=prev_100k,decimals=1) |>
  gt::data_color(columns=prev_100k,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(paste(CAP,"| per 100.000 peserta JKN 2024 (≈277,9 juta)"))) |> gfmt()
Tabel 1.0b — Prevalensi Terlayani 2024 menurut Kelompok Diagnostik · Unit: Pasien unik (tertimbang)
Kelompok Diagnostik Prevalen 2024 (tertimbang) Prevalensi /100k JKN
SMI – Skizofrenia/Psikotik (F20–29) 679,492 244.5
Ansietas/Stres (F40–48) 362,285 130.4
Perkembangan/Anak (F70–98) 299,145 107.7
Mood/Depresi (F30,F32–39) 122,360 44.0
Organik/Demensia (F00–09) 87,797 31.6
Perilaku/Kepribadian (F50–69) 55,757 20.1
SMI – Bipolar (F31) 36,981 13.3
SUD – Gangguan Zat (F10–19) 9,351 3.4
Lainnya 189 0.1
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | per 100.000 peserta JKN 2024 (≈277,9 juta)
Key takeaway epidemiologi: Pada 2024 (tahun terandal), prevalensi gangguan jiwa terlayani 595 per 100.000 peserta JKN (≈0,5%) dengan kumulatif 2,644,341 pasien teridentifikasi. Insidensi-terlayani stabil ~20–26/100k pada 2016–2021 — ini sinyal yang paling interpretable; lonjakan 2022–2024 sebagian besar artefak akrual sampel (lihat peringatan), bukan kenaikan insidensi sejati. Semua angka tetap jauh di bawah prevalensi komunitas (treatment gap, Layer 0).

2.4 Validasi tren — epidemiologi sejati atau artefak sampel?

Uji kohort stabil

Untuk memisahkan kenaikan riil dari artefak akrual, kami batasi ke kohort stabil = pasien yang terobservasi sejak awal (kontak pertama ≤2016) dan masih aktif akhir periode (≥2023). Bila tren kohort tetap ini datar sementara keseluruhan meledak, kenaikan keseluruhan didominasi perluasan/akrual sampel, bukan epidemiologi.

ov <- A$prev_year_total |> dplyr::transmute(yr, N=wt_pts, seri="Seluruh kohort (terpengaruh akrual)")
st <- A$stable_prev |> dplyr::filter(yr<=2023) |> dplyr::transmute(yr, N=as.numeric(wt_pts),
        seri="Kohort stabil (observasi 2016–2023)")
cmp <- dplyr::bind_rows(ov, st)
ggplot(cmp, aes(yr, N, color=seri)) + geom_line(linewidth=1.1) + geom_point(size=2) +
  scale_color_manual(values=c("Seluruh kohort (terpengaruh akrual)"=AMBER,
                              "Kohort stabil (observasi 2016–2023)"=NAVY), name=NULL) +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()), limits=c(0,NA), expand=expansion(mult=c(0,.12))) +
  guides(color=guide_legend(nrow=2)) +
  labs(title="Validasi Tren: Seluruh Kohort vs Kohort Stabil · Unit: pasien unik/tahun",
       subtitle=sprintf("Kohort stabil (n=%s pasien, observasi 2016–2023) relatif datar → lonjakan keseluruhan didominasi akrual/perluasan sampel, bukan kenaikan epidemiologis.", fmt(A$stable_n)),
       x=NULL, y="Pasien terlayani/tahun (tertimbang)", caption=CAP) + th()

Validasi: Prevalensi kohort stabil hampir datar (~90–110rb/tahun, 2016–2023) sementara kohort keseluruhan naik berlipat — bukti kuat bahwa tren pertumbuhan sebagian besar artefak konstruksi sampel (perluasan frame, left-truncation), bukan kenaikan beban epidemiologis sejati. Gunakan level cross-sectional 2024 untuk perbandingan, bukan kemiringan tren.

2.5 Tren prevalensi terlayani per tahun

pyt <- A$prev_year_total
p1 <- ggplot(pyt, aes(yr, wt_pts)) +
  geom_area(fill=BLUE, alpha=.18) + geom_line(color=NAVY, linewidth=1.1) +
  geom_point(color=NAVY, size=2) +
  geom_text(aes(label=label_number(scale_cut=cut_short_scale())(wt_pts)),
            vjust=-0.9, size=2.8, color=NAVY, fontface="bold") +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()),
                             limits=c(0,NA), expand=expansion(mult=c(0,.12))) +
  labs(title="Pasien Gangguan Jiwa Terlayani JKN per Tahun (tertimbang) · Unit: pasien unik/tahun",
       subtitle="Pasien unik dengan ≥1 klaim F-code per tahun (FKTP+FKRTL), proyeksi nasional",
       x=NULL, y="Pasien (tertimbang)", caption=CAP) + th()

pyg <- A$prev_year |> filter(!is.na(grp))
p2 <- ggplot(pyg, aes(yr, wt_pts, color=grp)) +
  geom_line(linewidth=.9) + geom_point(size=1.3) +
  scale_color_manual(values=GRP_COLS, name=NULL) +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale())) +
  guides(color=guide_legend(nrow=3)) +
  labs(title="Tren menurut Kelompok Diagnostik", subtitle="Pasien tertimbang per tahun", x=NULL, y=NULL) + th(10)
p1 / p2 + patchwork::plot_layout(heights=c(1,1.1))

ptab <- A$prev_year_total |>
  mutate(YoY=round((wt_pts-lag(wt_pts))/lag(wt_pts)*100,1),
         YoY=ifelse(is.na(YoY),"—",paste0(ifelse(YoY>0,"+",""),YoY,"%")))
gt::gt(ptab) |>
  gt::cols_label(yr="Tahun",raw_pts="Pasien (sampel)",wt_pts="Pasien (tertimbang)",YoY="YoY") |>
  gt::tab_header(title=gt::md("**Tabel 1.1 — Prevalensi Terlayani per Tahun** · _Unit: Pasien unik (tertimbang)_")) |>
  gt::fmt_number(columns=c(raw_pts,wt_pts),decimals=0,use_seps=TRUE) |>
  gt::data_color(columns=wt_pts,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 1.1 — Prevalensi Terlayani per Tahun · Unit: Pasien unik (tertimbang)
Tahun Pasien (sampel) Pasien (tertimbang) YoY
2015 4,090 82,736
2016 5,289 107,345 +29.7%
2017 6,793 139,061 +29.5%
2018 8,463 173,114 +24.5%
2019 10,326 211,997 +22.5%
2020 11,884 243,519 +14.9%
2021 14,890 302,343 +24.2%
2022 22,031 444,318 +47%
2023 54,820 1,032,023 +132.3%
2024 72,266 1,653,357 +60.2%
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
write.csv(ptab, file.path(OUT_DIR,"T1_1_prevalensi_tahun.csv"), row.names=FALSE)

2.6 Insidensi — kontak F-code pertama per tahun

inc <- A$incidence
ggplot(inc, aes(yr, wt_new)) +
  geom_col(fill=TEAL, width=.7) +
  geom_text(aes(label=label_number(scale_cut=cut_short_scale())(wt_new)),vjust=-0.5,size=2.8,color=NAVY,fontface="bold") +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()),expand=expansion(mult=c(0,.12))) +
  labs(title="Kasus Baru Teridentifikasi (Kontak F-code Pertama) per Tahun — tertimbang · Unit: pasien unik (baru)",
       subtitle="2015 dikecualikan. ⚠ Lonjakan 2023–2024 didominasi akrual/perluasan sampel (bukan insidensi sejati) — lihat peringatan di atas.",
       x=NULL, y="Kasus baru teridentifikasi (tertimbang)", caption=CAP) + th()

2.7 Karakteristik demografi

Profil demografi lengkap (jenis kelamin, usia, segmentasi/membership, kelas rawat, pulau, kelompok diagnostik) — dibandingkan Overall vs Membership vs FKTP vs FKRTL — ada di Tabel 1 (Karakteristik Sampel) di Fondasi. Di sini struktur usia–jenis kelamin divisualkan sebagai piramida.

2.8 Distribusi geografis (provinsi tempat tinggal)

isl <- A$geo_island |> filter(island!="Tidak diketahui") |> mutate(island=fct_reorder(island,wt_pts))
ggplot(isl, aes(wt_pts, island)) + geom_col(fill=NAVY,width=.7) +
  geom_text(aes(label=paste0(fmt(wt_pts)," (",pct,"%)")),hjust=-0.05,size=3,color=NAVY,fontface="bold") +
  scale_x_continuous(labels=label_number(scale_cut=cut_short_scale()),expand=expansion(mult=c(0,.2))) +
  labs(title="Sebaran Pasien Gangguan Jiwa Terlayani menurut Pulau · Unit: pasien unik",
       subtitle="Pasien tertimbang berdasarkan provinsi tempat tinggal (PSTV09)", x="Pasien (tertimbang)", y=NULL, caption=CAP) + th()

gtop <- A$geo_prov |> filter(prov_name!="Tidak diketahui") |> head(12) |>
  mutate(Rank=row_number()) |> select(Rank,prov_name,island,wt_pts,pct)
gt::gt(gtop) |>
  gt::cols_label(prov_name="Provinsi",island="Pulau",wt_pts="Pasien (tertimbang)",pct="%") |>
  gt::tab_header(title=gt::md("**Tabel 1.3 — 12 Provinsi dengan Beban Terlayani Tertinggi** · _Unit: Pasien unik (tertimbang)_")) |>
  gt::fmt_number(columns=wt_pts,decimals=0,use_seps=TRUE) |>
  gt::data_color(columns=wt_pts,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_style(style=list(gt::cell_fill(color="#fef3c7"),gt::cell_text(weight="bold")),
    locations=gt::cells_body(rows=Rank<=3)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 1.3 — 12 Provinsi dengan Beban Terlayani Tertinggi · Unit: Pasien unik (tertimbang)
Rank Provinsi Pulau Pasien (tertimbang) %
1 Jawa Barat Jawa 445,128 16.8
2 Jawa Tengah Jawa 422,784 16.0
3 Jawa Timur Jawa 348,581 13.2
4 DKI Jakarta Jawa 219,123 8.3
5 Sulawesi Selatan Sulawesi 104,358 3.9
6 Banten Jawa 99,356 3.8
7 Sumatera Utara Sumatera 92,728 3.5
8 Sumatera Barat Sumatera 83,736 3.2
9 DI Yogyakarta Jawa 77,560 2.9
10 Aceh Sumatera 67,593 2.6
11 Sumatera Selatan Sumatera 61,894 2.3
12 Bali Bali-Nusra 60,197 2.3
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)

2.9 Struktur usia & jenis kelamin

ageband <- pt |> dplyr::filter(!is.na(age), sex %in% c(1,2)) |>
  dplyr::mutate(band=cut(age,c(-Inf,9,19,29,39,49,59,69,Inf),
    labels=c("<10","10–19","20–29","30–39","40–49","50–59","60–69","70+"))) |>
  dplyr::count(band, sex_lab, wt=w, name="N") |>
  dplyr::mutate(N2=ifelse(sex_lab=="Laki-laki", -N, N))
ggplot(ageband, aes(N2, band, fill=sex_lab)) + geom_col(width=.82) +
  scale_x_continuous(labels=function(x) label_number(scale_cut=cut_short_scale())(abs(x))) +
  scale_fill_manual(values=c("Laki-laki"=BLUE,"Perempuan"=RED), name=NULL) +
  labs(title="Piramida Usia–Jenis Kelamin Pasien Gangguan Jiwa JKN · Unit: pasien unik",
       subtitle="Pasien tertimbang; usia saat kontak F-code pertama (♂ kiri, ♀ kanan)",
       x="Pasien (tertimbang)", y="Kelompok usia", caption=CAP) + th()

2.10 20 Kabupaten/Kota dengan beban terlayani tertinggi

KLU <- "/home/arcinstitute/.claude/skills/indonesia-district-map/kabkota_lookup.csv"
if(file.exists(KLU)){
  klu <- read.csv(KLU)
  kab <- A$district_prev |> dplyr::left_join(klu, by=c("kab"="gis_code_24")) |>
    dplyr::filter(!is.na(kabkota)) |> head(20) |>
    dplyr::mutate(Rank=dplyr::row_number()) |> dplyr::select(Rank,kabkota,province,wt_pts,raw_pts)
  write.csv(kab, file.path(OUT_DIR,"T1_4_kabupaten_top20.csv"), row.names=FALSE)
  gt::gt(kab) |>
    gt::cols_label(kabkota="Kabupaten/Kota",province="Provinsi",wt_pts="Pasien (tertimbang)",raw_pts="Pasien (sampel)") |>
    gt::tab_header(title=gt::md("**Tabel 1.4 — 20 Kabupaten/Kota dengan Beban Terlayani Tertinggi** · _Unit: Pasien unik (tertimbang)_"),
      subtitle=gt::md("_Berdasarkan kabupaten/kota tempat tinggal (PSTV10)_")) |>
    gt::fmt_number(columns=c(wt_pts,raw_pts),decimals=0,use_seps=TRUE) |>
    gt::data_color(columns=wt_pts,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
    gt::tab_style(style=list(gt::cell_fill(color="#fef3c7"),gt::cell_text(weight="bold")),
      locations=gt::cells_body(rows=Rank<=5)) |>
    gt::tab_source_note(gt::md(paste(CAP,"| Choropleth kabupaten interaktif = langkah lanjut (skill indonesia-district-map)"))) |> gfmt()
}
Tabel 1.4 — 20 Kabupaten/Kota dengan Beban Terlayani Tertinggi · Unit: Pasien unik (tertimbang)
Berdasarkan kabupaten/kota tempat tinggal (PSTV10)
Rank Kabupaten/Kota Provinsi Pasien (tertimbang) Pasien (sampel)
1 Kota Jakarta Utara DKI Jakarta 70,470 2,406
2 Kota Surabaya Jawa Timur 50,376 1,603
3 Kota Jakarta Selatan DKI Jakarta 48,515 1,572
4 Kab. Bogor Jawa Barat 48,420 1,425
5 Kota Bandung Jawa Barat 42,883 1,289
6 Kota Jakarta Pusat DKI Jakarta 42,558 1,429
7 Kota Bekasi Jawa Barat 36,115 1,070
8 Kota Semarang Jawa Tengah 34,636 1,051
9 Kota Jakarta Timur DKI Jakarta 32,600 1,085
10 Kab. Bandung Jawa Barat 31,459 904
11 Kota Depok Jawa Barat 27,437 818
12 Kab. Bekasi Jawa Barat 27,433 780
13 Kota Tangerang Banten 26,986 1,196
14 Kab. Sleman Daerah Istimewa Yogyakarta 26,258 1,262
15 Kab. Banyumas Jawa Tengah 25,253 754
16 Kota Makassar Sulawesi Selatan 25,065 1,083
17 Kab. Tangerang Banten 24,918 990
18 Kota Binjai Sumatera Utara 24,866 1,151
19 Kab. Cirebon Jawa Barat 24,759 704
20 Kota Jakarta Barat DKI Jakarta 24,592 798
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | Choropleth kabupaten interaktif = langkah lanjut (skill indonesia-district-map)
Key takeaway P1: Beban terlayani naik tajam, terkonsentrasi di Jawa. Profil didominasi skizofrenia (kronik, kontak berulang) di samping mood/ansietas. Kenaikan kasus baru kemungkinan besar mencerminkan perbaikan deteksi & ekspansi cakupan JKN, bukan semata insidensi. Catatan baca: Maluku-Papua tampak kecil saat tertimbang (1%) karena di-oversample berat (bobot ~2 vs Jawa ~31) — sampel mentahnya justru besar (~8.800 pasien); jangan dibaca sebagai beban rendah/data minim.

3 Pilar B — FKTP (Layanan Primer)

② Pilar B · Layanan Primer (FKTP/Kapitasi) · Diagnosis · Cakupan
Pertanyaan: Apa yang dilayani di tingkat primer dan seberapa besar peran FKTP sebagai pintu masuk keswa. Figur pertama = gambaran lintas-tingkat (FKTP vs FKRTL) sebagai jembatan.
uy <- A$util_year |> mutate(level=factor(level,levels=c("FKTP (Primer)","FKRTL Rawat Jalan","FKRTL Rawat Inap")))
ggplot(uy, aes(yr, wt_visits, fill=level)) +
  geom_area(alpha=.9, color="white", linewidth=.2) +
  scale_fill_manual(values=LVL_COLS, name=NULL) +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()),expand=expansion(mult=c(0,.05))) +
  labs(title="Volume Kunjungan Gangguan Jiwa per Tingkat Layanan (tertimbang) · Unit: kunjungan",
       subtitle="FKTP (primer/kapitasi) vs FKRTL rawat jalan vs rawat inap — klaim F-code per tahun",
       x=NULL, y="Kunjungan (tertimbang)", caption=CAP) + th()

3.1 Diagnosis yang dilayani di FKTP & cakupan layanan primer

fd <- A$fktp_dx |> filter(!is.na(grp)) |> mutate(grp=fct_reorder(as.character(grp),wt))
ggplot(fd, aes(wt, grp, fill=grp)) + geom_col(width=.72) +
  geom_text(aes(label=label_number(scale_cut=cut_short_scale())(wt)),hjust=-0.05,size=3,color=NAVY,fontface="bold") +
  scale_fill_manual(values=GRP_COLS, guide="none") +
  scale_x_continuous(labels=label_number(scale_cut=cut_short_scale()),expand=expansion(mult=c(0,.16))) +
  labs(title="Diagnosis Jiwa yang Dilayani di FKTP (Primer) · Unit: kunjungan",
       subtitle="Kunjungan F-code FKTP tertimbang menurut kelompok diagnostik",
       x="Kunjungan FKTP (tertimbang)", y=NULL, caption=CAP) + th()

cv <- A$coverage |> filter(grpc!="Lainnya")
gt::gt(cv) |> gt::cols_label(grpc="Pola pemakaian layanan",wt="Pasien (tertimbang)",raw="Pasien (sampel)",pct="%") |>
  gt::tab_header(title=gt::md("**Tabel B.1 — Cakupan: FKTP saja vs FKRTL saja vs Keduanya** · _Unit: Pasien unik (tertimbang)_")) |>
  gt::fmt_number(columns=c(wt,raw),decimals=0,use_seps=TRUE) |>
  gt::data_color(columns=wt,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel B.1 — Cakupan: FKTP saja vs FKRTL saja vs Keduanya · Unit: Pasien unik (tertimbang)
Pola pemakaian layanan Pasien (tertimbang) Pasien (sampel) %
FKTP + FKRTL 1,613,814 73,083 61.0
FKRTL saja 587,409 29,729 22.2
FKTP saja 443,118 19,560 16.8
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
Key takeaway FKTP: Diagnosis FKTP didominasi skizofrenia & ansietas. Namun 22.2% pasien jiwa tak pernah kontak FKTP (langsung ke RS), dan hanya 16.8% tertangani cukup di FKTP saja — menegaskan peran layanan primer keswa masih terbatas.

4 Pilar C — FKRTL (Rujukan / Rumah Sakit)

③ Pilar C · RJTL vs RITL · RSJ vs RSU · LOS · Krisis (IGD)
Pertanyaan: Karakter layanan rujukan/RS — tingkat layanan, jenis fasilitas (RSJ vs RSU), lama rawat, intensitas per pasien, dan kunjungan krisis.
vr <- A$visit_rate |> mutate(grp=as.character(grp))
gt::gt(vr) |>
  gt::cols_label(grp="Kelompok Diagnostik",n_pts="Pasien (sampel)",mean_fktp="Rata2 kunjungan FKTP",
    mean_rjtl="Rata2 FKRTL R.Jalan",mean_ritl="Rata2 FKRTL R.Inap",mean_total="Rata2 total",
    pct_ever_inp="% pernah dirawat inap") |>
  gt::tab_header(title=gt::md("**Tabel 2.1 — Intensitas Utilisasi per Pasien menurut Kelompok** · _Unit: Rata-rata per pasien_")) |>
  gt::data_color(columns=mean_total,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::data_color(columns=pct_ever_inp,colors=scales::col_numeric(c("#fee2e2","#dc2626"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 2.1 — Intensitas Utilisasi per Pasien menurut Kelompok · Unit: Rata-rata per pasien
Kelompok Diagnostik Pasien (sampel) Rata2 kunjungan FKTP Rata2 FKRTL R.Jalan Rata2 FKRTL R.Inap Rata2 total % pernah dirawat inap
SMI – Skizofrenia/Psikotik (F20–29) 45211 9 18 0 28 27.6
Ansietas/Stres (F40–48) 29087 1 5 0 6 7.6
Perkembangan/Anak (F70–98) 22279 1 16 0 18 3.7
Mood/Depresi (F30,F32–39) 13591 2 7 0 10 13.0
Organik/Demensia (F00–09) 5915 0 5 0 6 24.4
Perilaku/Kepribadian (F50–69) 3516 1 3 0 4 4.8
SMI – Bipolar (F31) 2050 3 12 0 15 10.5
SUD – Gangguan Zat (F10–19) 713 4 9 0 13 6.6
Lainnya 10 0 2 0 2 0.0
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
los <- A$los |> filter(!is.na(grp)) |> mutate(grp=as.character(grp),
  IQR=paste0(median_los," (",q1,"–",q3,")")) |> select(grp,n_inp,mean_los,IQR)
gt::gt(los) |>
  gt::cols_label(grp="Kelompok Diagnostik",n_inp="Episode rawat inap (sampel)",
    mean_los="Rata2 LOS (hari)",IQR="Median LOS (IQR)") |>
  gt::tab_header(title=gt::md("**Tabel 2.2 — Lama Rawat Inap Psikiatri (LOS)** · _Unit: Episode rawat inap_")) |>
  gt::data_color(columns=mean_los,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(paste(CAP,"| LOS = FKL04−FKL03, dibatasi 0–365 hari"))) |> gfmt()
Tabel 2.2 — Lama Rawat Inap Psikiatri (LOS) · Unit: Episode rawat inap
Kelompok Diagnostik Episode rawat inap (sampel) Rata2 LOS (hari) Median LOS (IQR)
SMI – Skizofrenia/Psikotik (F20–29) 23258 22.6 15 (9–24)
SMI – Bipolar (F31) 631 11.4 9 (5–15)
SUD – Gangguan Zat (F10–19) 48 9.6 6 (2.75–13)
Mood/Depresi (F30,F32–39) 1206 7.1 4 (3–9)
Ansietas/Stres (F40–48) 796 3.7 3 (2–4)
Organik/Demensia (F00–09) 1017 11.2 7 (3–14)
Perilaku/Kepribadian (F50–69) 112 6.5 4.5 (2–8)
Perkembangan/Anak (F70–98) 483 8.0 5 (2–11)
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | LOS = FKL04−FKL03, dibatasi 0–365 hari

4.1 Tempat layanan: RS Jiwa (RSJ) vs RS Umum

cs <- A$care_setting_year |> dplyr::mutate(setting=factor(setting,
  levels=c("RS Umum","RS Khusus Jiwa (RSJ)","RS Khusus Lain","Klinik","Lainnya")))
ggplot(cs, aes(yr, wt, fill=setting)) + geom_area(alpha=.9,color="white",linewidth=.2) +
  scale_fill_manual(values=c("RS Umum"=BLUE,"RS Khusus Jiwa (RSJ)"=NAVY,"RS Khusus Lain"=TEAL,
    "Klinik"=AMBER,"Lainnya"=GREY), name=NULL) +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()),expand=expansion(mult=c(0,.05))) +
  labs(title="Tempat Layanan FKRTL Gangguan Jiwa per Tahun (tertimbang) · Unit: kunjungan",
       subtitle=sprintf("RS Khusus Jiwa (RSJ) = %.1f%% total kunjungan FKRTL; RS Umum = %.1f%%",
         A$care_setting_total$pct[A$care_setting_total$setting=="RS Khusus Jiwa (RSJ)"],
         A$care_setting_total$pct[A$care_setting_total$setting=="RS Umum"]),
       x=NULL, y="Kunjungan FKRTL (tertimbang)", caption=CAP) + th()

gt::gt(A$los_class |> dplyr::mutate(IQR=paste0(median_los," (",q1,"–",q3,")")) |>
       dplyr::select(kelas_rs,n_inp,mean_los,IQR)) |>
  gt::cols_label(kelas_rs="Kelas/Tipe RS",n_inp="Episode rawat inap (sampel)",mean_los="Rata2 LOS (hari)",IQR="Median LOS (IQR)") |>
  gt::tab_header(title=gt::md("**Tabel 2.3 — Lama Rawat Inap menurut Kelas/Tipe Rumah Sakit** · _Unit: Episode rawat inap_")) |>
  gt::data_color(columns=mean_los,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(paste(CAP,"| RSJ = RS Khusus Jiwa"))) |> gfmt()
Tabel 2.3 — Lama Rawat Inap menurut Kelas/Tipe Rumah Sakit · Unit: Episode rawat inap
Kelas/Tipe RS Episode rawat inap (sampel) Rata2 LOS (hari) Median LOS (IQR)
RS Khusus Jiwa (RSJ) 18033 25.9 18 (11–28)
RS Kelas B 3934 11.3 9 (5–14)
RS Kelas C 3779 7.9 6 (3–11)
RS Kelas D 850 13.0 4 (4–7.75)
RS Kelas A 824 9.3 8 (4–13)
RS Khusus Lain 83 3.3 2 (2–4)
Lainnya/Missing 48 4.3 4 (2–6)
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | RSJ = RS Khusus Jiwa
em <- A$emergency_year |> dplyr::select(Tahun=yr, `Kunjungan IGD/UGD (sampel)`=raw_igd, `% dari FKRTL`=pct_igd)
psy <- A$psych_poli
gt::gt(em) |>
  gt::tab_header(title=gt::md("**Tabel 2.4 — Kunjungan Gawat Darurat (IGD/UGD) Psikiatri per Tahun** · _Unit: Kunjungan (tertimbang)_"),
    subtitle=gt::md(sprintf("_Poli jiwa spesifik (JIW/JWA/PSK) = %.1f%% kunjungan FKRTL ber-poli; kepemilikan: %s_",
      100*psy$psy/psy$tot,
      paste(sprintf("%s %.0f%%",A$ownership$owner,100*A$ownership$wt/sum(A$ownership$wt)),collapse=", ")))) |>
  gt::fmt_number(columns=2,decimals=0,use_seps=TRUE) |>
  gt::tab_source_note(gt::md(paste(CAP,"| event akut = proxy kegagalan layanan rawat jalan"))) |> gfmt()
Tabel 2.4 — Kunjungan Gawat Darurat (IGD/UGD) Psikiatri per Tahun · Unit: Kunjungan (tertimbang)
Poli jiwa spesifik (JIW/JWA/PSK) = 67.8% kunjungan FKRTL ber-poli; kepemilikan: Publik 62%, Swasta 38%
Tahun Kunjungan IGD/UGD (sampel) % dari FKRTL
2015 138 0.4
2016 208 0.5
2017 333 0.6
2018 914 1.2
2019 1,102 1.1
2020 589 0.6
2021 751 0.6
2022 1,134 0.6
2023 1,962 0.6
2024 2,297 0.4
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | event akut = proxy kegagalan layanan rawat jalan
Key takeaway FKRTL: Layanan gangguan jiwa terkonsentrasi di FKRTL rawat jalan (poli jiwa RS), bukan FKTP. Skizofrenia paling intensif (kontak berulang, LOS terpanjang di RSJ). RSJ menampung ~1/5 kunjungan FKRTL.

5 Pilar D — Inter: Rujukan & Konektivitas Antar-Faskes

④ Pilar D · Gate FKTP→FKRTL · Tipe Perujuk · Geografi Rujukan
Pertanyaan: Bagaimana pasien berpindah antar fasilitas — apakah lewat gate primer, siapa yang merujuk, dan apakah rujukan menyeberang kabupaten/provinsi.
rr <- A$referral_rate_year |> filter(yr>=2018, yr<=2023)   # FKP02 hanya tercatat 2018–2023
ggplot(rr, aes(yr, pct_via_fktp)) + geom_col(fill=TEAL,width=.6) +
  geom_text(aes(label=paste0(pct_via_fktp,"%")),vjust=-0.4,size=3,color=NAVY,fontface="bold") +
  scale_x_continuous(breaks=2018:2023,labels=function(x)paste0("'",substr(x,3,4))) +
  scale_y_continuous(limits=c(0,100),expand=expansion(mult=c(0,.1))) +
  labs(title="Gate FKTP→FKRTL: % Kunjungan FKRTL via Rujukan FKTP · Unit: kunjungan",
       subtitle="Hanya 2018–2023 (linkage FKP02 tercatat; 2015–16 & 2024 belum terisi → dikecualikan)",
       x=NULL, y="% FKRTL via rujukan FKTP", caption=CAP) + th()

rt <- A$referrer_type |> head(6) |> select(perujuk,raw,pct)
gt::gt(rt) |> gt::cols_label(perujuk="Tipe faskes perujuk (rawat inap)",raw="Episode (sampel)",pct="%") |>
  gt::tab_header(title=gt::md("**Tabel D.1 — Tipe Faskes Perujuk Rawat Inap Psikiatri** · _Unit: Episode discharge_")) |>
  gt::fmt_number(columns=raw,decimals=0,use_seps=TRUE) |>
  gt::data_color(columns=pct,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel D.1 — Tipe Faskes Perujuk Rawat Inap Psikiatri · Unit: Episode discharge
Tipe faskes perujuk (rawat inap) Episode (sampel) %
Rumah Sakit 118,915 91.1
Puskesmas 7,187 5.5
Klinik Pratama 2,033 1.6
Dokter Umum 1,289 1.0
Klinik Utama 1,158 0.9
Lainnya 7 0.0
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
rg <- A$referral_geo
rgd <- tibble::tibble(jenis=c("Dalam kabupaten sama","Lintas kabupaten (prov sama)","Lintas provinsi"),
  n=c(rg$same_kab,rg$cross_kab,rg$cross_prov)) |> mutate(pct=round(100*n/sum(n),1))
ggplot(rgd, aes(reorder(jenis,n), pct, fill=jenis)) + geom_col(width=.6) + coord_flip() +
  geom_text(aes(label=paste0(pct,"%")),hjust=-0.1,size=3.2,color=NAVY,fontface="bold") +
  scale_fill_manual(values=c("Dalam kabupaten sama"=NAVY,"Lintas kabupaten (prov sama)"=AMBER,"Lintas provinsi"=RED),guide="none") +
  scale_y_continuous(limits=c(0,110),expand=c(0,0)) +
  labs(title="Geografi Rujukan Rawat Inap Psikiatri · Unit: episode rujukan",
       subtitle="Lokasi faskes perujuk (FKL25/26) vs faskes pelayan (FKL05/06)", x=NULL, y="% rujukan", caption=CAP) + th()

Key takeaway Inter: Pada 2018–2023 (saat linkage tercatat), ~75–80% kunjungan FKRTL datang via rujukan FKTP — gate primer berfungsi untuk rawat jalan. Namun rawat inap psikiatri mayoritas dirujuk antar-RS (92%), hanya 5,5% dari Puskesmas (eskalasi hospital-internal). Rujukan sangat lokal: 96,7% dalam kabupaten sama, hanya 0,8% lintas provinsi. Rujuk-balik (FKRTL→FKTP) tidak terkode eksplisit → tidak dianalisis.

6 Pilar E — Geografi Member ↔︎ Faskes (Akses Spasial)

⑤ Pilar E · Tempat Tinggal vs Faskes Terdaftar · Luar-Kabupaten · Gurun RSJ
Pertanyaan: Apakah peserta terdaftar di faskes dalam kabupatennya sendiri, dan di wilayah mana akses memaksa keluar daerah. (Sebaran beban penyakit secara geografis ada di Pilar A.)
mf <- A$mf_geo
mfd <- tibble::tibble(Indikator=c("Faskes terdaftar dalam PROVINSI sama","Faskes terdaftar dalam KABUPATEN sama"),
  `%`=c(mf$same_prov,mf$same_kab))
gt::gt(mfd) |> gt::tab_header(title=gt::md("**Tabel E.1 — Kesesuaian Tempat Tinggal ↔ Faskes Terdaftar** · _Unit: Member_"),
  subtitle=gt::md("_PSTV09/10 (tempat tinggal) vs PSTV13/14 (faskes terdaftar)_")) |>
  gt::fmt_number(columns=2,decimals=1) |> gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel E.1 — Kesesuaian Tempat Tinggal ↔ Faskes Terdaftar · Unit: Member
PSTV09/10 (tempat tinggal) vs PSTV13/14 (faskes terdaftar)
Indikator %
Faskes terdaftar dalam PROVINSI sama 95.0
Faskes terdaftar dalam KABUPATEN sama 88.8
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
provref <- A$geo_prov |> dplyr::select(prov,prov_name,island) |> dplyr::distinct()
mfp <- A$mf_geo_prov |> left_join(provref, by="prov") |> filter(!is.na(prov_name)) |>
  arrange(pct_same_kab) |> head(12) |> mutate(prov_name=fct_reorder(prov_name,-pct_same_kab))
ggplot(mfp, aes(pct_same_kab, prov_name)) + geom_col(fill=TEAL,width=.7) +
  geom_text(aes(label=paste0(pct_same_kab,"%")),hjust=-0.1,size=2.8,color=NAVY,fontface="bold") +
  scale_x_continuous(limits=c(0,108),expand=c(0,0)) +
  labs(title="12 Provinsi dengan Faskes-Dalam-Kabupaten Terendah · Unit: % member",
       subtitle="Makin rendah = makin banyak peserta terdaftar di luar kabupaten tinggalnya (akses terbatas)",
       x="% terdaftar di faskes dalam kabupaten sama", y=NULL, caption=CAP) + th()

Key takeaway Geografi: 88,8% peserta jiwa terdaftar di faskes dalam kabupatennya; ~11% di luar kabupaten. Terendah di Papua/Papua Barat & DKI Jakarta (~79–84%) — Papua karena faskes jarang (gurun layanan), DKI karena mobilitas antar-kota. Sebaran beban penyakit lihat Pilar A; RSJ terkonsentrasi di Jawa.

7 Pilar F — Proses, Kontinuitas & Follow-up

③ Pilar 3 · Follow-up Pasca-Rawat 7/30 Hari (FUH) · Disengagement
Inti mutu keswa. Indikator follow-up pasca-rawat inap (FUH) — mirip HEDIS — mengukur apakah pasien mendapat kontak rawat jalan dalam 7/30 hari setelah pulang dari rawat inap psikiatri. Plus pola gap antar-kunjungan (disengagement).
fo <- A$fuh_overall
fuh <- A$fuh |> filter(!is.na(grp), n_disc>=30) |> mutate(grp=as.character(grp)) |>
  tidyr::pivot_longer(c(fuh7_pct,fuh30_pct),names_to="win",values_to="pct") |>
  mutate(win=recode(win,fuh7_pct="Dalam 7 hari",fuh30_pct="Dalam 30 hari"),grp=fct_reorder(grp,pct))
ggplot(fuh, aes(pct, grp, fill=win)) +
  geom_col(position="dodge", width=.7) +
  geom_text(aes(label=paste0(pct,"%")),position=position_dodge(width=.7),hjust=-0.1,size=2.7,color=NAVY) +
  scale_fill_manual(values=c("Dalam 7 hari"=AMBER,"Dalam 30 hari"=NAVY),name=NULL) +
  scale_x_continuous(limits=c(0,100),expand=expansion(mult=c(0,.1))) +
  labs(title="Follow-up Pasca Rawat Inap Psikiatri (FUH) menurut Kelompok · Unit: episode discharge",
       subtitle=sprintf("Keseluruhan: %.1f%% kontak rawat jalan dalam 7 hari, %.1f%% dalam 30 hari (n=%s discharge)",
                        fo$fuh7,fo$fuh30,fmt(fo$n_disc)),
       x="% discharge dengan follow-up rawat jalan", y=NULL, caption=CAP) + th()

Definisi FUH (STRICT psikiatri)

Indikator mutu (FUH, readmisi, LOS) memakai definisi strict: episode rawat inap yang memang untuk gangguan jiwa (diagnosis F di masuk atau primer) — bukan definisi luas yang ikut memasukkan admisi fisik dengan jiwa sekunder (yang akan mencemari indikator ±21%, n 27.581 vs 34.989). FUH = proporsi discharge dengan kontak rawat jalan psikiatri dalam 7 / 30 hari setelah pulang (FKL04). Disengagement = gap antar-kunjungan > 180 hari.

g <- A$gaps
gtab <- tibble::tibble(Indikator=c("Median gap antar-kunjungan rawat jalan (hari)","% interval kunjungan > 180 hari (disengagement)"),
  Nilai=c(paste0(g$median_gap," hari"), paste0(g$pct_gap_gt180,"%")))
gt::gt(gtab) |> gt::tab_header(title=gt::md("**Tabel 3.1 — Kontinuitas & Disengagement** · _Unit: Interval antar-kunjungan_")) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 3.1 — Kontinuitas & Disengagement · Unit: Interval antar-kunjungan
Indikator Nilai
Median gap antar-kunjungan rawat jalan (hari) 14 hari
% interval kunjungan > 180 hari (disengagement) 1.3%
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)

7.1 FUH menurut tahun & segmen kepesertaan

fy <- A$fuh_year |> dplyr::filter(n_disc>=20)
ggplot(fy, aes(yr, fuh30)) + geom_line(color=NAVY,linewidth=1.1) + geom_point(color=NAVY,size=2) +
  geom_text(aes(label=paste0(fuh30,"%")),vjust=-0.8,size=2.7,color=NAVY,fontface="bold") +
  yrx() + scale_y_continuous(limits=c(0,100),expand=expansion(mult=c(0,.1))) +
  labs(title="Tren Follow-up Pasca Rawat Inap (FUH 30 hari) per Tahun · Unit: episode discharge",
       subtitle="Patokan mutu internasional umumnya ≥60–70%",
       x=NULL, y="% discharge dengan follow-up 30 hari", caption=CAP) + th()

gt::gt(A$fuh_segment |> dplyr::filter(segmen!="Missing")) |>
  gt::cols_label(segmen="Segmen Kepesertaan",n_disc="Episode discharge (sampel)",fuh30="FUH 30 hari (%)") |>
  gt::tab_header(title=gt::md("**Tabel 3.2 — FUH 30 Hari menurut Segmen Kepesertaan** · _Unit: Episode discharge_")) |>
  gt::data_color(columns=fuh30,colors=scales::col_numeric(c("#fee2e2","#16a34a"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 3.2 — FUH 30 Hari menurut Segmen Kepesertaan · Unit: Episode discharge
Segmen Kepesertaan Episode discharge (sampel) FUH 30 hari (%)
PBI (Disubsidi) 16851 56.6
Non-PBI 10730 57.4
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
Key takeaway P3: FUH 30 hari keseluruhan 57% — patokan mutu internasional umumnya menargetkan ≥60–70% FUH 30 hari, sehingga ada ruang perbaikan transisi rawat inap→rawat jalan. Gap antar-kunjungan & disengagement menandakan tantangan retensi dalam perawatan.

7.2 Lintasan Klinis: Readmisi & Mortalitas

④ Pilar 4 · Readmisi · Komorbiditas Fisik · Mortalitas
Pertanyaan: Relaps/readmisi, beban komorbiditas fisik (jiwa↔︎fisik), dan kematian.
rd <- A$readmit
rtab <- tibble::tibble(Indikator=c("Readmisi psikiatri ≤30 hari","Readmisi psikiatri ≤90 hari"),
  `% dari discharge`=c(paste0(rd$readmit30_pct,"%"),paste0(rd$readmit90_pct,"%")))
gt::gt(rtab) |> gt::tab_header(title=gt::md("**Tabel 4.1 — Readmisi Rawat Inap Psikiatri** · _Unit: Episode discharge_"),
  subtitle=gt::md(sprintf("_Dari %s episode discharge rawat inap_",fmt(rd$n_disc)))) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 4.1 — Readmisi Rawat Inap Psikiatri · Unit: Episode discharge
Dari 27,581 episode discharge rawat inap
Indikator % dari discharge
Readmisi psikiatri ≤30 hari 16%
Readmisi psikiatri ≤90 hari 25.5%
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
co <- A$comorbid |> mutate(komorbid=fct_reorder(komorbid,pct))
ggplot(co, aes(pct, komorbid)) + geom_col(fill=RED, width=.68) +
  geom_text(aes(label=paste0(pct,"%")),hjust=-0.15,size=3,color=NAVY,fontface="bold") +
  scale_x_continuous(limits=c(0,max(co$pct)*1.18),expand=expansion(mult=c(0,.02))) +
  labs(title="Komorbiditas Fisik pada Pasien Gangguan Jiwa JKN · Unit: pasien unik",
       subtitle=sprintf("%% dari %s pasien jiwa (sampel) dengan klaim diagnosis fisik terkait", fmt(A$n_mental_pts)),
       x="% pasien jiwa dengan komorbid", y=NULL, caption=CAP) + th()

Mortalitas — interpretasi hati-hati. Angka ini = kematian 2 TAHUN (2023–2024 saja), BUKAN rate tahunan, dan sangat under-captured. Dua sumber: (1) PSTV18 (tahun meninggal sistem kepesertaan) hanya terisi 2023–2024 → 2,401 kematian sampel (1.96% kohort dalam 2 tahun); (2) FKL14=3 (meninggal in-hospital) per tahun. Banding antar-kelompok belum age-standardized — rate tinggi pada Organik/Demensia mencerminkan usia lansia, bukan keparahan gangguan organik per se (lihat median usia di tabel). Kematian di luar RS/komunitas tak tertangkap penuh. SMR (mortality gap) butuh life-table populasi umum — belum dihitung di edisi ini. Self-harm/percobaan bunuh diri via kode sebab-luar (X60–X84) hanya 95 baris → praktis tak tercatat di klaim; tidak dianalisis sebagai outcome.

mi <- A$mort_inhosp
ggplot(mi, aes(yr, wt_deaths)) + geom_col(fill=GREY,width=.7) +
  geom_text(aes(label=fmt(wt_deaths)),vjust=-0.5,size=2.6,color=NAVY) +
  ggplot2::scale_x_continuous(breaks=2015:2024,labels=function(x)paste0("'",substr(x,3,4))) +
  scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()),expand=expansion(mult=c(0,.12))) +
  labs(title="Kematian In-Hospital (FKL14=3) per Tahun — tertimbang · Unit: kematian (tertimbang)",
       subtitle="Hanya kematian saat rawat inap; under-capture besar untuk kematian komunitas",
       x=NULL,y="Kematian (tertimbang)",caption=CAP) + th()

7.3 Apakah follow-up menurunkan readmisi?

fr <- A$fuh_readmit
ggplot(fr, aes(reorder(grp,readmit90_pct), readmit90_pct, fill=grp)) +
  geom_col(width=.6) + coord_flip() +
  geom_text(aes(label=paste0(readmit90_pct,"%  (n=",scales::comma(n_disc),")")),hjust=-0.05,size=3.2,color=NAVY,fontface="bold") +
  scale_fill_manual(values=c("Ada follow-up 30 hari"=GREEN,"Tanpa follow-up"=RED),guide="none") +
  scale_y_continuous(limits=c(0,max(fr$readmit90_pct)*1.25),expand=expansion(mult=c(0,.02))) +
  labs(title="Readmisi 90 Hari menurut Status Follow-up Pasca-Rawat · Unit: episode discharge",
       subtitle="Pasien dengan follow-up rawat jalan dalam 30 hari memiliki readmisi jauh lebih rendah (asosiasi, bukan kausal)",
       x=NULL, y="Readmisi psikiatri ≤90 hari (%)", caption=CAP) + th()

Temuan kebijakan: Pasien dengan follow-up rawat jalan ≤30 hari pasca-pulang memiliki readmisi-90-hari 17.8% vs 35.8% tanpa follow-up — selisih besar yang menegaskan nilai transisi rawat-inap→rawat-jalan (catatan: asosiasi observasional, perlu adjustment confounder).

7.4 Beban komorbiditas (jumlah kategori per pasien) & mortalitas per kelompok

cc <- A$comorbid_count
ggplot(cc, aes(n_komorbid, pct, fill=n_komorbid)) + geom_col(width=.7) +
  geom_text(aes(label=paste0(pct,"%")),vjust=-0.4,size=3,color=NAVY,fontface="bold") +
  scale_fill_manual(values=c("0"=GREY,"1"=TEAL,"2"=AMBER,"3+"=RED),guide="none") +
  scale_y_continuous(expand=expansion(mult=c(0,.12))) +
  labs(title="Jumlah Kategori Komorbiditas Fisik per Pasien Gangguan Jiwa · Unit: pasien unik",
       subtitle=sprintf("%% dari %s pasien (diagnosis primer FKRTL; kemungkinan undercount)", fmt(A$n_mental_pts)),
       x="Jumlah kategori komorbid fisik", y="% pasien", caption=CAP) + th()

med_age <- pt |> filter(!is.na(age)) |> group_by(grp=as.character(grp)) |>
  summarise(median_usia=round(median(age)), .groups="drop")
mg <- A$mort_group |> left_join(med_age, by="grp")
gt::gt(mg) |>
  gt::cols_label(grp="Kelompok Diagnostik",wt_deaths="Kematian 2-th (tertimbang)",wt_total="Total (tertimbang)",
                 mort_per1k="Kematian/1.000 (2-th)",median_usia="Median usia") |>
  gt::tab_header(title=gt::md("**Tabel 4.2 — Mortalitas 2-Tahun (PSTV18, 2023–24) menurut Kelompok Diagnostik** · _Unit: Pasien — kematian (tertimbang)_"),
    subtitle=gt::md("_Kematian 2 tahun (bukan rate tahunan); under-capture besar; belum age-standardized — kolom median usia untuk konteks_")) |>
  gt::fmt_number(columns=c(wt_deaths,wt_total),decimals=0,use_seps=TRUE) |>
  gt::data_color(columns=mort_per1k,colors=scales::col_numeric(c("#fee2e2","#dc2626"),domain=NULL)) |>
  gt::data_color(columns=median_usia,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 4.2 — Mortalitas 2-Tahun (PSTV18, 2023–24) menurut Kelompok Diagnostik · Unit: Pasien — kematian (tertimbang)
Kematian 2 tahun (bukan rate tahunan); under-capture besar; belum age-standardized — kolom median usia untuk konteks
Kelompok Diagnostik Kematian 2-th (tertimbang) Total (tertimbang) Kematian/1.000 (2-th) Median usia
Organik/Demensia (F00–09) 16,302 146,973 110.9 63
Mood/Depresi (F30,F32–39) 4,105 195,198 21.0 38
Perilaku/Kepribadian (F50–69) 1,835 92,069 19.9 46
Ansietas/Stres (F40–48) 7,245 560,869 12.9 41
SMI – Skizofrenia/Psikotik (F20–29) 13,027 1,071,302 12.2 38
SUD – Gangguan Zat (F10–19) 199 17,614 11.3 37
Perkembangan/Anak (F70–98) 3,560 506,310 7.0 4
SMI – Bipolar (F31) 340 53,818 6.3 27
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)

8 Pilar G — Komorbiditas Jiwa–Fisik

Inti: Cohort ini memuat seluruh klaim pasien jiwa — termasuk kunjungan untuk penyakit fisik. Memisahkan kunjungan jiwa vs fisik mengungkap beban komorbiditas yang biasanya tak terlihat.
mvp <- A$mental_vs_physical_year |>
  tidyr::pivot_longer(c(wt_mental,wt_physical),names_to="jenis",values_to="wt") |>
  mutate(jenis=recode(jenis, wt_mental="Kunjungan jiwa", wt_physical="Kunjungan fisik (non-jiwa)"))
ggplot(mvp, aes(yr, wt, fill=jenis)) + geom_area(alpha=.9,color="white",linewidth=.2) +
  scale_fill_manual(values=c("Kunjungan jiwa"=NAVY,"Kunjungan fisik (non-jiwa)"=RED),name=NULL) +
  yrx() + scale_y_continuous(labels=label_number(scale_cut=cut_short_scale()),expand=expansion(mult=c(0,.05))) +
  labs(title="Kunjungan Jiwa vs Kunjungan Fisik pada Pasien Gangguan Jiwa (FKRTL, tertimbang) · Unit: kunjungan",
       subtitle=sprintf("%s dari %s pasien jiwa punya ≥1 kunjungan fisik; layanan fisik = beban komorbiditas besar",
         fmt(A$burden_patient$n_with_physical), fmt(A$burden_patient$n_mental_pts)),
       x=NULL, y="Kunjungan (tertimbang)", caption=CAP) + th()

pc <- A$phys_chapter |> filter(chap!="Lain") |> mutate(chap=fct_reorder(chap,wt))
ggplot(pc, aes(wt, chap, fill=chap)) + geom_col(width=.72) +
  geom_text(aes(label=paste0(pct,"%")),hjust=-0.1,size=3,color=NAVY,fontface="bold") +
  scale_fill_manual(values=colorRampPalette(c(NAVY,TEAL,AMBER))(nrow(pc)),guide="none") +
  scale_x_continuous(labels=label_number(scale_cut=cut_short_scale()),expand=expansion(mult=c(0,.12))) +
  labs(title="Jenis Penyakit Fisik pada Kunjungan Non-Jiwa Pasien Gangguan Jiwa · Unit: kunjungan",
       subtitle="Kelompok bab ICD-10 diagnosis primer kunjungan fisik (tertimbang)",
       x="Kunjungan (tertimbang)", y=NULL, caption=CAP) + th()

cs <- A$cost_split
csb <- tibble::tibble(Kategori=c("Layanan JIWA","Layanan FISIK (komorbiditas)"),
  `Biaya FKRTL (Miliar Rp, tertimbang)`=c(cs$mental_cost_bil,cs$physical_cost_bil),
  `Diagnosis fisik tersering (sampel)`=c("—","Lihat tabel diagnosis fisik"))
phys_top <- A$phys_dx_top |> head(8) |> mutate(label=stringr::str_to_title(label)) |> select(icd3,label,raw,wt)
gt::gt(csb) |>
  gt::tab_header(title=gt::md("**Tabel 4.3 — Belanja FKRTL: Layanan Jiwa vs Layanan Fisik** · _Unit: Biaya klaim (tertimbang)_"),
    subtitle=gt::md("_Pada pasien gangguan jiwa yang sama, 2015–2024 kumulatif_")) |>
  gt::fmt_number(columns=2,decimals=1) |>
  gt::data_color(columns=2,colors=scales::col_numeric(c("#fef3c7","#dc2626"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 4.3 — Belanja FKRTL: Layanan Jiwa vs Layanan Fisik · Unit: Biaya klaim (tertimbang)
Pada pasien gangguan jiwa yang sama, 2015–2024 kumulatif
Kategori Biaya FKRTL (Miliar Rp, tertimbang) Diagnosis fisik tersering (sampel)
Layanan JIWA 11,700.6
Layanan FISIK (komorbiditas) 16,911.0 Lihat tabel diagnosis fisik
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
gt::gt(phys_top) |>
  gt::cols_label(icd3="ICD-3",label="Diagnosis fisik (primer)",raw="Kunjungan (sampel)",wt="Tertimbang") |>
  gt::tab_header(title=gt::md("**Tabel 4.4 — Diagnosis Fisik Tersering (kunjungan non-jiwa)** · _Unit: Kunjungan non-jiwa (tertimbang)_")) |>
  gt::fmt_number(columns=c(raw,wt),decimals=0,use_seps=TRUE) |>
  gt::data_color(columns=wt,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(paste(CAP,"| kode Z dikecualikan"))) |> gfmt()
Tabel 4.4 — Diagnosis Fisik Tersering (kunjungan non-jiwa) · Unit: Kunjungan non-jiwa (tertimbang)
ICD-3 Diagnosis fisik (primer) Kunjungan (sampel) Tertimbang
M54 Sciatica, Thoracolumbar Region 50,370 922,383
G40 Special Epileptic Syndromes 47,706 1,031,331
E11 Noninsulindependent Diabetes Mellitus 43,499 820,382
N18 Other Chronic Renal Failure 33,848 666,612
I11 Hypertensive Heart Disease Without Con 32,405 560,104
I25 Silent Myocardial Ischaemia 27,160 482,251
I64 Stroke, Not Specified As Haemorrhage O 26,762 581,413
I50 Left Ventricular Failure 25,980 459,904
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | kode Z dikecualikan
Key takeaway komorbiditas: Belanja layanan FISIK pasien jiwa (Rp16,911 Miliar) melampaui belanja layanan jiwanya (Rp11,700.6 Miliar). Penyakit kardiovaskular, saraf, dan muskuloskeletal dominan. Komorbiditas jiwa-fisik adalah pusat beban biaya — menegaskan kebutuhan perawatan terintegrasi, bukan layanan jiwa terisolasi. Catatan: ~18% kunjungan “fisik” berkode Z (follow-up administratif) — sebagian mungkin kontrol yang ter-miskoding; baris diagnosis kosong difilter.
Key takeaway P4: Readmisi 30/90 hari menandakan beban relaps. Komorbiditas fisik (hipertensi, diabetes, jantung) lazim pada pasien jiwa — menegaskan kebutuhan perawatan terintegrasi jiwa-fisik. Mortalitas tak bisa dinilai penuh dari klaim (butuh integrasi data kematian).

9 Pilar H — Ekonomi Kesehatan Jiwa

⑤ Pilar 5 · Biaya Klaim FKRTL · Pendorong Biaya · Konsentrasi (Pareto)
Pertanyaan: Berapa belanja JKN untuk gangguan jiwa, apa pendorongnya, dan seberapa terkonsentrasi. (FKTP kapitasi dikecualikan karena bukan fee-for-service.)
cy <- A$cost_year
ggplot(cy, aes(yr, total_bil_idr)) +
  geom_col(fill=NAVY,width=.7) +
  geom_text(aes(label=paste0("Rp",total_bil_idr,"M")),vjust=-0.5,size=2.7,color=NAVY,fontface="bold") +
  ggplot2::scale_x_continuous(breaks=2015:2024,labels=function(x)paste0("'",substr(x,3,4))) +
  scale_y_continuous(expand=expansion(mult=c(0,.12))) +
  labs(title="Total Belanja Klaim FKRTL Gangguan Jiwa per Tahun · Unit: biaya/klaim",
       subtitle="Miliar Rupiah (FKL47), klaim F-code rawat jalan + rawat inap",
       x=NULL,y="Total biaya (Miliar Rp)",caption=CAP) + th()

cg <- A$cost_group |> filter(!is.na(grp)) |> mutate(grp=as.character(grp))
gt::gt(cg |> select(grp,setting,n_claims,total_bil_idr,mean_cost,median_cost)) |>
  gt::cols_label(grp="Kelompok",setting="Setting",n_claims="Klaim (sampel)",
    total_bil_idr="Total (Miliar Rp)",mean_cost="Rata2/klaim (Rp)",median_cost="Median/klaim (Rp)") |>
  gt::tab_header(title=gt::md("**Tabel 5.1 — Biaya menurut Kelompok Diagnostik & Setting** · _Unit: Klaim (tertimbang)_")) |>
  gt::fmt_number(columns=c(n_claims,mean_cost,median_cost),decimals=0,use_seps=TRUE) |>
  gt::data_color(columns=total_bil_idr,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 5.1 — Biaya menurut Kelompok Diagnostik & Setting · Unit: Klaim (tertimbang)
Kelompok Setting Klaim (sampel) Total (Miliar Rp) Rata2/klaim (Rp) Median/klaim (Rp)
SMI – Skizofrenia/Psikotik (F20–29) Rawat Inap 24,146 3187.23 5,748,499 5,381,800
SMI – Skizofrenia/Psikotik (F20–29) Rawat Jalan 613,718 3163.11 225,043 192,100
SMI – Bipolar (F31) Rawat Inap 710 84.51 4,845,069 4,478,200
SMI – Bipolar (F31) Rawat Jalan 34,979 209.61 231,132 195,600
SUD – Gangguan Zat (F10–19) Rawat Inap 65 8.45 4,862,638 4,077,800
SUD – Gangguan Zat (F10–19) Rawat Jalan 4,012 20.65 220,435 191,900
Mood/Depresi (F30,F32–39) Rawat Inap 2,438 205.30 5,927,858 4,242,400
Mood/Depresi (F30,F32–39) Rawat Jalan 121,205 423.02 216,758 194,300
Ansietas/Stres (F40–48) Rawat Inap 3,461 259.30 4,564,142 3,070,500
Ansietas/Stres (F40–48) Rawat Jalan 260,226 973.81 211,502 194,400
Organik/Demensia (F00–09) Rawat Inap 2,580 609.04 9,764,588 6,642,600
Organik/Demensia (F00–09) Rawat Jalan 51,790 290.67 237,038 196,100
Perilaku/Kepribadian (F50–69) Rawat Inap 291 30.56 5,244,452 3,757,100
Perilaku/Kepribadian (F50–69) Rawat Jalan 16,751 81.42 218,882 192,400
Perkembangan/Anak (F70–98) Rawat Inap 1,298 174.10 7,181,666 4,447,950
Perkembangan/Anak (F70–98) Rawat Jalan 433,697 1949.24 198,063 172,600
Lainnya Rawat Jalan 9,103 30.59 203,024 185,500
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
pa <- A$pareto
gt::gt(pa) |> gt::cols_label(top_pct="Top % pasien (biaya tertinggi)",spend_share="% total belanja FKRTL") |>
  gt::tab_header(title=gt::md("**Tabel 5.2 — Konsentrasi Biaya (Pareto)** · _Unit: Pasien — konsentrasi biaya_"),
    subtitle=gt::md(sprintf("_Total belanja FKRTL gangguan jiwa ≈ Rp%s Miliar (kumulatif)_",A$cost_total_bil))) |>
  gt::fmt_number(columns=spend_share,decimals=1) |>
  gt::data_color(columns=spend_share,colors=scales::col_numeric(c("#fef3c7","#d97706"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 5.2 — Konsentrasi Biaya (Pareto) · Unit: Pasien — konsentrasi biaya
Total belanja FKRTL gangguan jiwa ≈ Rp11814.6 Miliar (kumulatif)
Top % pasien (biaya tertinggi) % total belanja FKRTL
1 15.6
5 39.1
10 54.8
20 72.4
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)

9.1 Kelompok biaya INA-CBG teratas

cb <- A$cbg_top |> dplyr::mutate(cbg=stringr::str_to_title(cbg)) |>
  dplyr::select(cbg,n_claims,total_bil_idr,mean_cost)
gt::gt(cb) |>
  gt::cols_label(cbg="Deskripsi INA-CBG",n_claims="Klaim (sampel)",total_bil_idr="Total (Miliar Rp, tertimbang)",mean_cost="Rata2/klaim (Rp)") |>
  gt::tab_header(title=gt::md("**Tabel 5.3 — 15 Kelompok INA-CBG Teratas (volume klaim)** · _Unit: Klaim FKRTL_")) |>
  gt::fmt_number(columns=c(n_claims,mean_cost),decimals=0,use_seps=TRUE) |>
  gt::fmt_number(columns=total_bil_idr,decimals=1) |>
  gt::data_color(columns=n_claims,colors=scales::col_numeric(c("#dbeafe","#1e3a5f"),domain=NULL)) |>
  gt::data_color(columns=total_bil_idr,colors=scales::col_numeric(c("#fef3c7","#d97706"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 5.3 — 15 Kelompok INA-CBG Teratas (volume klaim) · Unit: Klaim FKRTL
Deskripsi INA-CBG Klaim (sampel) Total (Miliar Rp, tertimbang) Rata2/klaim (Rp)
Penyakit Kronis Kecil Lain-Lain 997,588 4,648.1 217,271
Prosedur Rehabilitasi 254,109 1,090.3 176,909
Psikotherapi Individu Dewasa Bukan Akut 61,392 252.1 239,879
Konsultasi Atau Pemeriksaan Lain-Lain 60,942 143.9 148,431
Prosedur Therapi Fisik Dan Prosedur Kecil Muskuloskletal 41,349 146.6 136,019
Penyakit Akut Kecil Lain-Lain 38,727 199.9 230,874
Pelayanan Kesehatan Mental Ekstensif 31,867 235.6 387,414
Penyakit Kronis Kecil Lainlain 18,796 95.1 232,172
Schizofrenia Ringan 17,834 2,352.9 5,852,056
Prosedur Tes Diagnostik Kesehatan Jiwa 9,169 63.2 339,495
Psikotherapi Individu Pada Kanak-Kanak Masalah Kesehatan Mental 6,379 49.8 307,659
Terapi Kelompok 3,106 18.9 358,105
Gangguan Bipolar Ringan 2,656 279.7 4,367,815
Prosedur Tes Fungsi Pada Telinga, Hidung, Mulut Dan Tenggorokan 1,973 17.2 369,342
Medical Check-Up 1,725 1.9 106,809
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
Key takeaway P5: Belanja klaim FKRTL keswa tumbuh seiring volume. Biaya terkonsentrasi pada sebagian kecil pasien kronik-berat (Pareto) — target intervensi manajemen kasus. Rawat inap & skizofrenia adalah pendorong biaya utama.

10 Pilar I — Ekuitas

⑨ Pilar I · Ekuitas · Segmen (SES) · Geografi · Representasi vs Populasi Umum
Untuk keswa, treatment gap & ekuitas akses adalah isu utama. Stratifikasi: segmen (PBI vs Non-PBI), geografi (Jawa vs luar), dan — kunci — perbandingan terhadap populasi JKN umum (representation index, served-rate, gradien SES).
es <- A$equity_segment |> filter(pbi!="Missing")
gt::gt(es) |> gt::cols_label(pbi="Segmen",n_pts="Pasien (sampel)",wt_pts="Pasien (tertimbang)",
  mean_visits="Rata2 kunjungan/pasien",pct_inp="% pernah rawat inap",median_cost="Median biaya/pasien (Rp)") |>
  gt::tab_header(title=gt::md("**Tabel 6.1 — Utilisasi menurut Segmen Kepesertaan (PBI vs Non-PBI)** · _Unit: Pasien unik (tertimbang)_")) |>
  gt::fmt_number(columns=c(n_pts,wt_pts,median_cost),decimals=0,use_seps=TRUE) |>
  gt::tab_source_note(gt::md(paste(CAP,"| PBI = PBI APBN/APBD (disubsidi); Non-PBI = PPU/PBPU/Bukan Pekerja"))) |> gfmt()
Tabel 6.1 — Utilisasi menurut Segmen Kepesertaan (PBI vs Non-PBI) · Unit: Pasien unik (tertimbang)
Segmen Pasien (sampel) Pasien (tertimbang) Rata2 kunjungan/pasien % pernah rawat inap Median biaya/pasien (Rp)
Non-PBI 66,631 1,349,398 18 12.9 1,731,600
PBI (Disubsidi) 55,741 1,294,943 16 19.0 2,011,700
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional) | PBI = PBI APBN/APBD (disubsidi); Non-PBI = PPU/PBPU/Bukan Pekerja
ei <- A$equity_island |> filter(island!="Tidak diketahui") |> mutate(island=fct_reorder(island,mean_visits))
ggplot(ei, aes(mean_visits, island)) + geom_col(fill=TEAL,width=.7) +
  geom_text(aes(label=round(mean_visits,1)),hjust=-0.2,size=3,color=NAVY,fontface="bold") +
  scale_x_continuous(expand=expansion(mult=c(0,.12))) +
  labs(title="Intensitas Layanan per Pasien menurut Pulau · Unit: rata-rata per pasien",
       subtitle="Rata-rata kunjungan per pasien — proxy kedalaman akses (RSJ terkonsentrasi di Jawa)",
       x="Rata2 kunjungan/pasien", y=NULL, caption=CAP) + th()

10.1 Representasi & akses jiwa relatif terhadap Populasi JKN Umum

Representation index = % terlayani jiwa ÷ % populasi umum (>1 over-represented, <1 under-served). Served-rate = pasien jiwa per 100.000 peserta JKN (numerator kohort jiwa ÷ denominator sample reguler). Breakdown by jenis kelamin · usia · segmen · pulau.
ri <- A$repr_index |> filter(char %in% c("Jenis Kelamin","Kelompok Usia","Segmentasi (Membership)","Pulau")) |>
  arrange(repr) |> mutate(level=factor(level, levels=unique(level)))
ggplot(ri, aes(repr, level, fill=repr>=1)) + geom_col(width=.7) +
  geom_vline(xintercept=1, linetype="dashed", color=GREY) +
  geom_text(aes(label=sprintf("%.2f",repr), hjust=ifelse(repr>=1,-0.2,1.2)), size=2.6, color=NAVY) +
  facet_wrap(~char, scales="free_y", ncol=2) +
  scale_fill_manual(values=c(`TRUE`=BLUE,`FALSE`=RED), guide="none") +
  scale_x_continuous(expand=expansion(mult=c(.14,.14))) +
  labs(title="Representation Index: Pasien Jiwa vs Populasi Umum (breakdown) · Unit: rasio",
       subtitle="1 = proporsional; <1 (merah) = under-served; >1 (biru) = over-represented",
       x="Representation index (Overall ÷ Populasi Umum)", y=NULL, caption=CAP) + th(10)

sr <- A$served_rate_prov |> filter(prov_name!="Tidak diketahui") |> mutate(prov_name=fct_reorder(prov_name,rate_per100k))
ISL_COLS <- c("Jawa"=NAVY,"Sumatera"=BLUE,"Sulawesi"=TEAL,"Kalimantan"=AMBER,"Bali-Nusra"=PURPLE,"Maluku-Papua"=RED)
ggplot(sr, aes(rate_per100k, prov_name, fill=island)) + geom_col(width=.74) +
  geom_text(aes(label=scales::comma(rate_per100k)), hjust=-0.1, size=2.5, color=NAVY) +
  scale_fill_manual(values=ISL_COLS, name=NULL) +
  scale_x_continuous(labels=scales::comma, expand=expansion(mult=c(0,.13))) +
  labs(title="Served-Rate Gangguan Jiwa per 100.000 Peserta JKN, per Provinsi · Unit: per 100k",
       subtitle="Rentang ~12× — tertinggi DI Yogyakarta/DKI, terendah Papua (gurun layanan timur)",
       x="Pasien jiwa per 100.000 peserta JKN", y=NULL, caption=CAP) + th(10)

sg <- A$ses_gradient |> mutate(segmen=factor(segmen, levels=segmen[order(rate_per1000)]))
ggplot(sg, aes(rate_per1000, segmen, fill=pbi)) + geom_col(width=.66) +
  geom_text(aes(label=rate_per1000), hjust=-0.15, size=3, color=NAVY, fontface="bold") +
  scale_fill_manual(values=c("PBI (disubsidi)"=RED,"Non-PBI"=BLUE), name=NULL) +
  scale_x_continuous(expand=expansion(mult=c(0,.12))) +
  labs(title="Gradien SES: Served-Rate Jiwa per 1.000 Peserta menurut Segmen · Unit: per 1.000",
       subtitle="Inverse care law — segmen termiskin (PBI APBN) justru paling rendah aksesnya",
       x="Pasien jiwa per 1.000 peserta segmen", y=NULL, caption=CAP) + th()

10.1.1 Versi basis REGULER (internally-consistent — num + denom sefrekuensi)

Served-rate di atas memakai numerator kohort ÷ denominator reguler (valid kira-kira di tahun-seed). Versi di bawah memakai numerator DAN denominator dari reguler (sampel household sama) → rate spasial/SES yang konsisten secara desain. Pola ekuitas sama (robust), menguatkan kesimpulan.

10.1.1.1 Served-rate per provinsi (reguler)

provref <- A$geo_prov |> dplyr::select(prov,prov_name,island) |> dplyr::distinct()
srr <- A$xcheck$served_rate_prov_reg |> left_join(provref, by="prov") |>
  filter(!is.na(prov_name), !is.na(rate_per100k), prov<95) |> mutate(prov_name=fct_reorder(prov_name,rate_per100k))
ggplot(srr, aes(rate_per100k, prov_name, fill=island)) + geom_col(width=.74) +
  geom_text(aes(label=scales::comma(rate_per100k)), hjust=-0.1, size=2.5, color=NAVY) +
  scale_fill_manual(values=ISL_COLS, name=NULL) +
  scale_x_continuous(labels=scales::comma, expand=expansion(mult=c(0,.13))) +
  labs(title="Served-Rate Jiwa per 100k Peserta JKN, per Provinsi (BASIS REGULER) · Unit: per 100k",
       subtitle="Numerator + denominator dari sampel reguler (household) — gradien spasial robust (Bali/DKI/DIY tinggi, Papua rendah)",
       x="Pasien jiwa per 100.000 peserta JKN", y=NULL, caption=CAP) + th(10)

10.1.1.2 Gradien SES (reguler)

sgr <- A$xcheck$served_rate_seg_reg |> mutate(segmen=factor(segmen, levels=segmen[order(rate_per1000)]))
ggplot(sgr, aes(rate_per1000, segmen, fill=pbi)) + geom_col(width=.66) +
  geom_text(aes(label=rate_per1000), hjust=-0.15, size=3, color=NAVY, fontface="bold") +
  scale_fill_manual(values=c("PBI (disubsidi)"=RED,"Non-PBI"=BLUE), name=NULL) +
  scale_x_continuous(expand=expansion(mult=c(0,.12))) +
  labs(title="Gradien SES Served-Rate Jiwa /1.000 (BASIS REGULER) · Unit: per 1.000",
       subtitle="Inverse care law tetap muncul di sampel reguler: PBI APBN terendah (~4,1) vs mandiri tertinggi (~16,2)",
       x="Pasien jiwa per 1.000 peserta segmen", y=NULL, caption=CAP) + th()

ovmap <- c("Jenis Kelamin"="sex_lab","Kelompok Usia"="age_kat","Segmentasi (Membership)"="seg_lab","Pulau"="island")
chi <- lapply(names(ovmap), function(ch){
  v <- ovmap[[ch]]
  ov <- pt |> filter(!is.na(.data[[v]]) & !as.character(.data[[v]]) %in% c("Missing","Tidak diketahui")) |>
    count(level=as.character(.data[[v]]), name="ov")
  gp <- A$genpop_dist |> filter(char==ch) |> select(level, gp=n)
  d <- inner_join(ov,gp,by="level"); M <- as.matrix(d[,c("ov","gp")])
  ct <- suppressWarnings(chisq.test(M)); cv <- sqrt(as.numeric(ct$statistic)/(sum(M)*(min(dim(M))-1)))
  data.frame(Karakteristik=ch, `Cramér V`=round(cv,3), `p`="<0,001", check.names=FALSE)
}) |> bind_rows()
gt::gt(chi) |> gt::tab_header(title=gt::md("**Tabel 6.2 — Uji Beda Distribusi: Pasien Jiwa vs Populasi Umum** · _Unit: sampel_"),
  subtitle=gt::md("_χ² (sampel mentah); n sangat besar → selalu signifikan, gunakan Cramér's V untuk besaran efek_")) |>
  gt::data_color(columns=`Cramér V`, colors=scales::col_numeric(c("#f0fdf4","#dc2626"),domain=NULL)) |>
  gt::tab_source_note(gt::md(CAP)) |> gfmt()
Tabel 6.2 — Uji Beda Distribusi: Pasien Jiwa vs Populasi Umum · Unit: sampel
χ² (sampel mentah); n sangat besar → selalu signifikan, gunakan Cramér’s V untuk besaran efek
Karakteristik Cramér V p
Jenis Kelamin 0.045 <0,001
Kelompok Usia 0.008 <0,001
Segmentasi (Membership) 0.075 <0,001
Pulau 0.022 <0,001
Sumber: Data Sampel BPJS Kesehatan 2015–2024 | ICD-10 F00–F99 | FKTP + FKRTL | tertimbang PSTV15 (proyeksi nasional)
Key takeaway Ekuitas: Pembandingan dengan populasi JKN umum mengungkap inverse care law kesehatan jiwa: segmen termiskin (PBI APBN) served-rate 6,3/1.000 vs mandiri (PBPU) 16,6/1.000 (~2,6× lebih rendah; representation index 0,71 vs 1,90). Geografis sangat timpang: ~12× antar-provinsi (Yogyakarta/DKI ~1.700–1.800 vs Papua 151/100k), dan Maluku-Papua representation 0,16 — wilayah timur & kelompok miskin paling under-served. JKN membiayai keswa kelompok rentan, tetapi akses belum pro-poor & belum merata spasial.

11 Keterbatasan & langkah lanjut

Keterbatasan utama. (1) Klaim = populasi terlayani, bukan prevalensi sejati (treatment gap besar). (2) Kohort Mental adalah oversample kumulatif — sebagian tren mencerminkan akrual kohort + ekspansi JKN, bukan murni insidensi. (3) Mortalitas under-captured (PSTV18 hanya 2023–24; FKL14 hanya in-hospital). (4) Self-harm praktis tak tercatat di klaim. (5) Denominator member hanya 2023–2024 → rate per-member penuh belum tersedia; estimasi memakai bobot PSTV15. (6) Data obat tidak tersedia → kontinuitas antipsikotik (PDC) belum dihitung.

Belum termasuk edisi ini (fase lanjut, sesuai blueprint): Age-Period-Cohort (HAPC), trajektori utilisasi (GBTM), SMR/mortality gap dengan life-table, kontinuitas obat antipsikotik (PDC — butuh data obat), concentration index/Wagstaff & MAIHDA formal, ITS/DiD kebijakan (UU Keswa 18/2014, Bebas Pasung, COVID), model biaya GLM-Gamma, model multilevel faskes, model prediksi (TRIPOD+AI), dan choropleth kabupaten/kota interaktif (perlu verifikasi indeks via skill indonesia-district-map).

if(requireNamespace("writexl",quietly=TRUE)){
  writexl::write_xlsx(list(
    cohort_flow=A$cohort_flow, strata=A$strata_patient, epidemiologi_dasar=epi,
    prevalensi_2024_grup=gr24,
    prevalensi_tahun=A$prev_year_total, prevalensi_grup=A$prev_year |> mutate(grp=as.character(grp)),
    insidensi=A$incidence, karakteristik_sampel=A$table1, karakteristik_n=A$table1_n,
    geo_provinsi=A$geo_prov, geo_pulau=A$geo_island,
    utilisasi_tahun=A$util_year, visit_rate=A$visit_rate |> mutate(grp=as.character(grp)),
    los=A$los |> mutate(grp=as.character(grp)), fuh=A$fuh |> mutate(grp=as.character(grp)),
    gaps=A$gaps, readmit=A$readmit, komorbiditas=A$comorbid,
    mortalitas_inhosp=A$mort_inhosp, mortalitas_pstv18=A$mort_pstv18,
    biaya_tahun=A$cost_year, biaya_grup=A$cost_group |> mutate(grp=as.character(grp)),
    pareto=A$pareto, ekuitas_segmen=A$equity_segment, ekuitas_pulau=A$equity_island,
    kohort_stabil=A$stable_prev, kabupaten=A$district_prev, tempat_layanan=A$care_setting_year,
    los_kelas_rs=A$los_class, igd_psikiatri=A$emergency_year, kepemilikan=A$ownership,
    inacbg_top=A$cbg_top, fuh_tahun=A$fuh_year, fuh_segmen=A$fuh_segment, fuh_readmisi=A$fuh_readmit,
    komorbid_count=A$comorbid_count, mortalitas_grup=A$mort_group,
    tipologi_kunjungan=A$visit_typology, intensitas_tahun=A$intensity_year,
    jiwa_vs_fisik=A$mental_vs_physical_year, fisik_bab=A$phys_chapter,
    fisik_dx_top=A$phys_dx_top, biaya_jiwa_vs_fisik=A$cost_split,
    fktp_diagnosis=A$fktp_dx |> mutate(grp=as.character(grp)), cakupan_layanan=A$coverage,
    rujukan_rate_tahun=A$referral_rate_year, tipe_perujuk=A$referrer_type, rujukan_geo=A$referral_geo,
    rujukan_geo_prov=A$referral_geo_prov, alur_faskes=A$flow_levels,
    member_faskes_geo=A$mf_geo, member_faskes_prov=A$mf_geo_prov,
    representation_index=A$repr_index, served_rate_provinsi=A$served_rate_prov,
    ses_gradient=A$ses_gradient, genpop_distribusi=A$genpop_dist),
    file.path(OUT_DIR,"tables_mental_jkn.xlsx"))
}
cat("Artefak diekspor ke:", normalizePath(OUT_DIR), "\n")
## Artefak diekspor ke: /opt/project_center_mirror/ARC9. Mental Health Institute/9.3 JKN on Mental Health/analysis/outputs

Analisis sistem kesehatan berbasis data administratif agregat. Menyentuh mortalitas dan self-harm sebagai variabel epidemiologis populasi. Bila topik ini relevan secara pribadi bagi Anda atau rekan, hubungi layanan dukungan kesehatan jiwa (mis. SEJIWA 119 ext 8).