LIBRARY
library(readxl)
library(dplyr)
library(ggplot2)
library(sf)
library(GGally)
library(ggspatial)
library(viridis)
library(patchwork)
library(scales)
LOAD DATA
data_ekonomi <- read_xlsx(
"D:/2026 Lebih Baik/SEMESTER 6/Statistik Spasial/Projek/Data Ekonomi Jatim.xlsx",
sheet = 1
)
# Rename kolom
colnames(data_ekonomi) <- c("kabkot", "TPT", "Kemiskinan", "IPM", "PDRB")
# Cek struktur data
str(data_ekonomi)
## tibble [38 × 5] (S3: tbl_df/tbl/data.frame)
## $ kabkot : chr [1:38] "Kabupaten Pacitan" "Kabupaten Ponorogo" "Kabupaten Trenggalek" "Kabupaten Tulungagung" ...
## $ TPT : num [1:38] 1.4 3.85 3.86 4.03 4.49 4.71 5 3.08 3.07 3.94 ...
## $ Kemiskinan: num [1:38] 72.5 77.9 72.3 63.2 89 ...
## $ IPM : num [1:38] 72.3 74.7 73.4 75.9 74.4 ...
## $ PDRB : num [1:38] 38215 30007 35110 49485 40200 ...
## # A tibble: 6 × 5
## kabkot TPT Kemiskinan IPM PDRB
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Kabupaten Pacitan 1.4 72.5 72.3 38215
## 2 Kabupaten Ponorogo 3.85 77.9 74.6 30007
## 3 Kabupaten Trenggalek 3.86 72.4 73.4 35110
## 4 Kabupaten Tulungagung 4.03 63.2 75.9 49485
## 5 Kabupaten Blitar 4.49 89.0 74.4 40200
## 6 Kabupaten Kediri 4.71 157. 76.1 34496
# Statistik deskriptif
summary(data_ekonomi[, c("TPT", "Kemiskinan", "IPM", "PDRB")])
## TPT Kemiskinan IPM PDRB
## Min. :1.330 Min. : 6.22 Min. :67.23 Min. : 25531
## 1st Qu.:3.115 1st Qu.: 65.28 1st Qu.:72.45 1st Qu.: 36641
## Median :3.855 Median :101.40 Median :75.32 Median : 42358
## Mean :3.780 Mean :102.00 Mean :76.06 Mean : 79425
## 3rd Qu.:4.565 3rd Qu.:143.31 3rd Qu.:79.27 3rd Qu.: 77958
## Max. :5.750 Max. :235.63 Max. :85.65 Max. :581558
LOAD SHAPEFILE PETA JAWA TIMUR
# Baca file GeoJSON (pastikan sudah di-unzip dulu)
IDN <- st_read(
"D:/2026 Lebih Baik/SEMESTER 6/Statistik Spasial/Projek/gadm41_IDN_2.json/gadm41_IDN_2.json"
)
## Reading layer `gadm41_IDN_2' from data source
## `D:\2026 Lebih Baik\SEMESTER 6\Statistik Spasial\Projek\gadm41_IDN_2.json\gadm41_IDN_2.json'
## using driver `GeoJSON'
## Simple feature collection with 502 features and 13 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 95.0102 ymin: -11.0075 xmax: 141.0194 ymax: 6.0766
## Geodetic CRS: WGS 84
# Cek nama provinsi yang tersedia di kolom NAME_1
# Jalankan baris ini untuk tahu nama persis Jawa Timur di shapefile
unique(IDN$NAME_1)
## [1] "Aceh" "Bali" "BangkaBelitung"
## [4] "Banten" "Bengkulu" "Gorontalo"
## [7] "JakartaRaya" "Jambi" "JawaBarat"
## [10] "JawaTengah" "JawaTimur" "KalimantanBarat"
## [13] "KalimantanSelatan" "KalimantanTengah" "KalimantanTimur"
## [16] "KalimantanUtara" "KepulauanRiau" "Lampung"
## [19] "Maluku" "MalukuUtara" "NusaTenggaraBarat"
## [22] "NusaTenggaraTimur" "Papua" "PapuaBarat"
## [25] "Riau" "SulawesiBarat" "SulawesiSelatan"
## [28] "SulawesiTengah" "SulawesiTenggara" "SulawesiUtara"
## [31] "SumateraBarat" "SumateraSelatan" "SumateraUtara"
## [34] "Yogyakarta"
jatim <- IDN[IDN$NAME_1 == "JawaTimur", ]
# Cek jumlah wilayah (harus 38)
nrow(jatim)
## [1] 38
# Cek nama kabupaten/kota di shapefile
sort(jatim$NAME_2)
## [1] "Bangkalan" "Banyuwangi" "Batu" "Blitar"
## [5] "Bojonegoro" "Bondowoso" "Gresik" "Jember"
## [9] "Jombang" "Kediri" "KotaBlitar" "KotaKediri"
## [13] "KotaMadiun" "KotaMalang" "KotaMojokerto" "KotaPasuruan"
## [17] "KotaProbolinggo" "Lamongan" "Lumajang" "Madiun"
## [21] "Magetan" "Malang" "Mojokerto" "Nganjuk"
## [25] "Ngawi" "Pacitan" "Pamekasan" "Pasuruan"
## [29] "Ponorogo" "Probolinggo" "Sampang" "Sidoarjo"
## [33] "Situbondo" "Sumenep" "Surabaya" "Trenggalek"
## [37] "Tuban" "Tulungagung"
MENYESUAIKAN NAMA KABUPATEN/KOTA
# PERBAIKAN: gsub("Kota ", "Kota ") dipertahankan dengan spasi
# Kota tetap "Kota Kediri" bukan "KotaKediri"
data_ekonomi <- data_ekonomi %>%
mutate(NAME_2 = kabkot) %>%
# Hapus prefix "Kabupaten " saja
mutate(NAME_2 = gsub("^Kabupaten ", "", NAME_2)) %>%
# "Kota X" dipertahankan apa adanya (tidak dihapus spasinya)
mutate(NAME_2 = trimws(NAME_2))
# Cek hasil cleaning
data_ekonomi %>% select(kabkot, NAME_2)
## # A tibble: 38 × 2
## kabkot NAME_2
## <chr> <chr>
## 1 Kabupaten Pacitan Pacitan
## 2 Kabupaten Ponorogo Ponorogo
## 3 Kabupaten Trenggalek Trenggalek
## 4 Kabupaten Tulungagung Tulungagung
## 5 Kabupaten Blitar Blitar
## 6 Kabupaten Kediri Kediri
## 7 Kabupaten Malang Malang
## 8 Kabupaten Lumajang Lumajang
## 9 Kabupaten Jember Jember
## 10 Kabupaten Banyuwangi Banyuwangi
## # ℹ 28 more rows
# Bersihkan nama di shapefile juga
jatim <- jatim %>%
mutate(NAME_2_clean = trimws(NAME_2))
data_ekonomi <- data_ekonomi %>%
mutate(NAME_2 = kabkot) %>%
mutate(NAME_2 = gsub("^Kabupaten ", "", NAME_2)) %>%
mutate(NAME_2 = gsub("^Kota ", "Kota", NAME_2)) %>%
mutate(NAME_2 = trimws(NAME_2)) %>%
mutate(NAME_2 = case_when(
NAME_2 == "KotaSurabaya" ~ "Surabaya",
NAME_2 == "KotaBatu" ~ "Batu",
TRUE ~ NAME_2
))
jatim_df <- jatim %>%
left_join(data_ekonomi, by = c("NAME_2_clean" = "NAME_2"))
sum(is.na(jatim_df$IPM))
## [1] 0
setdiff(data_ekonomi$NAME_2, jatim$NAME_2_clean)
## character(0)
HITUNG TITIK TENGAH UNTUK LABEL
# HITUNG TITIK TENGAH UNTUK LABEL (FIX GRESIK & SUMENEP)
jatim_df <- st_make_valid(jatim_df)
centroids <- jatim_df %>%
st_cast("POLYGON") %>% # pecah multipolygon
group_by(NAME_2_clean) %>%
slice_max(st_area(geometry), n = 1) %>% # ambil pulau terbesar
ungroup() %>%
st_point_on_surface() %>%
mutate(
long = st_coordinates(.)[, 1],
lat = st_coordinates(.)[, 2]
)
# Cek hasil
nrow(centroids)
## [1] 38
sum(is.na(centroids$long))
## [1] 0
sum(is.na(centroids$lat))
## [1] 0
CHOROPLETH MAP - IPM
peta_IPM <- ggplot() +
geom_sf(data = jatim_df, aes(fill = IPM), color = "white", linewidth = 0.3) +
geom_text(data = centroids,
aes(x = long, y = lat, label = NAME_2_clean),
size = 1.8, color = "black") +
scale_fill_gradient(low = "#fff7ed", high = "#ea580c",
name = "IPM", na.value = "grey80") +
annotation_north_arrow(location = "tr", which_north = "true",
style = north_arrow_fancy_orienteering) +
annotation_scale(location = "bl", width_hint = 0.3) +
labs(
title = "Indeks Pembangunan Manusia (IPM)",
subtitle = "Kabupaten/Kota di Jawa Timur Tahun 2025",
caption = "Sumber: BPS Jawa Timur, 2025"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
plot.subtitle = element_text(hjust = 0.5, size = 9),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank()
)
print(peta_IPM)

