1. Pendahuluan

Pandemi Coronavirus Disease 2019 (COVID-19) telah menjadi krisis kesehatan global yang memberikan dampak multidimensional yang signifikan terhadap tatanan sosial, ketahanan sistem medis, serta stabilitas perekonomian di berbagai negara, termasuk Indonesia. Sebagai negara kepulauan dengan karakteristik geografis yang luas dan heterogenitas demografi yang tinggi, dinamika transmisi virus SARS-CoV-2 di Indonesia menunjukkan pola penyebaran yang sangat kompleks. Jumlah penduduk yang besar dan disparitas infrastruktur kesehatan antardaerah menjadi faktor determinan utama yang memengaruhi beban risiko serta kapasitas respons penanggulangan wabah di setiap wilayah administratif.

Dalam perjalanannya, akumulasi kasus terkonfirmasi positif dan angka mortalitas menunjukkan ketimpangan yang sangat nyata antarpulau dan antarprovinsi di Indonesia. Wilayah pusat pertumbuhan ekonomi dan aglomerasi perkotaan, khususnya di Pulau Jawa, tercatat sebagai episentrum utama dengan konsentrasi jutaan kasus dan puluhan ribu kematian. Sebaliknya, sebagian besar provinsi di luar Pulau Jawa menghadapi tantangan yang berbeda, seperti keterbatasan akses fasilitas rujukan intensif dan keterjangkauan logistik penanganan medis meskipun secara kumulatif mencatatkan volume kasus yang lebih rendah. Keberadaan disparitas ekstrem dan data observasi pencilan (outlier) ini menimbulkan tantangan metodologis tersendiri dalam melakukan pengelompokan wilayah secara objektif dan akurat.

Untuk merumuskan strategi penanganan pasca-pandemi (recovery phase) serta kesiapsiagaan mitigasi krisis kesehatan di masa depan, dibutuhkan pemetaan segmentasi provinsi berbasis bukti empiris yang representatif. Pendekatan analisis klaster non-hierarki menjadi solusi analitis yang efektif untuk mengidentifikasi tipologi daerah berdasarkan variabel demografi dan beban kasus medis. Penelitian ini menerapkan algoritma K-Medoids (Partitioning Around Medoids / PAM) yang memiliki keunggulan ketahanan (robustness) terhadap gangguan data ekstrem dibandingkan metode berbasis rata-rata konvensional. Dengan menetapkan titik observasi nyata sebagai pusat klaster (medoid), hasil segmentasi ini diharapkan mampu memberikan pemahaman yang komprehensif mengenai peta kerentanan wilayah di Indonesia sehingga dapat menjadi rujukan strategis bagi pengambil kebijakan dalam merancang alokasi sumber daya kesehatan yang lebih proporsional, adil, dan tepat sasaran.

2. Tinjauan Pustaka

2.1 Analisis Klaster (Clustering)

Clustering adalah teknik dalam analisis data multivariat dan machine learning (unsupervised learning) untuk mengelompokkan objek-objek ke dalam beberapa kelompok (cluster) berdasarkan kesamaan karakteristiknya[cite: 2]. Data di dalam satu kelompok diharapkan memiliki tingkat homogenitas maksimum (maximum intra-cluster similarity), sedangkan data antarkelompok memiliki tingkat heterogenitas maksimum (minimum inter-cluster similarity)[cite: 2]. Metode klasterisasi secara umum dibagi menjadi dua pendekatan utama, yaitu hierarchical clustering dan partitional clustering[cite: 2].

2.2 Pencilan (Outlier)

Outlier atau pencilan merupakan observasi yang nilainya menyimpang secara ekstrem dari pola umum sebaran data lainnya[cite: 2]. Adanya pencilan berpotensi mendistorsi perhitungan jarak serta membiaskan struktur penaksiran klaster[cite: 2]. Deteksi visual terhadap pencilan umumnya dilakukan melalui diagram kotak-garis (boxplot) berbasis metode Interquartile Range (IQR), di mana titik data yang berada di luar batas whisker (\(Q_1 - 1{,}5 \times \text{IQR}\) atau \(Q_3 + 1{,}5 \times \text{IQR}\)) diklasifikasikan sebagai pencilan[cite: 2].

