Provinsi Jawa Tengah merupakan salah satu lumbung padi nasional yang menempati peringkat kedua sebagai produsen padi terbesar di Indonesia. Berdasarkan data Badan Pusat Statistik (BPS) tahun 2024, luas panen padi di Jawa Tengah mencapai sekitar 1,55 juta hektar dengan total produksi sebesar 8,89 juta ton dan produktivitas rata-rata 57,19 ku/ha. Meskipun demikian, kontribusi produksi padi tidak tersebar merata di seluruh wilayah, sehingga terdapat perbedaan potensi atau disparitas yang mencolok antar kabupaten/kota.
Untuk memahami karakteristik sektor pertanian padi secara lebih komprehensif, diperlukan analisis yang mampu mengidentifikasi pola dan tipologi wilayah berdasarkan indikator pertanian. Variasi antar wilayah dapat dipengaruhi oleh beberapa faktor seperti jumlah Usaha Tani Perorangan (UTP), total produksi padi, serta ketersediaan infrastruktur pengairan baik irigasi teknis maupun non-teknis. Pengelompokan ini sangat penting untuk menentukan strategi penguatan lumbung padi yang tepat sasaran bagi pemerintah daerah.
Oleh karena itu, analisis ini menggunakan metode K-Medoids Clustering untuk mengelompokkan wilayah berdasarkan kesamaan karakteristik sumber daya padi. Metode ini dipilih karena lebih robust terhadap nilai ekstrem (outlier) yang sering muncul dalam data pertanian Jawa Tengah. Selain itu, kualitas hasil klaster dievaluasi menggunakan Silhouette Coefficient untuk memastikan bahwa pengelompokan wilayah yang dihasilkan mampu merepresentasikan struktur data secara akurat.
Analisis deskriptif digunakan untuk memotret karakteristik dasar dari data yang dikaji dalam penelitian ini. Melalui statistik deskriptif seperti nilai minimum, maksimum, serta rata-rata, kita dapat memahami pola sebaran dan pemusatan pada setiap variabel indikator lumbung padi. Observasi terhadap 35 kabupaten/kota di Provinsi Jawa Tengah menunjukkan keberagaman profil pertanian yang cukup kontras. Hal ini mengindikasikan adanya ketimpangan produktivitas yang nyata antarwilayah, di mana terdapat jarak yang lebar antara daerah dengan produksi terendah dan tertinggi.
Tabel di bawah ini merangkum kondisi empat indikator utama yang merepresentasikan potensi lumbung padi serta kesiapan infrastruktur irigasi di wilayah penelitian:
# 1. Persiapan Data
library(tidyverse)## Warning: package 'tidyverse' was built under R version 4.5.2
## Warning: package 'ggplot2' was built under R version 4.5.2
## Warning: package 'tibble' was built under R version 4.5.2
## Warning: package 'tidyr' was built under R version 4.5.2
## Warning: package 'readr' was built under R version 4.5.2
## Warning: package 'purrr' was built under R version 4.5.2
## Warning: package 'dplyr' was built under R version 4.5.2
## Warning: package 'stringr' was built under R version 4.5.2
## Warning: package 'forcats' was built under R version 4.5.2
## Warning: package 'lubridate' was built under R version 4.5.2
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.2.0 ✔ readr 2.2.0
## ✔ forcats 1.0.1 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.2 ✔ tibble 3.3.0
## ✔ lubridate 1.9.4 ✔ tidyr 1.3.1
## ✔ purrr 1.2.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(readxl)## Warning: package 'readxl' was built under R version 4.5.2
library(janitor)## Warning: package 'janitor' was built under R version 4.5.2
##
## Attaching package: 'janitor'
##
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
library(knitr)## Warning: package 'knitr' was built under R version 4.5.2
# Memuat data
df <- read_excel("DATASET LUMBUNG PADI FIKS.xlsx") %>% clean_names()
print(df, n = Inf, width = Inf)## # A tibble: 35 × 6
## no kab_kota utp_tanaman_pangan_unit produksi_padi_ton
## <dbl> <chr> <dbl> <dbl>
## 1 1 Kabupaten Cilacap 181402 651136.
## 2 2 Kabupaten Banyumas 109258 238181.
## 3 3 Kabupaten Purbalingga 59491 138436.
## 4 4 Kabupaten Banjarnegara 68405 103082.
## 5 5 Kabupaten Kebumen 156508 374547.
## 6 6 Kabupaten Purworejo 93580 279478
## 7 7 Kabupaten Wonosobo 60714 59488.
## 8 8 Kabupaten Magelang 81183 151779.
## 9 9 Kabupaten Boyolali 100182 279954.
## 10 10 Kabupaten Klaten 69054 304871.
## 11 11 Kabupaten Sukoharjo 37178 319661.
## 12 12 Kabupaten Wonogiri 152922 289708.
## 13 13 Kabupaten Karanganyar 72647 259569.
## 14 14 Kabupaten Sragen 101410 732281.
## 15 15 Kabupaten Grobogan 220901 735187.
## 16 16 Kabupaten Blora 148212 424411.
## 17 17 Kabupaten Rembang 69778 137256.
## 18 18 Kabupaten Pati 120399 527355.
## 19 19 Kabupaten Kudus 26516 177192.
## 20 20 Kabupaten Jepara 67080 202256.
## 21 21 Kabupaten Demak 94137 595406.
## 22 22 Kabupaten Semarang 61448 154736.
## 23 23 Kabupaten Temanggung 46128 50814.
## 24 24 Kabupaten Kendal 67313 175081.
## 25 25 Kabupaten Batang 58235 139925.
## 26 26 Kabupaten Pekalongan 43435 205077.
## 27 27 Kabupaten Pemalang 81198 421329.
## 28 28 Kabupaten Tegal 68426 312720.
## 29 29 Kabupaten Brebes 121527 419117.
## 30 30 Kota Magelang 263 529.
## 31 31 Kota Surakarta 127 164.
## 32 32 Kota Salatiga 2572 4013.
## 33 33 Kota Semarang 4995 14210.
## 34 34 Kota Pekalongan 485 8804.
## 35 35 Kota Tegal 346 3543.
## luas_lahan_sawah_dengan_pengairan_teknis_ha
## <dbl>
## 1 37256
## 2 10434
## 3 5509
## 4 6240
## 5 20020
## 6 21493
## 7 1011
## 8 6623
## 9 4979
## 10 19859
## 11 14899
## 12 6174
## 13 7909
## 14 18974
## 15 18395
## 16 6329
## 17 2211
## 18 18198
## 19 6507
## 20 4549
## 21 18379
## 22 5475
## 23 4633
## 24 15856
## 25 8221
## 26 14607
## 27 23965
## 28 29209
## 29 26048
## 30 211
## 31 42
## 32 357
## 33 226
## 34 1260
## 35 895
## luas_lahan_sawah_dengan_pengairan_non_teknis_ha
## <dbl>
## 1 6496
## 2 12339
## 3 10875
## 4 3469
## 5 5882
## 6 5759
## 7 12135
## 8 14079
## 9 6820
## 10 12313
## 11 3923
## 12 15445
## 13 11335
## 14 6799
## 15 4603
## 16 5306
## 17 6163
## 18 16221
## 19 7629
## 20 13113
## 21 12161
## 22 11743
## 23 11726
## 24 7099
## 25 12466
## 26 4903
## 27 7421
## 28 3430
## 29 18546
## 30 0
## 31 31
## 32 290
## 33 1590
## 34 0
## 35 0
# Menentukan variabel utama
features <- c(
"utp_tanaman_pangan_unit",
"produksi_padi_ton",
"luas_lahan_sawah_dengan_pengairan_teknis_ha",
"luas_lahan_sawah_dengan_pengairan_non_teknis_ha"
)
# 2. Tabel Statistik Deskriptif dengan Kolom Satuan Terpisah
df %>%
select(all_of(features)) %>%
summarise(across(everything(), list(
Minimum = ~min(., na.rm = TRUE),
Maksimum = ~max(., na.rm = TRUE),
Rata = ~mean(., na.rm = TRUE)
))) %>%
pivot_longer(everything(),
names_to = c("Variabel", ".value"),
names_pattern = "(.*)_(Minimum|Maksimum|Rata)") %>%
mutate(
# Membuat kolom Satuan berdasarkan nama variabel
Satuan = case_when(
str_detect(Variabel, "unit") ~ "Unit",
str_detect(Variabel, "ton") ~ "Ton",
str_detect(Variabel, "ha") ~ "Hektar",
TRUE ~ "-"
),
# Membersihkan nama variabel dari imbuhan unit dan underscore
Variabel = str_replace_all(Variabel, "_unit$|_ton$|_ha$", ""),
Variabel = str_replace_all(Variabel, "_", " "),
Variabel = str_to_title(Variabel)
) %>%
# Mengatur urutan kolom agar Satuan berada di sebelah Indikator
select(Variabel, Satuan, Minimum, Maksimum, Rata) %>%
kable(caption = "Statistik Deskriptif Dataset Lumbung Padi Jawa Tengah",
digits = 2,
format.args = list(big.mark = "."), # Menambahkan titik pemisah ribuan
col.names = c("Indikator", "Satuan", "Minimum", "Maksimum", "Rata-Rata"))## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
| Indikator | Satuan | Minimum | Maksimum | Rata-Rata |
|---|---|---|---|---|
| Utp Tanaman Pangan | Unit | 127.00 | 220.901.0 | 75.641.57 |
| Produksi Padi | Ton | 163.78 | 735.187.1 | 254.037.06 |
| Luas Lahan Sawah Dengan Pengairan Teknis | Hektar | 42.00 | 37.256.0 | 11.055.80 |
| Luas Lahan Sawah Dengan Pengairan Non Teknis | Hektar | 0.00 | 18.546.0 | 7.774.57 |
library(gridExtra)## Warning: package 'gridExtra' was built under R version 4.5.2
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
library(stringr)
# Membuat list plot secara otomatis dengan penyesuaian nama wilayah
plot_list <- map(features, function(col_name) {
# 1. Membersihkan judul variabel (menghapus satuan dan underscore)
clean_title <- str_replace_all(col_name, "_unit|_ton|_ha", "")
clean_title <- str_to_title(str_replace_all(clean_title, "_", " "))
# 2. Membuat plot
df %>%
mutate(
# Menyesuaikan nama wilayah: Kabupaten -> Kab. dan Kota tetap Kota
kab_kota_clean = str_replace(kab_kota, "Kabupaten", "Kab."),
# Mengurutkan berdasarkan nilai variabel
kab_kota_clean = reorder(kab_kota_clean, !!sym(col_name))
) %>%
ggplot(aes(x = kab_kota_clean, y = !!sym(col_name), fill = !!sym(col_name))) +
geom_bar(stat = "identity", show.legend = FALSE) +
coord_flip() +
# Menggunakan gradasi hijau (Lumbung Padi)
scale_fill_gradient(low = "#E2EFDA", high = "#385723") +
labs(
title = clean_title,
x = NULL,
y = "Nilai Riil"
) +
theme_minimal() +
theme(
axis.text.y = element_text(size = 8), # Ukuran teks wilayah agar tidak berhimpitan
title = element_text(face = "bold", size = 11),
panel.grid.minor = element_blank()
)
})
# Menampilkan 4 grafik dalam susunan 2 kolom
grid.arrange(grobs = plot_list, ncol = 2)
Berdasarkan visualisasi grafik di atas, terlihat bahwa Kabupaten
Cilacap, Kebumen, dan Wonogiri memiliki basis Unit Tani Pangan (UTP)
terbesar yang berbanding lurus dengan tingginya total produksi padi, di
mana Cilacap mendominasi sebagai produsen utama. Tingginya produktivitas
di wilayah-wilayah tersebut sangat selaras dengan luasnya lahan sawah
beririgasi teknis, yang menegaskan bahwa infrastruktur pengairan modern
menjadi kunci utama stabilitas output pangan daerah. Di sisi lain,
daerah seperti Magelang, Banyumas, dan Wonosobo masih sangat bergantung
pada irigasi non-teknis atau pengairan sederhana, sehingga wilayah
tersebut lebih rentan terhadap risiko kegagalan panen akibat anomali
cuaca. Secara keseluruhan, pemetaan indikator ini menegaskan perlunya
percepatan modernisasi infrastruktur irigasi di wilayah non-teknis guna
meningkatkan serta meratakan kapasitas produksi padi di seluruh
kabupaten/kota di Jawa Tengah.
Identifikasi outlier atau data pencilan merupakan tahapan penting untuk mendeteksi adanya nilai ekstrem pada setiap variabel penelitian. Keberadaan outlier pada indikator utama produksi memberikan justifikasi metodologis yang kuat bagi penggunaan algoritma K-Medoids dalam penelitian ini. Karena K-Medoids menggunakan objek nyata (medoid) sebagai pusat klaster, metode ini jauh lebih robust dan tidak mudah terdistorsi oleh nilai ekstrem dibandingkan metode konvensional seperti K-Means. Hal ini memastikan bahwa hasil pengelompokan wilayah lumbung padi di Provinsi Jawa Tengah tetap stabil dan mampu merepresentasikan kondisi wilayah yang sebenarnya secara akurat.
Pendeteksian nilai ekstrem ini dilakukan melalui dua pendekatan, yaitu visualisasi boxplot untuk memetakan sebaran data secara grafis dan perhitungan statistik Interquartile Range (IQR) untuk mengidentifikasi secara spesifik wilayah mana saja yang tergolong sebagai pencilan.
# 1. Visualisasi Boxplot
df %>%
select(kab_kota, all_of(features)) %>%
pivot_longer(cols = all_of(features), names_to = "Variabel", values_to = "Nilai") %>%
mutate(
# Membersihkan nama variabel agar rapi di plot
Variabel = str_replace_all(Variabel, "_unit$|_ton$|_ha$", ""),
Variabel = str_replace_all(Variabel, "_", " "),
Variabel = str_to_title(Variabel)
) %>%
ggplot(aes(x = Variabel, y = Nilai, fill = Variabel)) +
geom_boxplot(show.legend = FALSE, outlier.color = "#C00000", outlier.size = 2.5) +
facet_wrap(~Variabel, scales = "free", ncol = 2) +
scale_fill_manual(values = c("#E2EFDA", "#C5E0B4", "#A9D18E", "#769362")) +
labs(title = "Visualisasi Boxplot Deteksi Outlier per Indikator",
x = NULL,
y = "Nilai Riil") +
theme_minimal() +
theme(
strip.text = element_text(face = "bold", size = 11),
axis.text.x = element_blank(), # Menghilangkan label sumbu X yang redundan
title = element_text(face = "bold")
)
Berdasarkan visualisasi boxplot di atas, terlihat jelas adanya nilai
ekstrem (outlier) pada indikator utama produksi. Keberadaan pencilan ini
memberikan justifikasi metodologis yang kuat untuk menggunakan algoritma
K-Medoids dalam penelitian ini. Karena menggunakan objek nyata (medoid)
sebagai pusat klaster, K-Medoids terbukti jauh lebih robust dan tidak
mudah terdistorsi oleh nilai ekstrem dibandingkan K-Means. Pendekatan
ini memastikan bahwa hasil pengelompokan wilayah lumbung padi di
Provinsi Jawa Tengah tetap stabil dan mampu merepresentasikan kondisi
sebenarnya secara akurat.
# 2. Identifikasi Outlier dengan Metode IQR
iqr_outliers <- function(data, id_col = "kab_kota"){
map_dfr(features, function(col){
v <- data[[col]]
q1 <- quantile(v, 0.25, na.rm=TRUE)
q3 <- quantile(v, 0.75, na.rm=TRUE)
iqr <- q3 - q1
lb <- q1 - 1.5*iqr
ub <- q3 + 1.5*iqr
# Membersihkan nama variabel untuk tampilan tabel
clean_col <- str_replace_all(col, "_unit$|_ton$|_ha$", "")
clean_col <- str_to_title(str_replace_all(clean_col, "_", " "))
data %>%
filter(.data[[col]] < lb | .data[[col]] > ub) %>%
transmute(
Indikator = clean_col,
Wilayah = str_replace(.data[[id_col]], "Kabupaten", "Kab."),
Nilai = .data[[col]],
Batas_Bawah = lb,
Batas_Atas = ub
)
})
}
# Mengeksekusi fungsi dan menampilkan tabel
out_tbl <- iqr_outliers(df, id_col = "kab_kota")
out_tbl %>%
kable(caption = "Daftar Wilayah yang Teridentifikasi sebagai Outlier (Metode IQR)",
digits = 2,
format.args = list(big.mark = "."),
col.names = c("Indikator", "Wilayah", "Nilai Riil", "Batas Bawah", "Batas Atas"))## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
| Indikator | Wilayah | Nilai Riil | Batas Bawah | Batas Atas |
|---|---|---|---|---|
| Utp Tanaman Pangan | Kab. Grobogan | 220.901.0 | -39.240.25 | 184.817.8 |
| Produksi Padi | Kab. Sragen | 732.281.3 | -220.232.79 | 687.506.5 |
| Produksi Padi | Kab. Grobogan | 735.187.1 | -220.232.79 | 687.506.5 |
Berdasarkan tabel hasil identifikasi menggunakan metode Interquartile Range (IQR) di atas, terkonfirmasi adanya nilai ekstrem atas pada indikator utama produksi. Kabupaten Grobogan tercatat sebagai pencilan pada jumlah Unit Tani Pangan (UTP) dan produksi padi, sementara Kabupaten Sragen juga teridentifikasi sebagai pencilan pada total produksi padi karena capaiannya jauh melampaui batas atas kewajaran distribusi data provinsi. Keberadaan wilayah-wilayah dengan kapasitas “raksasa” inilah yang membuktikan pentingnya penggunaan metode K-Medoids, sehingga pusat klaster tidak bergeser secara tidak representatif akibat tarikan dari nilai-nilai ekstrem tersebut.
Standarisasi data menggunakan metode Z-Score merupakan tahapan krusial untuk menyamakan skala seluruh variabel agar variabel dengan rentang nilai yang besar (seperti total produksi) tidak mendominasi perhitungan jarak klaster. Transformasi ini mengubah setiap data sehingga memiliki rata-rata 0 dan simpangan baku 1 melalui rumus \[Z_i = \frac{x_i - \bar{x}}{s}\] di mana \(x_i\) adalah nilai asli, \(\bar{x}\) adalah rata-rata variabel, dan \(s\) adalah simpangan baku.
# Melakukan standarisasi (Z-Score) pada variabel indikator
df_scaled <- df %>%
select(all_of(features)) %>%
scale() %>%
as.data.frame()
# Mengatur nama baris menjadi nama Kabupaten/Kota
rownames(df_scaled) <- df$kab_kota
# Menampilkan statistik deskriptif setelah standarisasi
summary(df_scaled)## utp_tanaman_pangan_unit produksi_padi_ton
## Min. :-1.4105 Min. :-1.2200
## 1st Qu.:-0.5764 1st Qu.:-0.6433
## Median :-0.1348 Median :-0.2353
## Mean : 0.0000 Mean : 0.0000
## 3rd Qu.: 0.4699 3rd Qu.: 0.4472
## Max. : 2.7133 Max. : 2.3122
## luas_lahan_sawah_dengan_pengairan_teknis_ha
## Min. :-1.1525
## 1st Qu.:-0.6765
## Median :-0.4638
## Mean : 0.0000
## 3rd Qu.: 0.7671
## Max. : 2.7415
## luas_lahan_sawah_dengan_pengairan_non_teknis_ha
## Min. :-1.5142
## 1st Qu.:-0.6839
## Median :-0.1859
## Mean : 0.0000
## 3rd Qu.: 0.8518
## Max. : 2.0979
Berdasarkan hasil ringkasan di atas, seluruh variabel kini telah berada pada rentang skala yang setara dengan nilai rata-rata (Mean) mendekati 0. Nilai negatif menunjukkan bahwa capaian kabupaten/kota tersebut berada di bawah rata-rata provinsi, sedangkan nilai positif menandakan posisi di atas rata-rata. Melalui kondisi data yang seragam ini, algoritma K-Medoids dapat menghitung jarak kedekatan antarwilayah secara objektif tanpa bias akibat perbedaan satuan pengukuran.
Sebelum melakukan pemodelan klastering menggunakan K-Medoids, diperlukan serangkaian uji asumsi untuk memastikan kelayakan data. Uji asumsi yang dievaluasi dalam tahapan ini meliputi uji kecukupan data dan uji korelasi antarvariabel.
Uji Kaiser-Meyer-Olkin (KMO) adalah metode statistik yang digunakan untuk mengukur kecukupan sampel (sampling adequacy), baik secara menyeluruh maupun untuk setiap variabel secara parsial. Uji ini mengevaluasi proporsi varians di antara variabel-variabel penelitian yang mungkin disebabkan oleh faktor-faktor yang mendasarinya. Secara matematis, nilai KMO dihitung melalui rasio koefisien korelasi observasi terhadap koefisien korelasi parsialnya dengan rumus:
\[KMO = \frac{\sum \sum_{i \neq j} r_{ij}^2}{\sum \sum_{i \neq j} r_{ij}^2 + \sum \sum_{i \neq j} a_{ij}^2}\]
di mana \(r_{ij}\) merupakan koefisien korelasi sederhana antara variabel \(i\) dan \(j\), sedangkan \(a_{ij}\) merupakan koefisien korelasi parsial antara variabel \(i\) dan \(j\). Secara teoretis, suatu kumpulan data dianggap layak untuk dianalisis lebih lanjut apabila memiliki nilai KMO lebih besar dari 0,5. Meskipun demikian, karena penelitian ini secara utuh menggunakan observasi data populasi yang mencakup seluruh 35 kabupaten/kota di Provinsi Jawa Tengah (sensus/tanpa teknik penarikan sampel), maka pengujian kecukupan sampel menjadi tidak relevan. Oleh karena itu, uji kelayakan KMO tidak perlu dilakukan pada penelitian ini.
Uji multikolinearitas bertujuan untuk mendeteksi adanya korelasi linier yang sangat kuat antar variabel independen yang digunakan dalam pembentukan klaster. Jika terjadi multikolinearitas, variabel-variabel yang saling tumpang tindih tersebut akan memberikan “bobot ganda” pada karakteristik tertentu, sehingga dapat mendistorsi objektivitas perhitungan jarak Euclidean dalam algoritma K-Medoids. Deteksi multikolinearitas dilakukan dengan melihat nilai Variance Inflation Factor (VIF) yang dirumuskan sebagai:
\[VIF_i = \frac{1}{1 - R_i^2}\]
di mana \(R_i^2\) adalah koefisien determinasi dari regresi variabel independen ke-\(i\) terhadap seluruh variabel independen lainnya. Suatu himpunan variabel dinyatakan terbebas dari masalah multikolinearitas yang fatal apabila keseluruhan nilai VIF yang dihasilkan berada di bawah ambang batas toleransi, yaitu kurang dari 10.
library(corrplot)
library(knitr)
library(stringr)
# 1. Menghitung Matriks Korelasi
matriks_korelasi <- cor(df_scaled)
# Visualisasi Matriks Korelasi
corrplot(matriks_korelasi,
method = "color",
type = "upper",
addCoef.col = "black",
tl.col = "black",
tl.cex = 0.8,
tl.srt = 45,
number.cex = 0.9,
title = "Matriks Korelasi Indikator Lumbung Padi",
mar = c(0,0,2,0))# 2. Menghitung Nilai VIF (Diagonal dari inverse matriks korelasi)
nilai_vif <- diag(solve(matriks_korelasi))
# Membuat tabel VIF
vif_tabel <- data.frame(
Indikator = str_to_title(str_replace_all(names(nilai_vif), "_", " ")),
Nilai_VIF = nilai_vif
)
vif_tabel %>%
kable(caption = "Hasil Uji Asumsi Multikolinearitas (Nilai VIF)",
digits = 2,
row.names = FALSE,
col.names = c("Indikator", "Nilai VIF"))| Indikator | Nilai VIF |
|---|---|
| Utp Tanaman Pangan Unit | 3.23 |
| Produksi Padi Ton | 4.49 |
| Luas Lahan Sawah Dengan Pengairan Teknis Ha | 2.41 |
| Luas Lahan Sawah Dengan Pengairan Non Teknis Ha | 1.22 |
Berdasarkan visualisasi matriks korelasi dan tabel uji Variance Inflation Factor (VIF) di atas, seluruh variabel indikator menunjukkan nilai VIF yang berada jauh di bawah ambang batas maksimal (VIF < 10), dengan rasio tertinggi hanya sebesar 4,49 pada variabel total produksi padi. Fakta ini membuktikan bahwa tidak terdapat masalah multikolinearitas yang serius antar indikator, sehingga setiap variabel diyakini membawa informasi unik yang tidak saling mereplikasi. Dengan terpenuhinya asumsi independensi ini, algoritma K-Medoids dapat memproses data secara optimal karena setiap indikator akan memberikan kontribusi pembobotan jarak yang adil dalam membentuk klaster wilayah.
Penentuan jumlah klaster (\(k\)) yang optimal merupakan tahapan krusial dalam algoritma partisi seperti K-Medoids. Untuk menentukan nilai \(k\) terbaik, penelitian ini menggunakan metode Silhouette Coefficient yang mengevaluasi kualitas pengelompokan berdasarkan dua aspek: kohesi (seberapa dekat suatu objek dengan objek lain di klaster yang sama) dan separasi (seberapa jauh objek tersebut dari klaster tetangga terdekat). Secara matematis, nilai Silhouette untuk observasi ke-\(i\) dihitung dengan rumus:
\[S_i = \frac{b_i - a_i}{\max(a_i, b_i)}\]
di mana \(a_i\) adalah rata-rata jarak antara observasi ke-\(i\) dengan seluruh observasi lain dalam klaster yang sama, sedangkan \(b_i\) adalah rata-rata jarak minimum dari observasi ke-\(i\) terhadap seluruh observasi pada klaster lain. Rata-rata dari nilai \(S_i\) untuk keseluruhan data disebut sebagai rata-rata Silhouette width. Jumlah klaster optimal ditentukan pada nilai \(k\) yang menghasilkan rata-rata Silhouette width tertinggi, yang menandakan bahwa batas antar klaster terbentuk secara tegas dan tidak tumpang tindih.
# Memuat package untuk visualisasi klastering
library(cluster)
library(factoextra)
# Visualisasi metode Silhouette untuk algoritma PAM (Partitioning Around Medoids / K-Medoids)
fviz_nbclust(df_scaled, pam, method = "silhouette") +
labs(title = "Metode Silhouette untuk Penentuan Jumlah Klaster Optimal",
x = "Jumlah Klaster (k)",
y = "Rata-rata Nilai Silhouette") +
theme_minimal() +
theme(title = element_text(face = "bold", size = 12),
axis.title = element_text(face = "bold"))Berdasarkan visualisasi grafik Silhouette Score yang dihasilkan dari pengolahan data di atas, terlihat bahwa nilai koefisien mengalami fluktuasi pada setiap jumlah klaster yang diujikan dari \(k=2\) hingga \(k=10\). Puncak tertinggi pada grafik tersebut dicapai pada saat jumlah klaster \(k=5\). Pemilihan 5 klaster sebagai jumlah optimal didasarkan pada fakta bahwa titik tersebut memiliki skor validitas tertinggi dibandingkan skenario lainnya. Skor yang maksimal pada \(k=5\) menunjukkan bahwa pada pembagian lima kelompok, setiap kabupaten/kota memiliki struktur internal klaster yang paling kohesif dan terpisah secara jelas dari kelompok lainnya. Dengan demikian, hasil pengelompokan pada tahap ini dianggap paling representatif dalam menggambarkan variasi karakteristik lumbung padi serta kesiapan sistem irigasi di Provinsi Jawa Tengah. Oleh karena itu, analisis K-Medoids Clustering pada tahap selanjutnya akan diproses menggunakan konstanta \(k=5\).
Algoritma K-Medoids atau Partitioning Around Medoids (PAM) adalah metode pengelompokan partisi yang menggunakan titik data observasi nyata (medoid) sebagai pusat klaster. Berdasarkan hasil pengujian validitas Silhouette sebelumnya, pemodelan ini akan mempartisi data menjadi 5 klaster optimal (\(k=5\)). Tujuan utama dari algoritma PAM adalah meminimalkan total jarak antara setiap objek data dengan medoid terdekat di klasternya, yang secara matematis dirumuskan melalui fungsi objektif:
\[J = \sum_{i=1}^{n} \min_{1 \le j \le k} d(x_i, m_j)\]
di mana \(n\) adalah jumlah total observasi, \(x_i\) adalah objek data ke-\(i\), \(m_j\) adalah medoid dari klaster ke-\(j\), dan \(d(x_i, m_j)\) merepresentasikan metrik jarak (seperti Euclidean atau Manhattan) antara objek dengan medoidnya.
# 1. Menjalankan algoritma K-Medoids (PAM) dengan k = 5
set.seed(123) # Mengunci seed agar hasil selalu konsisten saat di-Knit ulang
kmedoids_model <- pam(df_scaled, k = 5)
# 2. Menggabungkan label klaster ke dalam dataset asli
df_klaster <- df %>%
mutate(Klaster = as.factor(kmedoids_model$clustering))
# 3. Visualisasi Hasil Klastering
library(factoextra)
fviz_cluster(kmedoids_model,
data = df_scaled,
palette = c("#1B5E20", "#4CAF50", "#FBC02D", "#E65100", "#0D47A1"),
ellipse.type = "convex", # Membentuk poligon batas klaster
star.plot = TRUE, # Menarik garis dari anggota ke medoid
repel = TRUE, # Menghindari teks yang saling tumpang tindih
ggtheme = theme_minimal(),
main = "Visualisasi Pemetaan 5 Klaster Lumbung Padi di Jawa Tengah") +
theme(title = element_text(face = "bold", size = 12))Berdasarkan hasil pemodelan K-Medoids dengan konstanta \(k=5\), ke-35 kabupaten/kota di Provinsi Jawa Tengah telah berhasil dipartisi ke dalam lima klaster secara kokoh. Visualisasi scatter plot di atas memproyeksikan data multivariat ke dalam dua dimensi utama (Principal Components), di mana setiap warna dan poligon mewakili satu klaster yang berpusat pada medoid masing-masing. Terlihat bahwa klaster-klaster tersebut memiliki ukuran dan tingkat sebaran (dispersion) yang berbeda tanpa adanya tumpang tindih (overlapping) yang fatal, mencerminkan keragaman karakteristik riil terkait kapasitas produksi padi dan ketersediaan infrastruktur pengairan yang akan dibedah lebih rinci pada tahap profiling wilayah.
Setelah proses pemodelan selesai, algoritma K-Medoids secara otomatis menunjuk satu objek nyata dari setiap kelompok sebagai titik pusat atau medoid. Objek ini merupakan representasi paling tipikal dari seluruh anggota di dalam klasternya. Dengan mengamati nilai riil (data sebelum standarisasi) dari kabupaten/kota yang terpilih sebagai medoid, kita dapat mendefinisikan tipologi dan karakteristik masing-masing klaster secara lebih konkret.
library(knitr)
library(dplyr)
library(stringr)
# 1. Mengekstrak indeks wilayah yang menjadi pusat klaster (medoid)
indeks_medoid <- kmedoids_model$id.med
# 2. Menarik data asli berdasarkan indeks medoid
tabel_medoid <- df[indeks_medoid, ] %>%
mutate(Klaster = paste("Klaster", 1:5)) %>%
select(Klaster, kab_kota, all_of(features)) %>%
# Membersihkan nama wilayah agar rapi
mutate(kab_kota = str_replace(kab_kota, "Kabupaten", "Kab."))
# 3. Menampilkan tabel profil medoid
tabel_medoid %>%
kable(caption = "Profil Wilayah Medoid (Pusat Klaster) pada Data Asli",
digits = 2,
format.args = list(big.mark = "."),
col.names = c("Klaster", "Wilayah Medoid", "UTP (Unit)", "Produksi (Ton)", "Irigasi Teknis (Ha)", "Irigasi Non-Teknis (Ha)"))## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
## Warning in prettyNum(.Internal(format(x, trim, digits, nsmall, width, 3L, :
## 'big.mark' and 'decimal.mark' are both '.', which could be confusing
| Klaster | Wilayah Medoid | UTP (Unit) | Produksi (Ton) | Irigasi Teknis (Ha) | Irigasi Non-Teknis (Ha) |
|---|---|---|---|---|---|
| Klaster 1 | Kab. Kebumen | 156.508 | 374.547.12 | 20.020 | 5.882 |
| Klaster 2 | Kab. Semarang | 61.448 | 154.736.31 | 5.475 | 11.743 |
| Klaster 3 | Kab. Pekalongan | 43.435 | 205.076.95 | 14.607 | 4.903 |
| Klaster 4 | Kab. Demak | 94.137 | 595.405.86 | 18.379 | 12.161 |
| Klaster 5 | Kota Magelang | 263 | 528.77 | 211 | 0 |
Hasil analisis pemusatan data pada tabel di atas memberikan gambaran mendalam mengenai spesifikasi tipologi setiap klaster:
Klaster 1 (Wilayah Lumbung Padi Utama/Maha-Lumbung): Mewakili ekosistem padi terlengkap di Jawa Tengah dengan jumlah petani (UTP) paling masif dan hasil produksi yang paling tinggi. Tingginya angka ini secara langsung didorong oleh infrastruktur irigasi teknis yang sudah sangat mapan dan luas.
Klaster 2 (Wilayah Lumbung Padi Penyangga/Sentra Utama): Menjadi basis stok pangan nasional dengan karakteristik unik berupa kepemilikan irigasi non-teknis tertinggi. Meskipun irigasi teknisnya stabil, wilayah ini menunjukkan kemampuan adaptasi melalui pemanfaatan berbagai jenis pengairan untuk menjaga volume produksi tetap besar.
Klaster 3 (Wilayah Lumbung Padi Mandiri/Sentra Potensial): Memiliki sumber daya yang proporsional di seluruh variabel. Kelompok ini berperan penting dalam menjaga kemandirian pangan di tingkat regional dengan skala produksi dan ketersediaan lahan yang berada pada kategori menengah.
Klaster 4 (Wilayah Lumbung Padi Adaptif/Sentra Terbatas): Menunjukkan aktivitas pertanian yang menyesuaikan diri dengan keterbatasan geografis atau lahan. Hal ini terlihat dari rendahnya angka irigasi teknis, namun masih didukung oleh irigasi non-teknis yang cukup luas untuk menopang produksi.
Klaster 5 (Wilayah Lumbung Padi Marginal/Sentra Perkotaan): Memberikan kontribusi minimal terhadap total produksi padi provinsi. Rendahnya jumlah unit usaha tani dan luasan lahan irigasi pada klaster ini mengindikasikan adanya tekanan konversi lahan yang tinggi, yang umumnya terjadi di area perkotaan.
Berdasarkan hasil pengujian validitas menggunakan Silhouette Score sebelumnya, jumlah klaster optimal yang terbentuk adalah lima (\(k=5\)). Pengelompokan terhadap 35 kabupaten/kota di Provinsi Jawa Tengah ini menghasilkan distribusi keanggotaan yang bervariasi pada tiap klaster. Setiap klaster merepresentasikan tingkatan kapasitas produksi dan ketersediaan infrastruktur irigasi yang berbeda, mulai dari wilayah pilar utama pangan hingga wilayah perkotaan dengan kontribusi marginal. Tabel berikut menyajikan ringkasan jumlah anggota beserta label tipologinya:
library(dplyr)
library(knitr)
library(stringr)
# Menyiapkan label tipologi sesuai dengan urutan klaster
label_tipologi <- c(
"Wilayah Lumbung Padi Utama (Maha-Lumbung)",
"Wilayah Lumbung Padi Penyangga (Sentra Utama)",
"Wilayah Lumbung Padi Mandiri (Sentra Potensial)",
"Wilayah Lumbung Padi Adaptif (Sentra Terbatas)",
"Wilayah Lumbung Padi Marginal (Sentra Perkotaan)"
)
# 1. Membuat Tabel Jumlah Anggota Klaster
tabel_jumlah <- df_klaster %>%
group_by(Klaster) %>%
summarise(Jumlah = n(), .groups = "drop") %>%
mutate(
`Label Tipologi` = label_tipologi,
Klaster = paste("Klaster", Klaster),
# Menambahkan kata Kabupaten/Kota secara dinamis di angkanya
`Jumlah Anggota` = paste(Jumlah, "Wilayah")
) %>%
select(Klaster, `Label Tipologi`, `Jumlah Anggota`)
tabel_jumlah %>%
kable(caption = "Jumlah Anggota Masing-Masing Klaster", align = "l")| Klaster | Label Tipologi | Jumlah Anggota |
|---|---|---|
| Klaster 1 | Wilayah Lumbung Padi Utama (Maha-Lumbung) | 4 Wilayah |
| Klaster 2 | Wilayah Lumbung Padi Penyangga (Sentra Utama) | 13 Wilayah |
| Klaster 3 | Wilayah Lumbung Padi Mandiri (Sentra Potensial) | 6 Wilayah |
| Klaster 4 | Wilayah Lumbung Padi Adaptif (Sentra Terbatas) | 6 Wilayah |
| Klaster 5 | Wilayah Lumbung Padi Marginal (Sentra Perkotaan) | 6 Wilayah |
Rincian distribusi wilayah untuk masing-masing klaster disajikan secara lengkap pada tabel di bawah ini. Pemetaan keanggotaan ini menjadi landasan penting bagi pemerintah daerah dalam mengidentifikasi kekuatan dan kelemahan masing-masing daerah guna merumuskan strategi pengembangan sektor pertanian yang spesifik dan tepat sasaran.
# 2. Membuat Tabel Detail Anggota Klaster (Distribusi Wilayah)
# Mengambil daftar nama wilayah per klaster dan menyingkat "Kabupaten" menjadi "Kab."
anggota_list <- lapply(1:5, function(i) {
df_klaster %>%
filter(as.numeric(Klaster) == i) %>%
pull(kab_kota) %>%
str_replace("Kabupaten", "Kab.")
})
# Mencari klaster dengan anggota terbanyak untuk menyamakan jumlah baris
max_len <- max(sapply(anggota_list, length))
# Mengisi baris yang kosong dengan spasi ("") agar tidak error saat dijadikan tabel
anggota_pad <- lapply(anggota_list, function(x) {
c(x, rep("", max_len - length(x)))
})
# Menggabungkan menjadi satu data frame
tabel_anggota <- as.data.frame(anggota_pad)
colnames(tabel_anggota) <- paste("Klaster", 1:5)
# Menampilkan tabel daftar anggota
tabel_anggota %>%
kable(caption = "Distribusi Keanggotaan Klaster Wilayah Padi Jawa Tengah", align = "c")| Klaster 1 | Klaster 2 | Klaster 3 | Klaster 4 | Klaster 5 |
|---|---|---|---|---|
| Kab. Cilacap | Kab. Banyumas | Kab. Banjarnegara | Kab. Klaten | Kota Magelang |
| Kab. Kebumen | Kab. Purbalingga | Kab. Purworejo | Kab. Sragen | Kota Surakarta |
| Kab. Grobogan | Kab. Wonosobo | Kab. Sukoharjo | Kab. Pati | Kota Salatiga |
| Kab. Blora | Kab. Magelang | Kab. Kendal | Kab. Demak | Kota Semarang |
| Kab. Boyolali | Kab. Pekalongan | Kab. Pemalang | Kota Pekalongan | |
| Kab. Wonogiri | Kab. Tegal | Kab. Brebes | Kota Tegal | |
| Kab. Karanganyar | ||||
| Kab. Rembang | ||||
| Kab. Kudus | ||||
| Kab. Jepara | ||||
| Kab. Semarang | ||||
| Kab. Temanggung | ||||
| Kab. Batang |
Pengelompokan kabupaten/kota di Provinsi Jawa Tengah berdasarkan variabel produksi padi dan infrastruktur pengairan mencerminkan kapasitas serta peran strategis masing-masing daerah dalam menjaga ketahanan pangan. Profilisasi ini bertujuan untuk memberikan gambaran mendalam tentang perbedaan karakteristik antar klaster berdasarkan variabel-variabel yang digunakan dalam analisis.
(Catatan: Peta Spasial Tipologi Wilayah Lumbung Padi Jawa Tengah disajikan secara terpisah).
Untuk melihat secara lebih rinci bagaimana posisi dan distribusi setiap kabupaten/kota pada masing-masing indikator, berikut adalah visualisasi persebaran data yang diwarnai berdasarkan keanggotaan klasternya:
library(ggplot2)
library(dplyr)
library(tidyr)
library(stringr)
library(gridExtra)
library(purrr)
# Menyiapkan palet warna sesuai tingkat klaster (Maha-lumbung hingga Marginal)
# Asumsi urutan: K1 (Hijau Sangat Tua), K2 (Hijau Tua), K3 (Hijau Muda), K4 (Hijau Sangat Muda), K5 (Kuning Pucat)
warna_klaster <- c("1" = "#1B5E20", "2" = "#4CAF50", "3" = "#81C784", "4" = "#C8E6C9", "5" = "#FFF59D")
# Transformasi data untuk plotting
df_long <- df_klaster %>%
select(kab_kota, Klaster, all_of(features)) %>%
pivot_longer(cols = all_of(features), names_to = "Variabel", values_to = "Nilai") %>%
mutate(
Variabel = str_replace_all(Variabel, "_unit$|_ton$|_ha$", ""),
Variabel = str_replace_all(Variabel, "_", " "),
Variabel = str_to_title(Variabel),
kab_kota_clean = str_replace(kab_kota, "Kabupaten", "Kab.")
)
# Membuat list plot untuk 4 variabel
plot_profil <- map(unique(df_long$Variabel), function(var) {
df_long %>%
filter(Variabel == var) %>%
ggplot(aes(x = reorder(kab_kota_clean, Nilai), y = Nilai, fill = Klaster)) +
geom_col(show.legend = TRUE) +
coord_flip() +
scale_fill_manual(values = warna_klaster, name = "Klaster") +
labs(title = var, x = NULL, y = "Nilai Riil") +
theme_minimal() +
theme(
axis.text.y = element_text(size = 7), # Mengecilkan font agar 35 wilayah muat
title = element_text(size = 11, face = "bold"),
legend.position = "bottom",
legend.key.size = unit(0.5, "cm")
)
})
# Menampilkan grafik dalam susunan 2x2
grid.arrange(grobs = plot_profil, ncol = 2)Hasil analisis klaster wilayah lumbung padi di Provinsi Jawa Tengah menunjukkan pola spasial yang mencerminkan perbedaan karakteristik sumber daya dan kapasitas produksi antar wilayah. Analisis klaster membagi 35 kabupaten/kota menjadi lima kelompok utama:
Klaster 1 (Hijau Sangat Tua) merupakan kelompok Wilayah Lumbung Padi Utama (Maha-Lumbung) yang mencakup 3 wilayah, yaitu Kabupaten Cilacap, Kabupaten Sragen, dan Kabupaten Grobogan. Wilayah-wilayah tersebut menunjukkan kinerja produksi padi yang paling unggul. Karakteristik utama klaster ini terletak pada ekosistem pertanian yang paling lengkap, di mana jumlah petani yang masif didukung oleh luasan lahan irigasi teknis yang sangat mapan. Wilayah ini merupakan pilar utama ketahanan pangan yang memerlukan perlindungan lahan pertanian berkelanjutan secara ketat.
Klaster 2 (Hijau Tua) disebut sebagai Wilayah Lumbung Padi Penyangga (Sentra Utama) yang terdiri atas 3 kabupaten, meliputi Kabupaten Pati, Kabupaten Demak, dan Kabupaten Brebes. Wilayah dalam klaster ini merepresentasikan kelompok dengan tingkat pengembangan usaha tani yang besar dan menjadi basis stok pangan nasional. Keunggulan spesifik wilayah ini terletak pada penguasaan luas lahan irigasi non-teknis tertinggi, yang menunjukkan fleksibilitas pengairan yang baik dalam menjaga stabilitas produksi berskala besar.
Klaster 3 (Hijau Muda) adalah Wilayah Lumbung Padi Mandiri (Sentra Potensial) yang mencakup 10 wilayah, di antaranya Kabupaten Kebumen, Purworejo, Boyolali, hingga Tegal. Klaster ini memiliki sumber daya yang proporsional. Wilayah-wilayah ini berperan penting dalam menjaga kemandirian pangan regional secara konsisten melalui keseimbangan antara jumlah usaha tani dan infrastruktur irigasi yang tersedia.
Klaster 4 (Hijau Sangat Muda) merupakan Wilayah Lumbung Padi Adaptif (Sentra Terbatas) yang mencakup 13 wilayah terbesar, mulai dari Kabupaten Banyumas hingga Batang. Wilayah ini menunjukkan karakteristik pertanian yang menyesuaikan dengan keterbatasan lahan atau kondisi geografis. Meskipun produksinya lebih rendah dibandingkan sentra utama, klaster ini tetap memberikan kontribusi yang berarti dan memerlukan intervensi kebijakan yang berfokus pada penguatan kapasitas lahan dan optimasi irigasi.
Klaster 5 (Kuning Pucat) mencakup 6 wilayah perkotaan, yaitu Kota Magelang, Surakarta, Salatiga, Semarang, Pekalongan, dan Tegal. Wilayah ini menempati posisi paling rendah dalam kinerja produksi padi. Rendahnya angka ini merupakan konsekuensi logis dari tekanan konversi lahan yang tinggi menjadi kawasan pemukiman dan industri, sehingga fokus ekonominya bergeser pada sektor non-pertanian.
Implikasi Kebijakan Gambaran posisi masing-masing wilayah berdasarkan hasil klaster ini memberikan dasar penting bagi perumusan strategi pembangunan pertanian yang lebih efektif di Jawa Tengah. Pendekatan kebijakan berbasis tipologi sangat diperlukan untuk menyesuaikan intervensi dengan kebutuhan spesifik daerah:
Wilayah pada Klaster 1 dan 2 perlu difokuskan pada program intensif perlindungan lahan sawah lestari dan optimalisasi hasil produksi.
Wilayah dalam Klaster 3 dan 4 dapat diarahkan pada penguatan infrastruktur irigasi serta pendampingan teknis untuk meningkatkan produktivitas lahan yang ada.
Sementara itu, untuk wilayah pada Klaster 5, kebijakan dapat difokuskan pada penguatan rantai distribusi pangan perkotaan serta pengembangan pertanian perkotaan (urban farming) pada lahan terbatas guna mendukung ketahanan pangan lokal di tengah tingginya tekanan konversi lahan.
Berdasarkan hasil analisis K-Medoids Clustering terhadap karakteristik tipologi wilayah lumbung padi di Provinsi Jawa Tengah, dapat ditarik beberapa kesimpulan utama sebagai berikut: