Moran’s \(I\)
Geary’s \(C\)
Local Moran’s \(I_i\)
Getis-Ord \(G_i\) dan \(G_i^*\)
Moran’s \(I\) (adalah ukuran statistik spasial yang digunakan untuk melihat apakah ada autokorelasi antar wilayah. Selain itu digunakan pula ukuran ini untuk menunjukkan apakah wilayah-wilayah tersebut memiliki pola clustering atau tidak) :
\[ I = \frac{N}{S_0}.\frac{\sum_{i=1}^N\sum_{j=1}^Nw_{ij}(x_i - \bar{x})(x_j-\bar{x})}{\sum_{i=1}^N(x_i-\bar{x})^2} \]
dengan
N : jumlah area
\(x_i\) : variabel minat
\(\bar{x}\) : rata-rata
\(W = w_{ij}\) : matriks bobot spasial dengan \(w_{ii}=0\)
\(S_0 = \sum_i\sum_jw_{ij}\) : jumlah total bobot
Jika nilai :
\(I\) > 0 : terdapat autokorelasi spasial positif sehingga nilai antar wilayah mirip
\(I < 0\) : terdapat autokorelasi spasial negatif atau terdapat pola checkerboard (yang berdekatan tidak mirip)
\(I \approx 0\) : pola acak
Geary’s \(C\) (merupakan ukuran statistik spasial yang juga melihat hubungan atau autokorelasi tetapi dengan pendekatan yang berbeda dari Moran’s \(I\). Pendekatan yang digunakan andalah perbedaan kuadrat antar tetangganya) :
\[ C = \frac{(n-1)}{2S_0} \cdot \frac{\sum_{i=1}^{n}\sum_{j=1}^{n}w_{ij}(x_i-x_j)^2}{\sum_{i=1}^n(x_i-\bar{x})^2} \]
Jika nilai :
\(C <1\) : terjadi autkorelasi positif
\(C > 1\) : terjadi autokorelasi negatif
\(C \approx 1\) : tidak ada autokorelasi atau pola wilayah acak
Local Moran’s \(I_i\) (merupakan ukuran lokal dari autokorelasi spasial yang biasa digunakan untuk menemukan outlier atau lokasi cluster. Biasanya juga digunakan untuk melihat hotspot, coldspot, ataupun outlier) :
\[ I_i = \frac{x_i-\bar{x}}{m_2} \sum_{j=1}^N{w_{ij}(x_j - \bar{x})} \]
dengan
\[ m_2 = \frac{1}{N} \sum_{k=1}^{N}(x_k - \bar{x})^2 \]
Jika nilai
\(I_i > 0\) : unit spasial atau wilayah i memiliki nilai kemiripan dengan tetangganya atau terdapat cluster
\(I_i < 0\) : tidak terdapat kemiripan antar unit spasial i
\(I_i \approx 0\) : tidak ada pola lokal yang signifikan (acak)
Getis-Ord \(G_i\) dan \(G_i^*\) (merupakan statistik lokal untuk mendeteksi hotspot dan coldspot.) :
\[ G_i = \frac{\sum_{j \neq i} w_{ij}x_j}{\sum_{j\neq i}x_j} \]
\[ G_i^* = \frac{\sum_{j=1}^Nw_{ij}x_j}{\sum_{j=1}^{N}x_j} , \text{dengan } w_{ii} = 1 \]
library(sf)
## Linking to GEOS 3.13.1, GDAL 3.11.0, PROJ 9.6.0; sf_use_s2() is TRUE
library(sp)
library(spdep)
## Warning: package 'spdep' was built under R version 4.5.1
## Loading required package: spData
## Warning: package 'spData' was built under R version 4.5.1
## To access larger datasets in this package, install the spDataLarge
## package with: `install.packages('spDataLarge',
## repos='https://nowosad.github.io/drat/', type='source')`
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)
library(mapview)
library(spData)
# Membaca file RDS
setwd("C:/KAMPUS CHECK!/SPASIAL")
Indo_kec <- readRDS("gadm36_IDN_3_sp.rds")
Bandung <- Indo_kec[Indo_kec$NAME_2 =="Kota Bandung",]
Bandung$id <- seq_len(nrow(Bandung))
Bandung_sf <- sf::st_as_sf(Bandung)
# Peta Kota Bandung
ggplot(Bandung_sf) + geom_sf(fill="grey90", color="white") +
labs(title="Kota Bandung") + theme_minimal()
# Neighbor queen
nb <- spdep::poly2nb(sf::as_Spatial(Bandung_sf), queen = TRUE)
# Listw untuk analitik global/lokal (row-standar & biner)
lwW <- spdep::nb2listw(nb, style="W") # row-standardized
lwB <- spdep::nb2listw(nb, style="B") # binary (untuk raw G)
# Simulasi Data Diare per 10000 penduduk
set.seed(234)
lambda <- sample(2:30, size = nrow(Bandung), replace = TRUE)
kasus <- rpois(n = nrow(Bandung_sf), lambda = lambda)
data <- data.frame(
ID = Bandung_sf$id,
lambda = lambda,
kasus = kasus
)
diare <- dplyr::left_join(Bandung_sf, data, by = c("id" = "ID"))
# Pemetaan Kasus
ggplot(diare) +
geom_sf(aes(fill = kasus), color = "white") +
scale_fill_gradient(low = "lightyellow", high = "red") +
labs(title = "Peta Simulasi Kasus Diare per 10.000 Penduduk",
fill = "Kasus") +
theme_minimal()
Secara visual terlihat bahwa terdapat beberapa wilayah yang memiliki kasus tinggi (warna merah gelap). Ada pula wilayah-wilayah yang berdekatan yang berwarna kuning pucat yang menandakan adanya clustering di beberapa daerah.
Berapa nilai Moran’s I?
Apakah signifikan secara statistik (uji permutasi)?
Apa artinya bagi pola spasial penyakit?
Bagaimana perbandingannya dengan Moran’s I?
Jelaskan perbedaan sensitivitas kedua ukuran ini.
Identifikasi kecamatan yang masuk kategori High-High, Low-Low, High-Low, dan Low-High.
Buat peta cluster LISA.
Apa interpretasi hasil ini untuk kasus penyakit menular?
Tentukan kecamatan yang termasuk hot spot dan cold spot.
Bandingkan hasilnya dengan peta LISA.
Apakah ada perbedaan wilayah yang ditandai sebagai klaster signifikan?
moran_res <- spdep::moran.test(diare$kasus, lwW, randomisation = TRUE, alternative = "two.sided")
moran_res
##
## Moran I test under randomisation
##
## data: diare$kasus
## weights: lwW
##
## Moran I statistic standard deviate = -0.33806, p-value = 0.7353
## alternative hypothesis: two.sided
## sample estimates:
## Moran I statistic Expectation Variance
## -0.07340159 -0.03448276 0.01325371
Nilai Moran’s \(I\) adalah sebesar -0.0734 yang cukup mendekati 0, artinya data simulasi yang dimiliki bersifat acak. Dari pengujian permutasi didapatkan p-value sebesar 0.7353 yang menunjukkan bahwa tidak ada autokorelasi spasial yang terjadi pada data simulasi ini.
geary_res <- spdep::geary.test(diare$kasus, lwW,
randomisation = TRUE, alternative = "two.sided")
geary_res
##
## Geary C test under randomisation
##
## data: diare$kasus
## weights: lwW
##
## Geary C statistic standard deviate = -0.26088, p-value = 0.7942
## alternative hypothesis: two.sided
## sample estimates:
## Geary C statistic Expectation Variance
## 1.03044056 1.00000000 0.01361478
Dari hasil perhitungan Geary’s \(C\) didapatkan bahwa nilainya sebesar 1.030 yang mana \(\approx 1\) yang artinya tidak ada pola ataupun cluster yang terbentuk pada penyebaran penyakit diare di kota Bandung. Dari nilai p-valuenya pun menunjukkan bahwa tidak adanya autokorelasi spasial yang terbentuk.
Hasil dari Moran’s I dan Geary’s C sama-sama menunjukkan bahwa tidak ada pola dan cluster yang terbentuk dari data simulasi tersebut.
# --- Standarisasi data kasus ---
x <- scale(diare$kasus)[,1] # z-score untuk kasus diare
# --- Hitung spatial lag ---
lagx <- spdep::lag.listw(lwW, x, zero.policy = TRUE)
# --- Hitung Local Moran ---
lisa <- spdep::localmoran(x, lwW,
alternative = "two.sided",
zero.policy = TRUE)
# --- Ubah hasil ke data frame ---
lisa_df <- as.data.frame(lisa)
names(lisa_df) <- c("Ii","Ei","Vi","Zi","Pi.two.sided")
# --- Tentukan kategori kuadran ---
alpha <- 0.05
quad <- dplyr::case_when(
x >= 0 & lagx >= 0 ~ "High-High",
x < 0 & lagx < 0 ~ "Low-Low",
x >= 0 & lagx < 0 ~ "High-Low (Outlier)",
x < 0 & lagx >= 0 ~ "Low-High (Outlier)"
)
# --- Gabungkan ke data spasial ---
Bandung_LISA <- dplyr::bind_cols(diare, lisa_df) |>
dplyr::mutate(quad = ifelse(Pi.two.sided <= alpha, quad, "Not significant"))
# --- Ringkasan hasil ---
table(Bandung_LISA$quad)
##
## High-Low (Outlier) Not significant
## 1 29
# Ambil hanya kolom nama kecamatan dan kategorinya
outlier_kec <- subset(Bandung_LISA, grepl("Outlier", quad))
outlier_names <- outlier_kec[["NAME_3"]]
outlier_quad <- outlier_kec[["quad"]]
# Cetak hasil ringkas
data.frame(Kecamatan = outlier_names, Kategori = outlier_quad)
## Kecamatan Kategori
## 1 Sumur Bandung High-Low (Outlier)
# --- Contoh peta LISA ---
library(ggplot2)
pal <- c("High-High" = "red",
"Low-Low" = "blue",
"High-Low (Outlier)" = "orange",
"Low-High (Outlier)" = "cyan",
"Not significant" = "grey90")
ggplot(Bandung_LISA) +
geom_sf(aes(fill = quad), color = "white") +
scale_fill_manual(values = pal, na.value = "grey90") +
labs(title = "LISA Cluster (Local Moran’s I)",
subtitle = "Kasus Diare per 10.000 penduduk",
fill = "Cluster") +
theme_minimal()
Terdapat 1 outlier dari 30 kecamatan di Kota Bandung. Outlier tersebut adalah Kecamatan Sumur Bandung yang masuk pada kategori High-Low. Maksud dari kategori ini, kecamatan Sumur Bandung memiliki jumlah kasus yang tinggi tetapi sekitarnya rendah sehingga dapat disebut sebagai Outlier High-Low.
x_raw <- diare$kasus
sum_x <- sum(x_raw)
Wb <- spdep::listw2mat(lwW) # default diag=0
# --- Hitung G_i (tanpa i, w_ii=0) ---
num_G <- as.numeric(Wb %*% x_raw) # ÎŁ_j w_ij x_j
den_G <- (sum_x - x_raw) # Σ_j x_j, j ≠i
G_raw <- num_G / den_G
# --- Hitung G_i^* (dengan i, w_ii=1) ---
Wb_star <- Wb; diag(Wb_star) <- 1
num_Gs <- as.numeric(Wb_star %*% x_raw) # ÎŁ_j w_ij* x_j
den_Gs <- sum_x # ÎŁ_j x_j, semua
G_star_raw <- num_Gs / den_Gs
# --- Z-score Getis–Ord G* (pakai spdep) ---
Gz <- spdep::localG(x_raw, listw = lwW, zero.policy = TRUE)
# --- Gabungkan hasil ke data spasial ---
Bandung_G <- dplyr::mutate(diare,
G_raw = G_raw,
G_star_raw = G_star_raw,
z_Gistar = as.numeric(Gz),
hotcold = dplyr::case_when(
z_Gistar >= 1.96 ~ "Hot spot (p<0.05)",
z_Gistar <= -1.96 ~ "Cold spot (p<0.05)",
TRUE ~ "Not significant"
)
)
# --- Ringkasan statistik ---
summary(dplyr::select(Bandung_G, G_raw, G_star_raw, z_Gistar))
## G_raw G_star_raw z_Gistar geometry
## Min. :0.01416 Min. :0.03185 Min. :-2.63371 MULTIPOLYGON :30
## 1st Qu.:0.02815 1st Qu.:0.04634 1st Qu.:-0.59245 epsg:NA : 0
## Median :0.03287 Median :0.05949 Median :-0.14249 +proj=long...: 0
## Mean :0.03410 Mean :0.06631 Mean :-0.06676
## 3rd Qu.:0.03954 3rd Qu.:0.08382 3rd Qu.: 0.61909
## Max. :0.06250 Max. :0.11540 Max. : 1.69779
table(Bandung_G$hotcold)
##
## Cold spot (p<0.05) Not significant
## 1 29
# --- Peta Hotspot / Coldspot ---
pal_gc <- c("Hot spot (p<0.05)" = "red",
"Cold spot (p<0.05)" = "blue",
"Not significant" = "grey90")
ggplot(Bandung_G) +
geom_sf(aes(fill = hotcold), color = "white") +
scale_fill_manual(values = pal_gc) +
labs(title = "Getis–Ord Gi* Hotspot Analysis",
subtitle = "Kasus diare per 10.000 penduduk",
fill = "Cluster") +
theme_minimal()
Dari hasil perhitungan dengan Getis-Ord didapatkan bahwa terdapata cold spot yang merupakan Kecamatan Sumur Bandung. Hal ini menunjukkan bahwa wilayah ini memiliki jumlah kasus yang rendah dan dikelilingi dengan tetangga wilayah yang rendah.
library(patchwork)
## Warning: package 'patchwork' was built under R version 4.5.1
p1 <- ggplot(Bandung_G) +
geom_sf(aes(fill = G_star_raw), color="white", size=0.2) +
scale_fill_viridis_c() +
labs(title="Raw Getis–Ord G*", fill="G*_raw") +
theme_minimal()
p2 <- ggplot(Bandung_G) +
geom_sf(aes(fill = z_Gistar), color="white", size=0.2) +
scale_fill_gradient2(low="blue", mid="white", high="red", midpoint=0) +
labs(title="Z-score Getis–Ord G*", fill="Z(G*)") +
theme_minimal()
p1 + p2
Ketika antara Raw Getis Ord dan Z-Score Getis Ord dibandingkan, ada beberapa perbedaan. Raw menunjukkan proporsi kasus di sekitar tiap kecamatan dibandingkan total, sedangkan Z-score ini merupakan hasil standarisasi yang menunjukkan hotspot ataupun coldspot.
MAUP (Modifiable Areal Unit Problem)
Ukuran bobot spasial (rook, queen, k-nearest neighbors)
Masalah multiple testing pada analisis lokal
Analisis autokorelasi spasial dapat menjadi tambahan informasi bagi dinas kesehatan untuk melihat dari sisi pemetaan jumlah penyakit yang terjadi. Bukan hanya melihat jumlah kasusnya tetapi daerah mana-mana saja yang rawan untuk menjadi penyebar kasus. Adanya hotspot akan menjadi perhatian khusus bagi pemerintah untuk dapat melakukan intervensi secara cepat, sedangkan adanya coldspot membuat pemerintah melihat intervensi apa yang dilakukan pada wilayah tersebut untuk ditiru dan dilakukan. Ketika ada outlier, perlu dilihat lebih lagi faktor-faktor yang berpengaruh terhadap daerah atau wilayah tersebut. Selain itu dengan adanya pemetaan ini dapat mengefisiensi banyak hal terutama pada sumber daya dan keuangan karena pengerjaan intervensi ataupun penanganan sudah fokus pada wilayah-wilayah tertentu.
Terdapat beberapa keterbatasan analisis autokorelasi spasial, misalnya karena MAUP (Modifiable Areal Unit Problem) dimana hasil analisis bergantung batas wilayah yang dipakai hal ini bisa saja menjadi rancu untuk hasil analisisnya karena misal ketika analisis dilakukan dengan unit wilayah yang lebih kecil merupakan hotspot tetapi ketika unit wilayah tersebut diperbesar kasus hotspot tersebut menghilang.
Selain itu ketika analisis autokorelasi spasial dilakukan dengan ukuran bobot spasial ada beberapa hal yang mempengaruhi hasilnya. Ukuran bobot spasial ada 3 yang dapat digunakan yaitu dengan rook (berbagai sisi), queen (sisi + titik) atau k-nearest neighbors (berdasarkan jarak), dari ukuran ini ketika menggunakan beda ukuran akan menghasilkan hasil yang berbeda juga.
Kemudian ada masalah multiple testing pada analisis lokal, ketika banyak uji statistik spasial yang dilakukan sekaligus mungkin saja akan muncul masalah false positive, dimana seolah-olah ada klaster yang signifikan padahal itu hanya kebetulan dan perlu diperiksa lebih lagi.