2.3 Asumsi Non-Multikolinearitas

Multikolinearitas adalah kondisi korelasi linear yang sangat tinggi antara dua atau lebih variabel prediktor[cite: 2]. Dalam analisis klaster, korelasi ganda yang berlebih dapat menyebabkan pembobotan jarak yang tumpang tindih (redundant). Deteksi multikolinearitas diukur menggunakan nilai Variance Inflation Factor (VIF)[cite: 2]:

\[ \text{VIF}_j = \frac{1}{1 - R_j^2} \]

dengan \(R_j^2\) adalah koefisien determinasi hasil regresi variabel ke-\(j\) terhadap variabel lainnya[cite: 2]. Nilai \(\text{VIF} < 10\) menunjukkan bahwa model bebas dari masalah multikolinearitas[cite: 2].

2.4 Normalisasi Min-Max

Normalisasi data merupakan tahap prapemrosesan data (data preprocessing) yang bertujuan menyelaraskan rentang nilai pada setiap variabel agar variabel dengan skala satuan besar tidak mendominasi perhitungan jarak[cite: 2]. Metode Min-Max Scaling mengonversi data secara linear ke dalam rentang interval \([0, 1]\) menggunakan formula[cite: 2]:

\[ x_{ij}^{*} = \frac{x_{ij} - \min_j(x)}{\max_j(x) - \min_j(x)} \]

dengan \(x_{ij}^{*}\) adalah nilai hasil normalisasi objek ke-\(i\) pada variabel ke-\(j\), \(x_{ij}\) adalah nilai asli, sedangkan \(\min_j(x)\) dan \(\max_j(x)\) berturut-turut adalah nilai minimum dan maksimum pada variabel ke-\(j\)[cite: 2].

2.5 Algoritma K-Medoids (Partitioning Around Medoids / PAM)

K-Medoids merupakan algoritma partitional clustering yang mempartisi \(n\) objek ke dalam \(k\) kelompok berdasarkan tingkat kemiripan jarak[cite: 2]. Berbeda dengan K-Means yang menghitung pusat klaster menggunakan rata-rata (centroid), K-Medoids memilih titik observasi riil di dalam data sebagai pusat (medoid)[cite: 2]. Hal ini membuat K-Medoids sangat tahan (robust) terhadap gangguan nilai pencilan (outlier)[cite: 2].

Jarak kemiripan antardata dihitung menggunakan Euclidean Distance[cite: 2]:

\[ d(p, q) = \sqrt{\sum_{i=1}^{p} (p_i - q_i)^2} \]

dengan \(d(p,q)\) adalah jarak antara objek \(p\) dan \(q\), serta \(p_i\) dan \(q_i\) adalah koordinat data pada variabel ke-\(i\)[cite: 2].

Langkah-langkah algoritma K-Medoids (PAM) meliputi[cite: 2]: 1. Menentukan jumlah klaster \(k\)[cite: 2]. 2. Memilih \(k\) objek awal secara representatif sebagai medoid awal[cite: 2]. 3. Mengalokasikan setiap objek non-medoid ke medoid terdekat berdasarkan jarak Euclidean[cite: 2]. 4. Memilih kandidat objek non-medoid secara iteratif dan menghitung total selisih biaya penukaran simpangan (\(S\))[cite: 2]. 5. Melakukan pertukaran titik jika penukaran menghasilkan nilai simpangan negatif (\(S < 0\))[cite: 2]. 6. Mengulangi proses hingga konfigurasi medoid tidak mengalami perubahan lagi[cite: 2].

2.6 Silhouette Coefficient Method

Metode Silhouette Coefficient digunakan untuk mengukur validitas dan kualitas struktur pemisahan klaster[cite: 2]. Koefisien Silhouette objek ke-\(i\) dirumuskan sebagai[cite: 2]:

\[ s(i) = \frac{b(i) - a(i)}{\max\{a(i), b(i)\}} \]