CHOROPLETH MAP - KEMISKINAN
peta_Kemiskinan <- ggplot() +
geom_sf(data = jatim_df, aes(fill = Kemiskinan), color = "white", linewidth = 0.3) +
geom_text(data = centroids,
aes(x = long, y = lat, label = NAME_2_clean),
size = 1.8, color = "black") +
scale_fill_gradient(low = "#ccf5ff", high = "#00b8e6",
name = "Ribu Jiwa", na.value = "grey80") +
annotation_north_arrow(location = "tr", which_north = "true",
style = north_arrow_fancy_orienteering) +
annotation_scale(location = "bl", width_hint = 0.3) +
labs(
title = "Jumlah Penduduk Miskin",
subtitle = "Kabupaten/Kota di Jawa Timur Tahun 2024",
caption = "Sumber: BPS Jawa Timur, 2024"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
plot.subtitle = element_text(hjust = 0.5, size = 9),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank()
)
print(peta_Kemiskinan)

CHOROPLETH MAP - TPT
peta_TPT <- ggplot() +
geom_sf(data = jatim_df, aes(fill = TPT), color = "white", linewidth = 0.3) +
geom_text(data = centroids,
aes(x = long, y = lat, label = NAME_2_clean),
size = 1.8, color = "black") +
scale_fill_gradient(low = "#ffe6f0", high = "#e60073",
name = "%", na.value = "grey80") +
annotation_north_arrow(location = "tr", which_north = "true",
style = north_arrow_fancy_orienteering) +
annotation_scale(location = "bl", width_hint = 0.3) +
labs(
title = "Tingkat Pengangguran Terbuka (TPT)",
subtitle = "Kabupaten/Kota di Jawa Timur Tahun 2024",
caption = "Sumber: BPS Jawa Timur, 2024"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
plot.subtitle = element_text(hjust = 0.5, size = 9),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank()
)
print(peta_TPT)

