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.
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) |
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.
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.
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()

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()

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”.
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.
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.
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).
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()

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.
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)
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()

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.
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) |
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()

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.
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()

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.
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 |
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.
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.
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.
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) |
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()

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) |
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).
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) |
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.
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()

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()

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.
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)

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.
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).