dengan: * \(a(i) = \frac{1}{|A| - 1} \sum_{j \in A, j \neq i} d(i, j)\) : Rata-rata jarak objek ke-\(i\) dengan seluruh objek lain di dalam klaster yang sama (\(A\))[cite: 2]. * \(b(i) = \min_{C \neq A} \frac{1}{|C|} \sum_{j \in C} d(i, j)\) : Rata-rata jarak minimum objek ke-\(i\) dengan objek pada klaster lain terdekat (\(C\))[cite: 2].

Nilai rata-rata Silhouette Coefficient (\(\overline{SC}\)) berada pada rentang \([-1, 1]\) dengan kriteria interpretasi sebagai berikut (Rousseeuw, 1987)[cite: 2]:

Rentang Nilai Silhouette Keterangan Struktur Klaster
\(0{,}70 < \overline{SC} \le 1{,}00\) Struktur Kuat (Strong Structure)[cite: 2]
\(0{,}50 < \overline{SC} \le 0{,}70\) Struktur Baik (Reasonable Structure)[cite: 2]
\(0{,}25 < \overline{SC} \le 0{,}50\) Struktur Lemah (Weak Structure)[cite: 2]
\(\overline{SC} \le 0{,}25\) Tidak Terstruktur (No Substantial Structure)[cite: 2]

3. Deskripsi Data

3.1 Sumber Data

Data yang digunakan dalam penelitian ini merupakan data sekunder yang diunduh dari repositori publik Kaggle dengan judul COVID-19 Indonesia Time Series All Data melalui tautan berikut: https://www.kaggle.com/datasets/hendratno/covid19-indonesia.

3.2 Kondisi Data Awal (Raw Data)

Dataset primer yang diperoleh merupakan data runtun waktu harian (daily time-series data) yang mencakup periode 1 Maret 2020 hingga 16 September 2022 dengan volume sebanyak 31.822 baris observasi dan 38 variabel. Dataset ini memiliki struktur yang belum terstandardisasi untuk analisis (cross-section), sehingga memerlukan tahapan lanjutan agar siap digunakan untuk analisis klaster.

Adapun tampilan struktur asli dari (raw data) disajikan pada Tabel 1.

# 1. Membaca dataset mentah langsung dari file CSV
raw_data <- read.csv("covid_19_indonesia_time_series_all.csv")

# 2. Menampilkan beberapa baris pertama secara apa adanya dari CSV asli
cuplikan_mentah <- head(raw_data[, c("Date", "Location", "Location.Level", "Province", "New.Cases", "Total.Cases", "Total.Deaths", "Population")], 5)

kable(cuplikan_mentah, 
      caption = "Tabel 1: Cuplikan Struktur Dataset Mentah Awal (Raw Data) yang Belum Diproses")
Tabel 1: Cuplikan Struktur Dataset Mentah Awal (Raw Data) yang Belum Diproses
Date Location Location.Level Province New.Cases Total.Cases Total.Deaths Population
3/1/2020 DKI Jakarta Province DKI Jakarta 2 39 20 10846145
3/2/2020 DKI Jakarta Province DKI Jakarta 2 41 20 10846145
3/2/2020 Indonesia Country 2 2 0 265185520
3/2/2020 Riau Province Riau 1 1 0 6074100
3/3/2020 DKI Jakarta Province DKI Jakarta 2 43 20 10846145

3.3 Tahapan Pembersihan dan Transformasi Data

Transformasi data mentah menjadi data siap analisis dilakukan melalui penyaringan baris pada titik waktu akhir observasi, yaitu 15 September 2022, dengan mengeliminasi data agregat nasional (Indonesia) sehingga diperoleh 32 unit provinsi. Selanjutnya, dilakukan seleksi fitur dengan menetapkan tiga indikator utama yang merepresentasikan skala demografi dan tingkat keparahan epidemiologis di setiap daerah, meliputi Population (\(X_1\)), Total_Cases (\(X_2\)), dan Total_Deaths (\(X_3\)). Struktur data bersih hasil transformasi tersebut ditampilkan pada Tabel 2.

# 1. Eksekusi filter tanggal dan level provinsi
covid_prov <- raw_data %>%
  filter(grepl("2022-09-15|9/15/2022", Date)) %>%
  filter(Location.Level == "Province") %>%
  distinct(Province, .keep_all = TRUE)

# 2. Seleksi 3 variabel utama
data_cluster <- covid_prov %>%
  select(
    Province,
    Population = Population,
    Total_Cases = Total.Cases,
    Total_Deaths = Total.Deaths
  )

# 3. Menetapkan nama provinsi sebagai indeks baris
rownames(data_cluster) <- data_cluster$Province
data_analysis <- data_cluster %>% select(-Province)

# Menampilkan tabel data bersih siap analisis
kable(head(data_analysis, 10), 
      digits = 2, 
      format.args = list(big.mark = "."),
      caption = "Tabel 2: Data Bersih Hasil Transformasi pada 10 Provinsi Pertama")
Tabel 2: Data Bersih Hasil Transformasi pada 10 Provinsi Pertama
Population Total_Cases Total_Deaths
Aceh 5.247.257 44.038 2.223
Bali 4.216.171 166.831 4.731
Banten 10.722.374 333.875 2.950
Bengkulu 1.999.539 29.173 522
DKI Jakarta 10.846.145 1.412.511 15.513
Daerah Istimewa Yogyakarta 3.631.015 224.307 5.928
Jambi 3.493.357 38.643 889
Jawa Barat 45.161.325 1.173.731 15.937
Jawa Tengah 36.364.072 636.409 33.489
Jawa Timur 40.479.023 601.545 31.764

4. Tahap Eksplorasi Data

4.1 Statistik Deskriptif

# Menghitung ringkasan statistik deskriptif
stat_desc <- data.frame(
  Variabel = colnames(data_analysis),
  N        = sapply(data_analysis, length),
  Mean     = sapply(data_analysis, mean),
  Median   = sapply(data_analysis, median),
  SD       = sapply(data_analysis, sd),
  Min      = sapply(data_analysis, min),
  Max      = sapply(data_analysis, max)
)

kable(stat_desc, 
      digits = 2, 
      format.args = list(big.mark = "."),
      caption = "Tabel 3: Ringkasan Statistik Deskriptif Variabel Analisis")
Tabel 3: Ringkasan Statistik Deskriptif Variabel Analisis
Variabel N Mean Median SD Min Max
Population Population 32 8.201.402.66 4.278.259.5 11.157.113.60 648.407 45.161.325
Total_Cases Total_Cases 32 198.993.91 73.184.0 323.851.23 14.595 1.412.511
Total_Deaths Total_Deaths 32 4.906.62 2.055.5 8.145.88 295 33.489

Berdasarkan Tabel 3, sebaran nilai populasi berkisar antara \(648.407\) hingga \(45.161.325\) jiwa, total kasus antara \(14.595\) hingga \(1.412.511\) kasus, dan angka kematian antara \(295\) hingga \(33.489\) jiwa.

4.2 Visualisasi Perbandingan Wilayah (Top 10 Daerah Kasus Tertinggi)

Untuk melengkapi pemahaman statistik deskriptif secara visual, Gambar 1 menyajikan perbandingan 10 provinsi teratas dengan akumulasi kasus positif dan kematian tertinggi di Indonesia.

top10_cases <- data_cluster %>%
  arrange(desc(Total_Cases)) %>%
  slice(1:10)

top10_deaths <- data_cluster %>%
  arrange(desc(Total_Deaths)) %>%
  slice(1:10)

par(mfrow = c(1, 2), mar = c(7, 4, 3, 1))

# Barplot 1: 10 Provinsi Kasus Tertinggi
barplot(top10_cases$Total_Cases / 1000, 
        names.arg = top10_cases$Province, 
        las = 2, 
        col = "#3498db",
        main = "Top 10 Total Kasus (Ribu)",
        ylab = "Jumlah Kasus (Ribu)",
        cex.names = 0.8)