CHOROPLETH MAP - PDRB
peta_PDRB <- ggplot() +
geom_sf(data = jatim_df, aes(fill = PDRB), color = "white", linewidth = 0.3) +
geom_text(data = centroids,
aes(x = long, y = lat, label = NAME_2_clean),
size = 1.8, color = "black") +
scale_fill_gradient(low = "#ecfdf5", high = "#059669",
name = "Juta Rp",
na.value = "grey80",
labels = scales::comma) +
annotation_north_arrow(location = "tr", which_north = "true",
style = north_arrow_fancy_orienteering) +
annotation_scale(location = "bl", width_hint = 0.3) +
labs(
title = "PDRB Per Kapita",
subtitle = "Kabupaten/Kota di Jawa Timur Tahun 2024",
caption = "Sumber: BPS Jawa Timur, 2024"
) +
theme_minimal() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 11),
plot.subtitle = element_text(hjust = 0.5, size = 9),
axis.text = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank()
)
print(peta_PDRB)

PANEL 4 PETA SEKALIGUS
panel_peta <- (peta_IPM | peta_Kemiskinan) / (peta_TPT | peta_PDRB) +
plot_annotation(
title = "Visualisasi Spasial Indikator Ekonomi\nKabupaten/Kota Jawa Timur 2024",
caption = "Sumber: BPS Provinsi Jawa Timur, 2024",
theme = theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 13)
)
)
print(panel_peta)

PARALLEL COORDINATE PLOT (PCP)
# Data untuk PCP
data_pcp <- data_ekonomi %>%
select(kabkot, TPT, Kemiskinan, IPM, PDRB) %>%
mutate(Tipe = ifelse(grepl("^Kota", kabkot), "Kota", "Kabupaten"))
# PCP dengan skala uniminmax
pcp_plot <- ggparcoord(
data_pcp,
columns = 2:5, # TPT, Kemiskinan, IPM, PDRB
groupColumn = 6, # Tipe (Kota/Kabupaten)
scale = "uniminmax",
showPoints = TRUE,
alphaLines = 0.5,
title = "Parallel Coordinate Plot Indikator Ekonomi\nKabupaten/Kota di Jawa Timur Tahun 2025"
) +
scale_color_manual(
values = c("Kabupaten" = "#2196F3", "Kota" = "#FF5722"),
name = "Tipe Wilayah"
) +
xlab("Indikator") +
ylab("Nilai Terstandarisasi (uniminmax)") +
theme_bw() +
theme(
plot.title = element_text(hjust = 0.5, face = "bold", size = 12),
legend.position = "bottom",
axis.text.x = element_text(face = "bold", size = 10)
)
print(pcp_plot)