# Barplot 2: 10 Provinsi Kematian Tertinggi
barplot(top10_deaths$Total_Deaths / 1000, 
        names.arg = top10_deaths$Province, 
        las = 2, 
        col = "#e74c3c",
        main = "Top 10 Total Kematian (Ribu)",
        ylab = "Jumlah Kematian (Ribu)",
        cex.names = 0.8)

par(mfrow = c(1, 1))
Gambar 1: Perbandingan 10 Provinsi dengan Akumulasi Kasus dan Kematian Tertinggi


4.3 Pengecekan Outlier

Pengecekan keberadaan nilai pencilan (outlier) dilakukan menggunakan visualisasi Boxplot untuk masing-masing variabel[cite: 2]:

par(mfrow = c(1, 3))
boxplot(data_analysis$Population, main = "Boxplot Population", col = "lightblue", ylab = "Jiwa")
boxplot(data_analysis$Total_Cases, main = "Boxplot Total Cases", col = "lightgreen", ylab = "Kasus")
boxplot(data_analysis$Total_Deaths, main = "Boxplot Total Deaths", col = "salmon", ylab = "Jiwa")

par(mfrow = c(1, 1))
Gambar 2: Boxplot Distribusi dan Identifikasi Outlier Variabel Analisis


Visualisasi boxplot pada Gambar 2 mengonfirmasi keberadaan titik-titik data ekstrem di atas batas kuartil atas, yang merupakan provinsi aglomerasi padat di Pulau Jawa[cite: 2]. Hal ini mempertegas justifikasi pemilihan metode K-Medoids yang memiliki ketahanan (robustness) tinggi terhadap outlier[cite: 2].

5. Tahap Pre-Processing Data

5.1 Uji Asumsi Non-Multikolinearitas

Uji non-multikolinearitas dilakukan untuk memastikan tidak adanya korelasi linear yang berlebih atau informasi yang tumpang tindih (redundant) antarvariabel prediktor, sehingga perhitungan jarak pada algoritma K-Medoids memiliki bobot yang proporsional.

Deteksi multikolinearitas diuji menggunakan matriks korelasi Pearson serta perhitungan nilai Variance Inflation Factor (VIF). Nilai \(\text{VIF} < 10\) mengindikasikan bahwa antarvariabel bebas dari gangguan multikolinearitas.

# Matriks Korelasi
mat_korelasi <- cor(data_analysis)
corrplot(mat_korelasi, method = "number", type = "upper", tl.col = "black")

# Perhitungan nilai VIF
vif_model <- vif(lm(Population ~ Total_Cases + Total_Deaths, data = data_analysis))
kable(data.frame(Variabel = names(vif_model), VIF = vif_model), 
      digits = 2, 
      caption = "Tabel 4: Nilai Variance Inflation Factor (VIF)")
Tabel 4: Nilai Variance Inflation Factor (VIF)
Variabel VIF
Total_Cases Total_Cases 1.99
Total_Deaths Total_Deaths 1.99

Interpretasi:
Berdasarkan Tabel 4, seluruh variabel prediktor menghasilkan nilai \(\text{VIF} = 1.99\) yang berada jauh di bawah ambang batas kritis (\(\text{VIF} < 10\)). Dengan demikian, asumsi non-multikolinearitas terpenuhi dan seluruh variabel (Population, Total_Cases, dan Total_Deaths) dapat digunakan secara bersamaan dalam proses klasterisasi.

5.2 Normalisasi Data (Min-Max Scaling)

Agar perbedaan skala satuan antarvariabel tidak mendistorsi perhitungan jarak Euclidean, dilakukan transformasi Min-Max Scaling ke rentang interval \([0, 1]\)[cite: 2]:

\[x_{\text{scaled}} = \frac{x - x_{\min}}{x_{\max} - x_{\min}}\]

# Fungsi Min-Max Scaling
min_max_scale <- function(x) {
  return((x - min(x)) / (max(x) - min(x)))
}

scaled_data <- as.data.frame(lapply(data_analysis, min_max_scale))
rownames(scaled_data) <- rownames(data_analysis)

# Cuplikan data setelah dinormalisasi
kable(head(scaled_data, 6), digits = 4, caption = "Tabel 5: Data Hasil Min-Max Scaling (6 Baris Pertama)")
Tabel 5: Data Hasil Min-Max Scaling (6 Baris Pertama)
Population Total_Cases Total_Deaths
Aceh 0.1033 0.0211 0.0581
Bali 0.0802 0.1089 0.1336
Banten 0.2263 0.2284 0.0800
Bengkulu 0.0304 0.0104 0.0068
DKI Jakarta 0.2291 1.0000 0.4585
Daerah Istimewa Yogyakarta 0.0670 0.1500 0.1697

6. Tahap Klasterisasi

6.1 Penentuan Jumlah Klaster Optimal (Silhouette Method)

Metode Average Silhouette Width digunakan untuk mengukur seberapa baik setiap objek berada di dalam kelompoknya[cite: 2].

fviz_nbclust(scaled_data, pam, method = "silhouette") +
  ggtitle("Penentuan Jumlah Klaster Optimal (Silhouette Method)") +
  theme_minimal()

Berdasarkan grafik evaluasi Silhouette, nilai puncak tertinggi berada pada \(k = 2\) dengan koefisien rata-rata Silhouette Width mencapai 0.834 (\(> 0{,}70\))[cite: 2]. Sesuai kriteria Rousseeuw (1987), struktur pengelompokan dengan 2 klaster ini tergolong ke dalam kategori struktur kuat (strong structure)[cite: 2].

6.2 Pembentukan Klaster K-Medoids (PAM)

set.seed(42)
k_opt <- 2
pam_fit <- pam(scaled_data, k = k_opt, metric = "euclidean")

# Menyimpan label klaster ke data
data_analysis$Cluster <- as.factor(pam_fit$clustering)

Titik medoid representatif yang menjadi pusat aktual dari masing-masing klaster adalah:

medoids_df <- data.frame(
  Klaster = 1:k_opt,
  Provinsi_Medoid = rownames(pam_fit$medoids)
)
kable(medoids_df, caption = "Tabel 6: Titik Medoid (Pusat Aktual) Tiap Klaster")
Tabel 6: Titik Medoid (Pusat Aktual) Tiap Klaster
Klaster Provinsi_Medoid
1 Sulawesi Tengah
2 Jawa Timur

6.3 Jarak Antar-Centroid/Medoid

Matriks jarak Euclidean antarmedoid mengindikasikan derajat pemisahan antarkelompok:

medoids_matrix <- pam_fit$medoids
jarak_medoid <- as.matrix(dist(medoids_matrix, method = "euclidean"))
colnames(jarak_medoid) <- paste("Klaster", 1:k_opt)
rownames(jarak_medoid) <- paste("Klaster", 1:k_opt)

kable(jarak_medoid, digits = 4, caption = "Tabel 7: Matriks Jarak Euclidean Antar-Medoid")
Tabel 7: Matriks Jarak Euclidean Antar-Medoid
Klaster 1 Klaster 2
Klaster 1 0.0000 1.2956
Klaster 2 1.2956 0.0000

6.4 Rata-rata Variabel Tiap Klaster

ringkasan_klaster <- data_analysis %>%
  group_by(Cluster) %>%
  summarise(
    Jumlah_Provinsi = n(),
    Rata_Populasi = mean(Population),
    Rata_Total_Kasus = mean(Total_Cases),
    Rata_Kematian = mean(Total_Deaths)
  )

kable(ringkasan_klaster, 
      digits = 2, 
      format.args = list(big.mark = "."),
      caption = "Tabel 8: Rata-Rata Karakteristik Variabel Asli Tiap Klaster")
Tabel 8: Rata-Rata Karakteristik Variabel Asli Tiap Klaster
Cluster Jumlah_Provinsi Rata_Populasi Rata_Total_Kasus Rata_Kematian
1 28 4.628.369 90.843.18 2.153.89
2 4 33.212.641 956.049.00 24.175.75

6.5 Profilisasi Klaster

Berdasarkan nilai rata-rata pada Tabel 8, profilisasi masing-masing klaster didefinisikan sebagai berikut:

  1. Klaster 1 (Wilayah Beban Rendah - Sedang / Mayoritas Luar Pulau Jawa):
    • Pusat Medoid: Sulawesi Tengah
    • Karakteristik: Terdiri atas 28 provinsi dengan rata-rata jumlah penduduk \(4{,}63\) juta jiwa, rata-rata total kasus \(90.843\), dan rata-rata kematian \(2.154\) jiwa. Klaster ini merepresentasikan kelompok wilayah dengan transmisi dan beban kasus kesehatan yang tergolong lebih moderat.
  2. Klaster 2 (Wilayah Beban Tinggi & Episentrum Aglomerasi / Pulau Jawa):
    • Pusat Medoid: Jawa Timur
    • Karakteristik: Terdiri atas 4 provinsi padat di Pulau Jawa (DKI Jakarta, Jawa Barat, Jawa Tengah, dan Jawa Timur) dengan rata-rata populasi masif (\(33{,}21\) juta jiwa), rata-rata total kasus mencapai \(956.049\), serta rata-rata akumulasi kematian tertinggi nasional sebesar \(24.176\) jiwa.

6.6 Visualisasi Peta Spasial dan Keanggotaan Klaster

Visualisasi spasial berikut memetakan sebaran geografis klaster provinsi di Indonesia menggunakan peta dasar (basemap) kepulauan Indonesia. Wilayah Klaster 1 ditandai dengan warna Hijau (daerah beban kasus rendah hingga sedang) dan Klaster 2 ditandai dengan warna Merah (daerah beban kasus tinggi di Pulau Jawa).

# Memastikan library pemetaan aktif
library(ggplot2)
library(maps)
library(ggrepel)

# 1. Mengambil koordinat Longitude & Latitude dari dataset provinsi awal
geo_prov <- covid_prov %>%
  select(Province, Longitude, Latitude) %>%
  distinct(Province, .keep_all = TRUE)

# 2. Menggabungkan data koordinat dengan hasil klasterisasi
map_df <- data_analysis %>%
  tibble::rownames_to_column(var = "Province") %>%
  left_join(geo_prov, by = "Province")

# 3. Mengambil peta dasar (basemap) wilayah Indonesia
indonesia_map <- map_data("world", region = "Indonesia")

# 4. Membuat visualisasi peta klaster
ggplot() +
  # Layer 1: Peta poligon kepulauan Indonesia
  geom_polygon(data = indonesia_map, aes(x = long, y = lat, group = group),
               fill = "#f0f0f0", color = "#bdbdbd", linewidth = 0.3) +
  # Layer 2: Titik koordinat provinsi dengan warna klaster
  geom_point(data = map_df, aes(x = Longitude, y = Latitude, color = Cluster),
             size = 4, alpha = 0.85) +
  # Layer 3: Label nama provinsi
  geom_text_repel(data = map_df, aes(x = Longitude, y = Latitude, label = Province, color = Cluster),
                  size = 2.7, max.overlaps = 20, fontface = "bold") +
  # Pengaturan warna klaster (Klaster 1 = Hijau, Klaster 2 = Merah)
  scale_color_manual(
    values = c("1" = "#2ecc71", "2" = "#e74c3c"),
    labels = c("1" = "Klaster 1: Kasus Rendah-Sedang (28 Prov)",
               "2" = "Klaster 2: Kasus Tinggi / Pulau Jawa (4 Prov)")
  ) +
  coord_fixed(ratio = 1.1, xlim = c(94, 142), ylim = c(-11, 7)) +
  labs(
    title = "Peta Sebaran Klaster Provinsi COVID-19 di Indonesia (K-Medoids k=2)",
    subtitle = "Pemetaan Berdasarkan Variabel Populasi, Total Kasus, dan Total Kematian",
    x = "Bujur (Longitude)",
    y = "Lintang (Latitude)",
    color = "Klasifikasi Klaster"
  ) +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", size = 12, hjust = 0.5),
    plot.subtitle = element_text(size = 9, hjust = 0.5, color = "gray30"),
    legend.position = "bottom",
    panel.grid.minor = element_blank()
  )
Gambar 3: Peta Sebaran Spasial Klaster Provinsi COVID-19 di Indonesia


Daftar rincian provinsi anggota untuk masing-masing klaster disajikan sebagai berikut:

for(i in 1:k_opt) {
  cat(paste0("### **Anggota Klaster ", i, " (Pusat Medoid: ", medoids_df$Provinsi_Medoid[i], ") - Total ", ringkasan_klaster$Jumlah_Provinsi[i], " Provinsi**\n\n"))
  cat(paste(rownames(data_analysis[data_analysis$Cluster == i, ]), collapse = ", "), "\n\n")
}

Anggota Klaster 1 (Pusat Medoid: Sulawesi Tengah) - Total 28 Provinsi

Aceh, Bali, Banten, Bengkulu, Daerah Istimewa Yogyakarta, Jambi, Kalimantan Barat, Kalimantan Selatan, Kalimantan Tengah, Kalimantan Timur, Kalimantan Utara, Kepulauan Bangka Belitung, Kepulauan Riau, Lampung, Maluku, Maluku Utara, Nusa Tenggara Barat, Nusa Tenggara Timur, Papua, Papua Barat, Riau, Sulawesi Selatan, Sulawesi Tengah, Sulawesi Tenggara, Sulawesi Utara, Sumatera Barat, Sumatera Selatan, Sumatera Utara

Anggota Klaster 2 (Pusat Medoid: Jawa Timur) - Total 4 Provinsi

DKI Jakarta, Jawa Barat, Jawa Tengah, Jawa Timur

7. Kesimpulan

Berdasarkan keseluruhan tahapan analisis klaster menggunakan algoritma Partitioning Around Medoids (PAM) terhadap data COVID-19 di 32 provinsi Indonesia, diperoleh kesimpulan sebagai berikut:

  1. Hasil Evaluasi dan Kualitas Pengelompokan:
    Metode Silhouette menunjukkan bahwa pengelompokan terbaik terbentuk pada dua kelompok (\(k = 2\)) dengan skor Silhouette sebesar 0.834[cite: 1]. Nilai ini berada di atas \(0{,}70\), yang menunjukkan bahwa pembagian dua kelompok ini sangat jelas, rapi, dan terpisah dengan kuat antarwilayah[cite: 1].

  2. Pembagian Kelompok Wilayah:

    • Klaster 1 (Pusat: Sulawesi Tengah): Mencakup 28 provinsi di luar Pulau Jawa dengan rata-rata penduduk \(4{,}63\) juta jiwa, total kasus \(90.843\), dan kematian \(2.154\) jiwa. Kelompok ini memiliki wilayah yang luas dan tersebar, namun jumlah kasus hariannya tidak sepadat di Jawa.
    • Klaster 2 (Pusat: Jawa Timur): Mencakup 4 provinsi padat di Pulau Jawa (DKI Jakarta, Jawa Barat, Jawa Tengah, dan Jawa Timur) dengan rata-rata penduduk \(33{,}21\) juta jiwa, total kasus mencapai \(956.049\), dan kematian \(24.176\) jiwa. Kelompok ini menjadi pusat penyebaran kasus terbanyak di Indonesia.
  3. Rekomendasi Penanganan:
    Perbedaan kondisi kedua kelompok memerlukan langkah penanganan yang terarah sesuai kebutuhan lapangan:

    • Untuk Klaster 2 (Pulau Jawa): Fokus utama diletakkan pada penambahan tempat tidur ruang rawat intensif (ICU), kesiapan stok tabung oksigen dan obat-obatan dalam jumlah besar, serta keselarasan aturan pembatasan mobilitas antar-kota yang saling bertetangga.
    • Untuk Klaster 1 (Luar Pulau Jawa): Fokus utama diletakkan pada kelancaran jalur pengiriman alat kesehatan antarpulau, penguatan fasilitas dan alat tes di puskesmas serta rumah sakit daerah, dan pengawasan kesehatan di pintu masuk pelabuhan maupun bandara.