1 Tujuan Praktikum

Pada pertemuan sebelumnya kita sudah mengenal konsep dasar dalam analisis spasial. Pada praktikum kali ini, kita akan fokus pada salah satu komponen penting dalam analisis dan regresi spasial, yaitu matriks pembobot spasial.

Sebelum melakukan analisis spasial, kita perlu menentukan terlebih dahulu bagaimana hubungan antara satu wilayah dengan wilayah lainnya. Sederhananya, kita ingin mengetahui wilayah mana yang dianggap bertetangga dan seberapa kuat hubungan antarwilayah tersebut.

Hubungan antarwilayah dapat ditentukan dengan beberapa pendekatan, misalnya berdasarkan jarak, jumlah tetangga terdekat, maupun batas wilayah yang saling bersinggungan.

Setelah mengikuti praktikum ini, mahasiswa diharapkan mampu:

  1. memahami konsep proksimitas, ketetanggaan, dan matriks pembobot spasial;
  2. menghitung beberapa ukuran jarak antarwilayah;
  3. membentuk ketetanggaan berdasarkan distance band, k-nearest neighbors (KNN), dan contiguity;
  4. membentuk matriks pembobot spasial dalam bentuk binary dan row-standardized;
  5. memvisualisasikan hubungan ketetanggaan antarwilayah menggunakan R; dan
  6. memahami bahwa pemilihan matriks pembobot spasial dapat memengaruhi hasil analisis spasial pada tahap berikutnya.

2 Persiapan

Sebelum mulai membentuk matriks pembobot spasial, kita perlu menyiapkan beberapa package yang akan digunakan selama praktikum.

Package di R dapat dianalogikan sebagai kumpulan fungsi tambahan yang dibuat untuk tujuan tertentu. Pada praktikum ini, kita akan menggunakan beberapa package untuk mengelola data spasial, menentukan hubungan ketetanggaan, melakukan manipulasi data, serta membuat visualisasi.

2.1 Package yang Digunakan

Berikut package yang akan digunakan pada praktikum ini.

Package Kegunaan
sf Digunakan untuk membaca, menyimpan, mengelola, dan melakukan operasi pada data spasial, seperti titik, garis, dan polygon.
spdep Digunakan untuk membentuk hubungan ketetanggaan dan matriks pembobot spasial, seperti Queen, Rook, K-Nearest Neighbors (KNN), dan distance-based neighbors.
dplyr Digunakan untuk manipulasi data, seperti memilih variabel, membuat variabel baru, melakukan filter, serta mengurutkan data.
ggplot2 Digunakan untuk membuat visualisasi data dan peta agar pola spasial lebih mudah diamati.
tibble Digunakan untuk membuat dan menampilkan data dalam bentuk tabel yang lebih rapi dan mudah dibaca.
knitr Membantu menampilkan hasil analisis, seperti tabel, secara lebih rapi pada dokumen R Markdown.
units Digunakan untuk mengatur dan mengonversi satuan pengukuran, terutama ketika bekerja dengan jarak seperti meter atau kilometer.

Package yang paling penting pada praktikum ini adalah sf dan spdep.
Package sf akan membantu kita bekerja dengan objek spasial, sedangkan spdep akan banyak digunakan untuk membentuk hubungan ketetanggaan dan matriks pembobot spasial.

install.packages(c(
  "sf",
  "spdep",
  "dplyr",
  "ggplot2",
  "tibble",
  "knitr",
  "units"
))

Kemudian panggil package yang diperlukan.

library(sf)
library(spdep)
library(dplyr)
library(ggplot2)
library(tibble)
library(knitr)
library(units)

2.1.1 Package Utama pada Praktikum

Walaupun terdapat beberapa package yang digunakan, dua package yang akan paling sering muncul adalah sf dan spdep.

1. Package sf

sf merupakan singkatan dari Simple Features. Package ini digunakan untuk bekerja dengan data yang memiliki informasi lokasi atau geometri.

Sebagai contoh, suatu objek spasial dapat berbentuk:

  • Point, misalnya lokasi stasiun cuaca;
  • Line, misalnya jalan atau sungai; dan
  • Polygon, misalnya batas kecamatan, kabupaten, atau provinsi.

Pada praktikum ini, sf terutama akan digunakan untuk mengelola data polygon dan koordinat wilayah.

2. Package spdep

spdep merupakan salah satu package yang banyak digunakan dalam analisis dependensi spasial.

Pada praktikum ini, spdep akan digunakan untuk:

  • menentukan wilayah yang saling bertetangga;
  • membentuk Queen contiguity;
  • membentuk Rook contiguity;
  • menentukan K-Nearest Neighbors (KNN);
  • menentukan ketetanggaan berdasarkan jarak;
  • membuat daftar tetangga (neighbour list);
  • membentuk matriks pembobot spasial; dan
  • melakukan standardisasi bobot spasial.

Nantinya kita akan menemukan beberapa fungsi dari spdep, seperti poly2nb(), knearneigh(), knn2nb(), dnearneigh(), nb2listw(), dan nb2mat(). Fungsi-fungsi tersebut akan kita pelajari secara bertahap, sehingga tidak perlu dihafalkan di awal.

3 Mengenal Proksimitas dan Ketetanggaan

Sebelum membentuk matriks pembobot spasial, kita perlu memahami terlebih dahulu bagaimana hubungan antara satu wilayah dengan wilayah lainnya didefinisikan.

Dalam analisis spasial, lokasi yang berdekatan sering kali memiliki karakteristik yang lebih mirip dibandingkan lokasi yang berjauhan. Namun, istilah “dekat” tidak selalu berarti hanya dekat secara jarak.

Dua konsep yang penting untuk dipahami adalah proksimitas dan ketetanggaan.

3.0.1 Proksimitas

Proksimitas menggambarkan tingkat kedekatan antarwilayah atau antarlokasi. Kedekatan tersebut dapat ditentukan berdasarkan karakteristik atau mekanisme spasial yang dianggap relevan dalam penelitian.

Sebagai contoh, dua kabupaten dapat dianggap memiliki kedekatan karena:

  • jaraknya relatif dekat;
  • berbatasan secara langsung;
  • termasuk dalam sejumlah wilayah terdekat; atau
  • memiliki hubungan spasial tertentu yang sesuai dengan konteks penelitian.

Dengan demikian, proksimitas tidak selalu hanya berarti “jaraknya dekat”, tetapi lebih umum menggambarkan seberapa dekat atau seberapa kuat hubungan spasial antarwilayah.

3.0.2 Ketetanggaan

Setelah menentukan konsep kedekatan, langkah berikutnya adalah menentukan ketetanggaan.

Ketetanggaan menunjukkan apakah suatu wilayah dianggap memiliki hubungan langsung dengan wilayah lainnya.

Secara sederhana, kita dapat membayangkan pertanyaan:

“Wilayah A bertetangga dengan wilayah mana saja?”

Jawaban dari pertanyaan tersebut nantinya digunakan untuk membentuk struktur ketetanggaan.

Dalam praktikum ini, ketetanggaan akan ditentukan menggunakan beberapa pendekatan:

  1. Berdasarkan jarak (distance-based neighbors)
    Dua wilayah dianggap bertetangga apabila jaraknya memenuhi kriteria tertentu.

  2. K-Nearest Neighbors (KNN)
    Setiap wilayah dihubungkan dengan sejumlah k wilayah yang memiliki jarak paling dekat.

  3. Contiguity
    Dua wilayah dianggap bertetangga apabila batas wilayahnya saling bersentuhan. Pendekatan ini nantinya dibedakan menjadi Queen Contiguity dan Rook Contiguity.

Perhatikan perbedaannya:

Ketetanggaan menjawab pertanyaan “siapa tetangganya?”, sedangkan matriks pembobot spasial memberikan nilai atau bobot terhadap hubungan antarwilayah tersebut.



Jadi, kita menentukan tetangganya terlebih dahulu, kemudian menentukan bobot hubungan antar tetangga.

3.0.3 Contoh Sederhana

Misalkan terdapat lima wilayah, yaitu A, B, C, D, dan E.

Jika wilayah A berbatasan langsung dengan wilayah B dan C, maka berdasarkan pendekatan contiguity kita dapat mengatakan:

  • A bertetangga dengan B;
  • A bertetangga dengan C;
  • A tidak bertetangga langsung dengan D dan E.

Hubungan tersebut nantinya dapat ditulis dalam bentuk sederhana sebagai:

Wilayah B C D E
A 1 1 0 0

Nilai 1 menunjukkan bahwa wilayah tersebut dianggap bertetangga, sedangkan nilai 0 menunjukkan bahwa wilayah tersebut tidak dianggap bertetangga.

Konsep sederhana inilah yang nantinya akan dikembangkan menjadi matriks ketetanggaan dan selanjutnya menjadi matriks pembobot spasial.

4 Ukuran Jarak

Setelah memahami konsep proksimitas dan ketetanggaan, sekarang kita mulai dari salah satu cara paling sederhana untuk mendefinisikan kedekatan antar lokasi, yaitu menggunakan jarak.

Dalam analisis spasial, jarak digunakan untuk menggambarkan seberapa jauh suatu lokasi dari lokasi lainnya. Secara umum, semakin kecil jarak antara dua lokasi, maka keduanya dapat dianggap memiliki kedekatan spasial yang lebih tinggi.

Namun, cara menghitung jarak tidak selalu sama. Pemilihan ukuran jarak bergantung pada jenis koordinat dan karakteristik data yang digunakan.

Pada praktikum ini kita akan mengenal beberapa ukuran jarak, yaitu:

  1. Jarak Euclidean, yaitu jarak garis lurus antara dua lokasi;
  2. Jarak Manhattan, yaitu jarak berdasarkan perpindahan horizontal dan vertikal;
  3. Jarak Minkowski, yaitu bentuk umum dari beberapa ukuran jarak; dan
  4. Great Circle Distance, yaitu jarak yang memperhitungkan kelengkungan permukaan bumi.

Kita akan mempelajarinya secara bertahap menggunakan contoh sederhana terlebih dahulu.

4.1 Data Koordinat Sederhana

Agar konsep jarak lebih mudah dipahami, kita mulai dengan contoh sederhana menggunakan lima lokasi, yaitu A, B, C, D, dan E.

Setiap lokasi memiliki dua koordinat, yaitu koordinat x dan y. Pada contoh ini, koordinat tersebut merupakan koordinat buatan sehingga belum memiliki satuan geografis tertentu.

Data sederhana ini akan kita gunakan untuk melihat bagaimana posisi antar titik dapat diterjemahkan menjadi nilai jarak.

lokasi <- tibble(
  nama = c("A", "B", "C", "D", "E"),
  x = c(1, 2, 5, 6, 8),
  y = c(1, 4, 2, 6, 3)
)

lokasi
## # A tibble: 5 × 3
##   nama      x     y
##   <chr> <dbl> <dbl>
## 1 A         1     1
## 2 B         2     4
## 3 C         5     2
## 4 D         6     6
## 5 E         8     3

Dari tabel di atas, setiap baris menunjukkan satu lokasi pengamatan beserta posisi koordinatnya.

Sebagai contoh:

  • lokasi A berada pada koordinat (1, 1);
  • lokasi B berada pada koordinat (2, 4);
  • lokasi C berada pada koordinat (5, 2);
  • lokasi D berada pada koordinat (6, 6); dan
  • lokasi E berada pada koordinat (8, 3).

Koordinat tersebut selanjutnya dapat divisualisasikan agar posisi relatif antar lokasi lebih mudah diamati.

4.1.1 Visualisasi Posisi Lokasi

Sebelum menghitung jarak, kita lihat terlebih dahulu posisi kelima lokasi tersebut pada bidang koordinat.

Visualisasi ini membantu kita memperoleh gambaran awal mengenai lokasi mana yang terlihat berdekatan dan lokasi mana yang relatif berjauhan.

ggplot(lokasi, aes(x = x, y = y, label = nama)) +
  geom_point(size = 3) +
  geom_text(nudge_y = 0.3) +
  coord_equal() +
  labs(
    title = "Lokasi Lima Titik Pengamatan",
    x = "Koordinat X",
    y = "Koordinat Y"
  ) +
  theme_minimal()

Berdasarkan visualisasi di atas, terlihat bahwa setiap lokasi memiliki posisi yang berbeda pada bidang koordinat.

Secara visual, beberapa pasangan titik tampak relatif berdekatan. Misalnya, titik A terlihat cukup dekat dengan titik B, sedangkan titik A dan E terlihat memiliki jarak yang lebih jauh.

Namun, penilaian hanya berdasarkan visualisasi belum memberikan ukuran yang pasti.

Oleh karena itu, pada tahap selanjutnya kita akan menghitung jarak antar lokasi secara numerik menggunakan beberapa ukuran jarak.

Perhatikan: Grafik membantu kita melihat kedekatan secara visual, tetapi untuk menentukan seberapa dekat dua lokasi secara objektif kita membutuhkan ukuran jarak.

4.2 Jarak Euclidean

Ukuran jarak pertama yang akan kita gunakan adalah jarak Euclidean.

Jarak Euclidean merupakan jarak lurus antara dua titik. Ukuran ini mungkin merupakan konsep jarak yang paling familiar karena sama seperti ketika kita mengukur panjang garis lurus dari satu posisi menuju posisi lainnya.

Untuk dua lokasi dengan koordinat \((x_i,y_i)\) dan \((x_j,y_j)\), jarak Euclidean dapat dinyatakan sebagai:

\[ d_{ij}=\sqrt{(x_i-x_j)^2+(y_i-y_j)^2} \]

dengan:

  • \(d_{ij}\) = jarak antara lokasi ke-\(i\) dan lokasi ke-\(j\);
  • \(x_i\) dan \(y_i\) = koordinat lokasi ke-\(i\); dan
  • \(x_j\) dan \(y_j\) = koordinat lokasi ke-\(j\).

Semakin kecil nilai \(d_{ij}\), maka kedua lokasi tersebut semakin dekat secara spasial.

# Membuat matriks koordinat
coord_mat <- as.matrix(lokasi[, c("x", "y")])

# Memberikan nama baris sesuai nama lokasi
rownames(coord_mat) <- lokasi$nama

# Menghitung jarak Euclidean
D_euclidean <- dist(
  coord_mat,
  method = "euclidean"
)

as.matrix(D_euclidean)
##          A        B        C        D        E
## A 0.000000 3.162278 4.123106 7.071068 7.280110
## B 3.162278 0.000000 3.605551 4.472136 6.082763
## C 4.123106 3.605551 0.000000 4.123106 3.162278
## D 7.071068 4.472136 4.123106 0.000000 3.605551
## E 7.280110 6.082763 3.162278 3.605551 0.000000

Hasil yang diperoleh berbentuk matriks jarak.

Cara membaca matriks tersebut adalah dengan melihat perpotongan antara baris dan kolom dari dua lokasi yang ingin dibandingkan.

Beberapa hal yang perlu diperhatikan:

  1. nilai pada diagonal utama selalu 0, karena jarak suatu lokasi terhadap dirinya sendiri adalah nol;
  2. matriks jarak bersifat simetris, sehingga jarak A ke B sama dengan jarak B ke A; dan
  3. semakin kecil nilai jarak, semakin dekat posisi kedua lokasi tersebut.

Matriks jarak seperti ini nantinya dapat digunakan sebagai dasar dalam menentukan hubungan ketetanggaan antarwilayah.

4.3 Jarak Manhattan

Ukuran jarak berikutnya adalah jarak Manhattan.

Berbeda dengan jarak Euclidean yang mengukur jarak lurus antara dua titik, jarak Manhattan menghitung jarak berdasarkan total perpindahan pada masing-masing arah koordinat.

Untuk dua lokasi dengan koordinat \((x_i,y_i)\) dan \((x_j,y_j)\), jarak Manhattan dapat dituliskan sebagai:

\[ d_{ij}=|x_i-x_j|+|y_i-y_j| \]

Jarak ini dapat dibayangkan seperti perjalanan pada jalan yang tersusun membentuk blok-blok kota. Untuk berpindah dari satu lokasi ke lokasi lain, kita bergerak secara horizontal dan vertikal, bukan memotong langsung secara diagonal.

Selanjutnya, kita hitung jarak Manhattan untuk lima lokasi yang sama.

D_manhattan <- dist(
  coord_mat,
  method = "manhattan"
)

as.matrix(D_manhattan)
##    A B C  D E
## A  0 4 5 10 9
## B  4 0 5  6 7
## C  5 5 0  5 4
## D 10 6 5  0 5
## E  9 7 4  5 0

Hasil yang diperoleh kembali berbentuk matriks jarak.

Sama seperti matriks Euclidean:

  • diagonal utama bernilai 0 karena jarak suatu lokasi terhadap dirinya sendiri adalah nol;
  • matriks bersifat simetris;
  • nilai yang lebih kecil menunjukkan dua lokasi yang lebih dekat berdasarkan ukuran jarak Manhattan.

Perbedaannya terletak pada cara jarak tersebut dihitung.

4.3.1 Membandingkan Euclidean dan Manhattan

Agar perbedaannya lebih mudah dipahami, kita bandingkan jarak antara lokasi A dan B menggunakan kedua metode.

as.matrix(D_euclidean)["A", "B"]
## [1] 3.162278
as.matrix(D_manhattan)["A", "B"]
## [1] 4

Dari hasil tersebut diperoleh:

  • jarak Euclidean A–B = 3.162;
  • jarak Manhattan A–B = 4.

Mengapa nilainya berbeda?

Lokasi A berada pada koordinat (1,1), sedangkan lokasi B berada pada (2,4).

Untuk jarak Manhattan, perpindahannya adalah:

\[ |2-1|+|4-1|=1+3=4 \]

Sedangkan jarak Euclidean menghitung jarak lurus:

\[ \sqrt{(2-1)^2+(4-1)^2} = \sqrt{1+9} = \sqrt{10} \approx 3.162 \]

Dengan demikian, meskipun pasangan lokasi yang dibandingkan sama, nilai jarak dapat berbeda karena cara mendefinisikan jaraknya berbeda.

Intinya:
Euclidean mengukur jarak lurus, sedangkan Manhattan mengukur total perpindahan horizontal dan vertikal. Oleh karena itu, pemilihan ukuran jarak perlu disesuaikan dengan karakteristik data dan mekanisme hubungan spasial yang ingin direpresentasikan.

4.4 Jarak Minkowski

Setelah mengenal Euclidean dan Manhattan, sekarang kita masuk ke jarak Minkowski.

Jarak Minkowski merupakan bentuk umum dari beberapa ukuran jarak. Nilai jaraknya ditentukan oleh parameter \(p\).

Secara umum, jarak Minkowski dapat dituliskan sebagai:

\[ d_{ij} = \left( |x_i-x_j|^p+ |y_i-y_j|^p \right)^{1/p} \]

Parameter \(p\) menentukan bentuk ukuran jarak yang digunakan.

Beberapa kasus khusus yang penting adalah:

  • jika \(p=1\), jarak Minkowski menjadi jarak Manhattan;
  • jika \(p=2\), jarak Minkowski menjadi jarak Euclidean.

Pada contoh berikut kita menggunakan \(p=3\) untuk melihat bagaimana perubahan nilai \(p\) menghasilkan ukuran jarak yang berbeda.

D_minkowski_p3 <- dist(
  lokasi[, c("x", "y")],
  method = "minkowski",
  p = 3
)

as.matrix(D_minkowski_p3)
##          1        2        3        4        5
## 1 0.000000 3.036589 4.020726 6.299605 7.054004
## 2 3.036589 0.000000 3.271066 4.160168 6.009245
## 3 4.020726 3.271066 0.000000 4.020726 3.036589
## 4 6.299605 4.160168 4.020726 0.000000 3.271066
## 5 7.054004 6.009245 3.036589 3.271066 0.000000

Matriks di atas menunjukkan jarak Minkowski dengan \(p=3\) untuk setiap pasangan lokasi.

Perhatikan bahwa nilai yang diperoleh berbeda dari Manhattan maupun Euclidean. Hal ini terjadi karena perubahan nilai \(p\) mengubah cara perbedaan koordinat diberikan bobot dalam perhitungan jarak.

4.4.1 Mencoba Nilai p yang Berbeda

Sekarang kita periksa hubungan antara Minkowski, Manhattan, dan Euclidean.

Ubah nilai p menjadi 1 dan 2, kemudian bandingkan hasilnya dengan matriks jarak yang sudah dihitung sebelumnya.

D_minkowski_p1 <- dist(
  coord_mat,
  method = "minkowski",
  p = 1
)

D_minkowski_p2 <- dist(
  coord_mat,
  method = "minkowski",
  p = 2
)

as.matrix(D_minkowski_p1)
##    A B C  D E
## A  0 4 5 10 9
## B  4 0 5  6 7
## C  5 5 0  5 4
## D 10 6 5  0 5
## E  9 7 4  5 0
as.matrix(D_minkowski_p2)
##          A        B        C        D        E
## A 0.000000 3.162278 4.123106 7.071068 7.280110
## B 3.162278 0.000000 3.605551 4.472136 6.082763
## C 4.123106 3.605551 0.000000 4.123106 3.162278
## D 7.071068 4.472136 4.123106 0.000000 3.605551
## E 7.280110 6.082763 3.162278 3.605551 0.000000

Dari percobaan tersebut dapat diamati bahwa:

  • Minkowski dengan \(p=1\) menghasilkan nilai yang sama dengan Manhattan;
  • Minkowski dengan \(p=2\) menghasilkan nilai yang sama dengan Euclidean.

Artinya, Euclidean dan Manhattan sebenarnya merupakan kasus khusus dari jarak Minkowski.

Hubungan penting yang perlu diingat:

Minkowski \(p=1\) → Manhattan
Minkowski \(p=2\) → Euclidean

4.5 Great Circle Distance

Jika data menggunakan koordinat longitude dan latitude, perhitungan jarak perlu mempertimbangkan bentuk permukaan bumi.

Karena itu, kita dapat menggunakan Great Circle Distance atau jarak geodesik.

Pada contoh ini digunakan tiga kota, yaitu Bogor, Jakarta, dan Bandung.

kota <- tibble(
  kota = c("Bogor", "Jakarta", "Bandung"),
  lon = c(106.8060, 106.8456, 107.6191),
  lat = c(-6.5971, -6.2088, -6.9175)
)

kota_sf <- st_as_sf(
  kota,
  coords = c("lon", "lat"),
  crs = 4326
)

D_kota <- st_distance(kota_sf)
set_units(D_kota, "km")
## Units: [km]
##          [,1]      [,2]      [,3]
## [1,]  0.00000  43.39823  96.59473
## [2,] 43.39823   0.00000 116.23658
## [3,] 96.59473 116.23658   0.00000

Dari hasil tersebut diperoleh:

  • Bogor–Jakarta sekitar 43,40 km;
  • Bogor–Bandung sekitar 96,59 km;
  • Jakarta–Bandung sekitar 116,24 km.

Pasangan kota dengan jarak paling dekat adalah Bogor dan Jakarta.

Jika data menggunakan longitude dan latitude, gunakan fungsi seperti st_distance() agar jarak dihitung dalam konteks geografis.

5 Contoh Matriks Jarak Enam Area

Sekarang kita gunakan contoh matriks jarak untuk enam area.

Setiap nilai pada matriks menunjukkan jarak antara satu area dengan area lainnya dalam satuan kilometer.

Contohnya:

  • jarak Area 1 ke Area 2 adalah 40 km;
  • jarak Area 1 ke Area 3 adalah 10 km;
  • jarak Area 4 ke Area 5 adalah 14 km.

Matriks jarak ini selanjutnya akan digunakan untuk menentukan wilayah mana yang dianggap bertetangga berdasarkan beberapa pendekatan.

D <- matrix(
  c(
     0, 40, 10, 22, 45, 73,
    40,  0, 28, 20, 22, 51,
    10, 28,  0, 22, 32, 50,
    22, 20, 22,  0, 14, 22,
    45, 22, 32, 14,  0, 22,
    73, 51, 50, 22, 22,  0
  ),
  nrow = 6,
  byrow = TRUE
)

rownames(D) <- colnames(D) <- paste0("Area_", 1:6)

D
##        Area_1 Area_2 Area_3 Area_4 Area_5 Area_6
## Area_1      0     40     10     22     45     73
## Area_2     40      0     28     20     22     51
## Area_3     10     28      0     22     32     50
## Area_4     22     20     22      0     14     22
## Area_5     45     22     32     14      0     22
## Area_6     73     51     50     22     22      0

Dari matriks di atas dapat diperhatikan bahwa:

  • nilai diagonal selalu 0, karena jarak suatu area terhadap dirinya sendiri adalah nol;
  • matriks bersifat simetris, sehingga jarak Area 1 ke Area 2 sama dengan jarak Area 2 ke Area 1;
  • semakin kecil nilainya, semakin dekat jarak antara kedua area.

Sebagai contoh, Area 1 paling dekat dengan Area 3 karena jaraknya hanya 10 km.

6 Ketetanggaan Berdasarkan Jarak Ambang

Pada pendekatan jarak ambang (distance band), dua wilayah dianggap bertetangga jika jaraknya masih berada dalam batas tertentu.

Pada contoh ini digunakan batas jarak sebesar 25 km. Artinya:

  • jika jarak antararea ≤ 25 km, maka diberi nilai 1;
  • jika jarak antararea > 25 km, maka diberi nilai 0.

Dengan cara ini, matriks jarak sebelumnya dapat diubah menjadi matriks ketetanggaan.

\[ w_{ij} = \begin{cases} 1, & 0 < d_{ij} \leq d_{max}\\ 0, & d_{ij} > d_{max} \end{cases} \]

Selanjutnya, kita gunakan matriks jarak enam area sebelumnya dan menentukan dmax = 25.

dmax <- 25

W_threshold <- matrix(0, nrow(D), ncol(D))
W_threshold[D > 0 & D <= dmax] <- 1

W_threshold
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,]    0    0    1    1    0    0
## [2,]    0    0    0    1    1    0
## [3,]    1    0    0    1    0    0
## [4,]    1    1    1    0    1    1
## [5,]    0    1    0    1    0    1
## [6,]    0    0    0    1    1    0

6.0.1 Interpretasi

Pada matriks di atas:

  • nilai 1 menunjukkan bahwa dua area dianggap bertetangga;
  • nilai 0 menunjukkan bahwa dua area tidak dianggap bertetangga;
  • diagonal bernilai 0 karena suatu area tidak dianggap sebagai tetangga dirinya sendiri.

Sebagai contoh:

  • Area 1 bertetangga dengan Area 3 dan Area 4;
  • Area 2 bertetangga dengan Area 4 dan Area 5;
  • Area 4 memiliki hubungan dengan lebih banyak area dibandingkan area lainnya.

Untuk mengetahui berapa banyak tetangga yang dimiliki setiap area, kita dapat menjumlahkan nilai pada setiap baris menggunakan rowSums().

rowSums(W_threshold)
## [1] 2 2 2 5 3 2

Hasil tersebut menunjukkan bahwa:

  • Area 1 memiliki 2 tetangga;
  • Area 2 memiliki 2 tetangga;
  • Area 3 memiliki 2 tetangga;
  • Area 4 memiliki 5 tetangga;
  • Area 5 memiliki 3 tetangga;
  • Area 6 memiliki 2 tetangga.

Dengan demikian, Area 4 merupakan area yang memiliki jumlah tetangga paling banyak pada batas jarak 25 km.

7 Ketetanggaan Berdasarkan K-Nearest Neighbors

Pada pendekatan K-Nearest Neighbors (KNN), setiap area dihubungkan dengan sejumlah k area yang memiliki jarak paling dekat.

Pada contoh ini digunakan k = 3, sehingga setiap area akan memiliki 3 tetangga terdekat.

Matriks jarak enam area sebelumnya digunakan untuk mencari tiga area dengan jarak paling kecil dari setiap area.

k <- 3

W_knn <- matrix(
  0,
  nrow = nrow(D),
  ncol = ncol(D),
  dimnames = dimnames(D)
)

for (i in 1:nrow(D)) {
  urutan <- order(D[i, ])
  tetangga <- urutan[urutan != i][1:k]
  W_knn[i, tetangga] <- 1
}

W_knn
##        Area_1 Area_2 Area_3 Area_4 Area_5 Area_6
## Area_1      0      1      1      1      0      0
## Area_2      0      0      1      1      1      0
## Area_3      1      1      0      1      0      0
## Area_4      1      1      0      0      1      0
## Area_5      0      1      0      1      0      1
## Area_6      0      0      1      1      1      0

7.0.1 Interpretasi

Pada matriks KNN:

  • nilai 1 menunjukkan bahwa area tersebut termasuk tetangga terdekat;
  • nilai 0 menunjukkan bahwa area tersebut tidak termasuk tetangga terdekat.

Sebagai contoh, Area 1 memiliki tiga tetangga terdekat, yaitu Area 2, Area 3, dan Area 4.

Untuk memastikan bahwa setiap area memiliki tiga tetangga, kita dapat menjumlahkan nilai pada setiap baris.

rowSums(W_knn)
## Area_1 Area_2 Area_3 Area_4 Area_5 Area_6 
##      3      3      3      3      3      3

Hasil rowSums() menunjukkan bahwa seluruh area memiliki tepat 3 tetangga, sesuai dengan nilai k = 3 yang digunakan.

Catatan: Pada KNN, hubungan ketetanggaan tidak selalu dua arah. Suatu area dapat memilih area lain sebagai tetangga terdekat, tetapi belum tentu berlaku sebaliknya.

8 Bobot Jarak Invers

Pada inverse distance, bobot antarwilayah ditentukan berdasarkan jaraknya.

Prinsipnya sederhana:

  • wilayah yang lebih dekat akan memperoleh bobot yang lebih besar;
  • wilayah yang lebih jauh akan memperoleh bobot yang lebih kecil.

Bobot jarak invers dapat dituliskan sebagai:

\[ w_{ij}=d_{ij}^{-\alpha} \]

Nilai \(\alpha\) mengatur seberapa cepat bobot menurun ketika jarak semakin jauh.

Pertama, kita gunakan \(\alpha = 1\).

alpha_inv <- 1

W_inverse <- matrix(
  0,
  nrow = nrow(D),
  ncol = ncol(D),
  dimnames = dimnames(D)
)

W_inverse[D > 0] <- D[D > 0]^(-alpha_inv)

round(W_inverse, 4)
##        Area_1 Area_2 Area_3 Area_4 Area_5 Area_6
## Area_1 0.0000 0.0250 0.1000 0.0455 0.0222 0.0137
## Area_2 0.0250 0.0000 0.0357 0.0500 0.0455 0.0196
## Area_3 0.1000 0.0357 0.0000 0.0455 0.0312 0.0200
## Area_4 0.0455 0.0500 0.0455 0.0000 0.0714 0.0455
## Area_5 0.0222 0.0455 0.0312 0.0714 0.0000 0.0455
## Area_6 0.0137 0.0196 0.0200 0.0455 0.0455 0.0000

8.0.1 Interpretasi

Dari hasil tersebut terlihat bahwa area yang memiliki jarak lebih dekat memperoleh bobot yang lebih besar.

Sebagai contoh:

  • jarak Area 1 ke Area 3 adalah 10 km, sehingga bobotnya sebesar 0,1000;
  • jarak Area 1 ke Area 6 adalah 73 km, sehingga bobotnya hanya sekitar 0,0137.

Artinya, semakin jauh jaraknya, semakin kecil bobot yang diberikan.

Selanjutnya, kita coba menggunakan \(\alpha = 2\) untuk melihat perubahan bobot.

alpha_inv2 <- 2

W_inverse2 <- matrix(
  0,
  nrow = nrow(D),
  ncol = ncol(D),
  dimnames = dimnames(D)
)

W_inverse2[D > 0] <- D[D > 0]^(-alpha_inv2)

round(W_inverse2, 6)
##          Area_1   Area_2   Area_3   Area_4   Area_5   Area_6
## Area_1 0.000000 0.000625 0.010000 0.002066 0.000494 0.000188
## Area_2 0.000625 0.000000 0.001276 0.002500 0.002066 0.000384
## Area_3 0.010000 0.001276 0.000000 0.002066 0.000977 0.000400
## Area_4 0.002066 0.002500 0.002066 0.000000 0.005102 0.002066
## Area_5 0.000494 0.002066 0.000977 0.005102 0.000000 0.002066
## Area_6 0.000188 0.000384 0.000400 0.002066 0.002066 0.000000

Ketika nilai \(\alpha\) diperbesar menjadi 2, bobot menjadi lebih cepat mengecil seiring bertambahnya jarak.

Jadi, nilai \(\alpha\) yang lebih besar membuat pengaruh wilayah yang jauh menjadi semakin kecil.

Intinya: semakin dekat dua wilayah, semakin besar bobotnya. Semakin besar nilai \(\alpha\), semakin cepat bobot menurun ketika jarak bertambah.

9 Bobot Jarak Eksponensial

Pada bobot jarak eksponensial, bobot antarwilayah juga akan semakin kecil ketika jarak semakin besar.

Bobot dapat dituliskan sebagai:

\[ w_{ij}=\exp(-\alpha d_{ij}) \]

Nilai \(\alpha\) mengatur seberapa cepat bobot menurun terhadap jarak.

Pada contoh ini digunakan nilai \(\alpha = 0.05\).

alpha_exp <- 0.05

W_exp <- exp(-alpha_exp * D)
diag(W_exp) <- 0

round(W_exp, 4)
##        Area_1 Area_2 Area_3 Area_4 Area_5 Area_6
## Area_1 0.0000 0.1353 0.6065 0.3329 0.1054 0.0260
## Area_2 0.1353 0.0000 0.2466 0.3679 0.3329 0.0781
## Area_3 0.6065 0.2466 0.0000 0.3329 0.2019 0.0821
## Area_4 0.3329 0.3679 0.3329 0.0000 0.4966 0.3329
## Area_5 0.1054 0.3329 0.2019 0.4966 0.0000 0.3329
## Area_6 0.0260 0.0781 0.0821 0.3329 0.3329 0.0000

9.0.1 Interpretasi

Dari hasil tersebut terlihat bahwa wilayah yang lebih dekat memiliki bobot yang lebih besar.

Sebagai contoh untuk Area 1:

  • Area 3 memiliki bobot sekitar 0.6065;
  • Area 4 memiliki bobot sekitar 0.3329;
  • Area 6 hanya memiliki bobot sekitar 0.0260.

Hal ini menunjukkan bahwa semakin jauh jaraknya, semakin kecil bobot yang diberikan.

Untuk melihat pola tersebut dengan lebih jelas, kita tampilkan bobot Area 1 terhadap seluruh area lainnya.

round(W_exp["Area_1", ], 4)
## Area_1 Area_2 Area_3 Area_4 Area_5 Area_6 
## 0.0000 0.1353 0.6065 0.3329 0.1054 0.0260

Coba sendiri: ubah nilai alpha_exp menjadi 0.01 dan 0.10. Perhatikan bagaimana perubahan nilai \(\alpha\) memengaruhi bobot wilayah yang jauh.

Intinya: semakin besar nilai \(\alpha\), semakin cepat bobot mengecil ketika jarak bertambah.

10 Double Power Distance

Pada Double Power Distance, bobot ditentukan berdasarkan jarak dengan menggunakan suatu batas tertentu.

Prinsipnya:

  • semakin dekat jaraknya, semakin besar bobotnya;
  • semakin jauh jaraknya, semakin kecil bobotnya;
  • jika jarak melebihi batas yang ditentukan, maka bobotnya menjadi 0.

Pada contoh ini digunakan batas jarak 50 km dan nilai k = 2.

d_cutoff <- 50
k_power <- 2

W_double <- ifelse(
  D <= d_cutoff,
  (1 - (D / d_cutoff)^k_power)^k_power,
  0
)

diag(W_double) <- 0
dimnames(W_double) <- dimnames(D)

round(W_double, 4)
##        Area_1 Area_2 Area_3 Area_4 Area_5 Area_6
## Area_1 0.0000 0.1296 0.9216 0.6503 0.0361 0.0000
## Area_2 0.1296 0.0000 0.4711 0.7056 0.6503 0.0000
## Area_3 0.9216 0.4711 0.0000 0.6503 0.3486 0.0000
## Area_4 0.6503 0.7056 0.6503 0.0000 0.8493 0.6503
## Area_5 0.0361 0.6503 0.3486 0.8493 0.0000 0.6503
## Area_6 0.0000 0.0000 0.0000 0.6503 0.6503 0.0000

10.0.1 Interpretasi

Dari hasil tersebut terlihat bahwa area yang memiliki jarak lebih dekat memperoleh bobot yang lebih besar.

Sebagai contoh:

  • Area 1 dan Area 3 memiliki jarak 10 km, sehingga bobotnya cukup besar, yaitu sekitar 0.9216;
  • Area 1 dan Area 2 memiliki jarak 40 km, sehingga bobotnya lebih kecil, yaitu sekitar 0.1296;
  • Area 1 dan Area 6 memiliki jarak 73 km, sehingga bobotnya menjadi 0 karena jaraknya melebihi batas 50 km.

Intinya: Double Power Distance memberikan bobot yang semakin kecil ketika jarak bertambah, dan memberikan bobot 0 jika jarak sudah melewati batas yang ditentukan.

11 Standardisasi Baris

Setelah matriks pembobot terbentuk, bobot tersebut sering distandarisasi per baris.

Tujuannya agar jumlah bobot pada setiap baris menjadi 1.

Caranya adalah dengan membagi setiap bobot dengan jumlah bobot pada baris tersebut.

Kita buat fungsi sederhana untuk melakukan standardisasi baris secara otomatis.

row_standardize <- function(W) {
  total <- rowSums(W)

  W_std <- W
  punya_tetangga <- total > 0

  W_std[punya_tetangga, ] <-
    W[punya_tetangga, , drop = FALSE] /
    total[punya_tetangga]

  W_std[!punya_tetangga, ] <- 0

  W_std
}

Selanjutnya, fungsi tersebut diterapkan pada matriks ketetanggaan distance band yang sudah dibuat sebelumnya.

W_threshold_std <- row_standardize(W_threshold)

round(W_threshold_std, 3)
##      [,1]  [,2] [,3]  [,4] [,5]  [,6]
## [1,]  0.0 0.000  0.5 0.500  0.0 0.000
## [2,]  0.0 0.000  0.0 0.500  0.5 0.000
## [3,]  0.5 0.000  0.0 0.500  0.0 0.000
## [4,]  0.2 0.200  0.2 0.000  0.2 0.200
## [5,]  0.0 0.333  0.0 0.333  0.0 0.333
## [6,]  0.0 0.000  0.0 0.500  0.5 0.000
rowSums(W_threshold_std)
## [1] 1 1 1 1 1 1

11.0.1 Interpretasi

Perhatikan bahwa nilai bobot sekarang bergantung pada jumlah tetangga setiap area.

Sebagai contoh:

  • Area 1 memiliki 2 tetangga, sehingga masing-masing memperoleh bobot 0.5;
  • Area 4 memiliki 5 tetangga, sehingga masing-masing memperoleh bobot 0.2;
  • Area 5 memiliki 3 tetangga, sehingga masing-masing memperoleh bobot sekitar 0.333.

Hasil rowSums() menunjukkan bahwa jumlah bobot pada setiap baris sudah menjadi 1.

Artinya, proses standardisasi baris berhasil dilakukan.

Intinya: setelah standardisasi baris, total bobot yang dimiliki setiap area menjadi 1.

Jika suatu area mempunyai 4 tetangga dengan bobot awal yang sama, maka masing-masing tetangga akan memperoleh bobot \(1/4 = 0.25\).

12 Contiguity: Queen dan Rook

Pada pendekatan contiguity, ketetanggaan ditentukan berdasarkan batas wilayah.

Dua wilayah dianggap bertetangga jika batas wilayahnya saling bersentuhan.

Terdapat dua jenis contiguity yang akan digunakan, yaitu:

  • Queen Contiguity
  • Rook Contiguity

12.1 Membuat Grid Sederhana

Agar perbedaan Queen dan Rook lebih mudah dipahami, kita membuat contoh sederhana berupa grid berukuran 3 × 3.

Grid ini terdiri dari 9 area yang akan digunakan untuk melihat hubungan ketetanggaan antarwilayah.

grid_geom <- st_make_grid(
  st_bbox(c(
    xmin = 0,
    ymin = 0,
    xmax = 3,
    ymax = 3
  )),
  n = c(3, 3)
)

grid_sf <- st_sf(
  id = paste0("Area_", 1:9),
  geometry = grid_geom
)

grid_sf
## Simple feature collection with 9 features and 1 field
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 0 ymin: 0 xmax: 3 ymax: 3
## CRS:           NA
##       id                       geometry
## 1 Area_1 POLYGON ((0 0, 1 0, 1 1, 0 ...
## 2 Area_2 POLYGON ((1 0, 2 0, 2 1, 1 ...
## 3 Area_3 POLYGON ((2 0, 3 0, 3 1, 2 ...
## 4 Area_4 POLYGON ((0 1, 1 1, 1 2, 0 ...
## 5 Area_5 POLYGON ((1 1, 2 1, 2 2, 1 ...
## 6 Area_6 POLYGON ((2 1, 3 1, 3 2, 2 ...
## 7 Area_7 POLYGON ((0 2, 1 2, 1 3, 0 ...
## 8 Area_8 POLYGON ((1 2, 2 2, 2 3, 1 ...
## 9 Area_9 POLYGON ((2 2, 3 2, 3 3, 2 ...

Objek grid_sf sekarang berisi 9 area berbentuk polygon.

Selanjutnya, grid tersebut akan divisualisasikan agar posisi setiap area lebih mudah dilihat.

center_grid <- st_coordinates(st_centroid(grid_sf))
## Warning: st_centroid assumes attributes are constant over geometries
plot(st_geometry(grid_sf), col = "white")
text(
  center_grid[, 1],
  center_grid[, 2],
  labels = grid_sf$id
)

Dari grid tersebut, kita dapat melihat area mana yang saling berbagi sisi maupun sudut.

Hal inilah yang nantinya membedakan Queen Contiguity dan Rook Contiguity.

12.2 Queen Contiguity

Pada Queen Contiguity, dua area dianggap bertetangga jika berbagi sisi atau titik sudut.

Untuk membentuk hubungan ketetanggaan, digunakan fungsi poly2nb() dari package spdep.

Pada Queen Contiguity digunakan queen = TRUE.

nb_queen <- poly2nb(
  grid_sf,
  queen = TRUE,
  row.names = grid_sf$id
)

nb_queen
## Neighbour list object:
## Number of regions: 9 
## Number of nonzero links: 40 
## Percentage nonzero weights: 49.38272 
## Average number of links: 4.444444

Output tersebut menunjukkan bahwa objek nb_queen berisi hubungan ketetanggaan untuk 9 area.

Untuk mengetahui jumlah tetangga dari setiap area, digunakan fungsi card().

card(nb_queen)
## [1] 3 5 3 5 8 5 3 5 3

12.2.1 Interpretasi

Hasil tersebut menunjukkan jumlah tetangga untuk Area 1 sampai Area 9.

Sebagai contoh:

  • Area 1 memiliki 3 tetangga;
  • Area 2 memiliki 5 tetangga;
  • Area 5 sebagai area tengah memiliki 8 tetangga.

Area tengah memiliki tetangga paling banyak karena pada Queen Contiguity, hubungan melalui sisi dan sudut sama-sama dihitung.

12.3 Rook Contiguity

Pada Rook Contiguity, dua area dianggap bertetangga hanya jika berbagi sisi.

Pada fungsi poly2nb(), Rook Contiguity ditentukan dengan queen = FALSE.

nb_rook <- poly2nb(
  grid_sf,
  queen = FALSE,
  row.names = grid_sf$id
)

nb_rook
## Neighbour list object:
## Number of regions: 9 
## Number of nonzero links: 24 
## Percentage nonzero weights: 29.62963 
## Average number of links: 2.666667
card(nb_rook)
## [1] 2 3 2 3 4 3 2 3 2

12.3.1 Interpretasi

Pada Rook Contiguity, jumlah tetangga lebih sedikit karena hubungan melalui sudut tidak dihitung.

Sebagai contoh:

  • Area 1 memiliki 2 tetangga;
  • Area 2 memiliki 3 tetangga;
  • Area 5 sebagai area tengah memiliki 4 tetangga.

12.3.2 Membandingkan Queen dan Rook

Agar perbedaannya lebih jelas, kita bandingkan tetangga Area 5, yaitu area yang berada di tengah grid.

nb_queen[[5]]
## [1] 1 2 3 4 6 7 8 9
nb_rook[[5]]
## [1] 2 4 6 8
grid_sf$id[nb_queen[[5]]]
## [1] "Area_1" "Area_2" "Area_3" "Area_4" "Area_6" "Area_7" "Area_8" "Area_9"
grid_sf$id[nb_rook[[5]]]
## [1] "Area_2" "Area_4" "Area_6" "Area_8"

Pada Queen Contiguity, Area 5 bertetangga dengan:

Area 1, 2, 3, 4, 6, 7, 8, dan 9.

Sedangkan pada Rook Contiguity, Area 5 hanya bertetangga dengan:

Area 2, 4, 6, dan 8.

Kesimpulan:
Queen menghasilkan lebih banyak tetangga karena hubungan melalui sisi dan sudut ikut dihitung, sedangkan Rook hanya menghitung hubungan melalui sisi.

13 Mengubah Objek Tetangga Menjadi Matriks

Setelah hubungan ketetanggaan terbentuk, objek tetangga dapat diubah menjadi matriks pembobot spasial.

Pada bagian ini kita akan melihat dua bentuk matriks, yaitu:

  • Binary, yang hanya menunjukkan ada atau tidaknya hubungan ketetanggaan;
  • Row-standardized, yaitu bobot yang sudah distandarisasi sehingga jumlah setiap baris menjadi 1.

13.1 Matriks Binary

Matriks binary menggunakan:

  • nilai 1 jika dua area bertetangga;
  • nilai 0 jika dua area tidak bertetangga.

Pada fungsi nb2mat(), style = "B" menunjukkan bahwa matriks yang dibuat adalah matriks binary.

W_queen_B <- nb2mat(
  nb_queen,
  style = "B",
  zero.policy = TRUE
)

W_queen_B
##        Area_1 Area_2 Area_3 Area_4 Area_5 Area_6 Area_7 Area_8 Area_9
## Area_1      0      1      0      1      1      0      0      0      0
## Area_2      1      0      1      1      1      1      0      0      0
## Area_3      0      1      0      0      1      1      0      0      0
## Area_4      1      1      0      0      1      0      1      1      0
## Area_5      1      1      1      1      0      1      1      1      1
## Area_6      0      1      1      0      1      0      0      1      1
## Area_7      0      0      0      1      1      0      0      1      0
## Area_8      0      0      0      1      1      1      1      0      1
## Area_9      0      0      0      0      1      1      0      1      0
## attr(,"call")
## nb2mat(neighbours = nb_queen, style = "B", zero.policy = TRUE)

13.1.1 Interpretasi

Sebagai contoh, pada baris Area 1 terlihat nilai 1 pada Area 2, Area 4, dan Area 5.

Artinya, berdasarkan Queen Contiguity, Area 1 bertetangga dengan Area 2, Area 4, dan Area 5.

13.2 Matriks Row-Standardized

Selanjutnya, matriks ketetanggaan dapat distandarisasi per baris.

Pada fungsi nb2mat(), style = "W" digunakan untuk menghasilkan matriks row-standardized.

W_queen_W <- nb2mat(
  nb_queen,
  style = "W",
  zero.policy = TRUE
)

round(W_queen_W, 3)
##        Area_1 Area_2 Area_3 Area_4 Area_5 Area_6 Area_7 Area_8 Area_9
## Area_1  0.000  0.333  0.000  0.333  0.333  0.000  0.000  0.000  0.000
## Area_2  0.200  0.000  0.200  0.200  0.200  0.200  0.000  0.000  0.000
## Area_3  0.000  0.333  0.000  0.000  0.333  0.333  0.000  0.000  0.000
## Area_4  0.200  0.200  0.000  0.000  0.200  0.000  0.200  0.200  0.000
## Area_5  0.125  0.125  0.125  0.125  0.000  0.125  0.125  0.125  0.125
## Area_6  0.000  0.200  0.200  0.000  0.200  0.000  0.000  0.200  0.200
## Area_7  0.000  0.000  0.000  0.333  0.333  0.000  0.000  0.333  0.000
## Area_8  0.000  0.000  0.000  0.200  0.200  0.200  0.200  0.000  0.200
## Area_9  0.000  0.000  0.000  0.000  0.333  0.333  0.000  0.333  0.000
## attr(,"call")
## nb2mat(neighbours = nb_queen, style = "W", zero.policy = TRUE)

13.2.1 Interpretasi

Setelah standardisasi, jumlah bobot pada setiap baris menjadi 1.

Sebagai contoh:

  • Area 1 memiliki 3 tetangga, sehingga masing-masing mendapat bobot sekitar 0.333;
  • Area 5 memiliki 8 tetangga, sehingga masing-masing mendapat bobot 0.125.
rowSums(W_queen_W)
## Area_1 Area_2 Area_3 Area_4 Area_5 Area_6 Area_7 Area_8 Area_9 
##      1      1      1      1      1      1      1      1      1

Hasil rowSums() menunjukkan bahwa jumlah bobot pada setiap baris sudah sama dengan 1.

Ingat:
style = “B” → matriks binary (0 dan 1)
style = “W” → matriks row-standardized (jumlah setiap baris = 1)

14 Penerapan pada Data Polygon Nyata

Setelah memahami konsep ketetanggaan menggunakan contoh sederhana, sekarang kita menerapkannya pada data polygon nyata.

Pada bagian ini digunakan data wilayah North Carolina yang sudah tersedia di dalam package sf, sehingga kita tidak perlu mengunduh shapefile tambahan.

Data ini terdiri dari 100 wilayah yang masing-masing memiliki informasi atribut dan bentuk wilayah (geometry).

Data dibaca menggunakan fungsi st_read(). Selanjutnya dibuat variabel rate_sid74, yaitu rasio SID74 terhadap BIR74 yang dikalikan 1000.

Pada data ini:

  • SID74 = jumlah kasus Sudden Infant Death tahun 1974;
  • BIR74 = jumlah kelahiran tahun 1974;
  • rate_sid74 = jumlah kasus per 1000 kelahiran.
nc <- st_read(
  system.file("shape/nc.shp", package = "sf"),
  quiet = TRUE
)

nc <- nc %>%
  mutate(
    rate_sid74 = SID74 / BIR74 * 1000
  )

nc
## Simple feature collection with 100 features and 15 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
## Geodetic CRS:  NAD27
## First 10 features:
##     AREA PERIMETER CNTY_ CNTY_ID        NAME  FIPS FIPSNO CRESS_ID BIR74 SID74
## 1  0.114     1.442  1825    1825        Ashe 37009  37009        5  1091     1
## 2  0.061     1.231  1827    1827   Alleghany 37005  37005        3   487     0
## 3  0.143     1.630  1828    1828       Surry 37171  37171       86  3188     5
## 4  0.070     2.968  1831    1831   Currituck 37053  37053       27   508     1
## 5  0.153     2.206  1832    1832 Northampton 37131  37131       66  1421     9
## 6  0.097     1.670  1833    1833    Hertford 37091  37091       46  1452     7
## 7  0.062     1.547  1834    1834      Camden 37029  37029       15   286     0
## 8  0.091     1.284  1835    1835       Gates 37073  37073       37   420     0
## 9  0.118     1.421  1836    1836      Warren 37185  37185       93   968     4
## 10 0.124     1.428  1837    1837      Stokes 37169  37169       85  1612     1
##    NWBIR74 BIR79 SID79 NWBIR79                       geometry rate_sid74
## 1       10  1364     0      19 MULTIPOLYGON (((-81.47276 3...  0.9165903
## 2       10   542     3      12 MULTIPOLYGON (((-81.23989 3...  0.0000000
## 3      208  3616     6     260 MULTIPOLYGON (((-80.45634 3...  1.5683814
## 4      123   830     2     145 MULTIPOLYGON (((-76.00897 3...  1.9685039
## 5     1066  1606     3    1197 MULTIPOLYGON (((-77.21767 3...  6.3335679
## 6      954  1838     5    1237 MULTIPOLYGON (((-76.74506 3...  4.8209366
## 7      115   350     2     139 MULTIPOLYGON (((-76.00897 3...  0.0000000
## 8      254   594     2     371 MULTIPOLYGON (((-76.56251 3...  0.0000000
## 9      748  1190     2     844 MULTIPOLYGON (((-78.30876 3...  4.1322314
## 10     160  2038     5     176 MULTIPOLYGON (((-80.02567 3...  0.6203474

Dari output terlihat bahwa data memiliki 100 wilayah dengan tipe geometry MULTIPOLYGON.

Artinya, setiap baris mewakili satu wilayah yang memiliki data atribut sekaligus informasi bentuk geografisnya.

14.1 Peta Variabel

Sebelum membentuk hubungan ketetanggaan, kita visualisasikan terlebih dahulu nilai rate_sid74 pada setiap wilayah.

Warna pada peta menunjukkan besar kecilnya nilai kasus per 1000 kelahiran.

ggplot(nc) +
  geom_sf(aes(fill = rate_sid74)) +
  labs(
    title = "Contoh Data Spasial: North Carolina",
    fill = "SID per 1000"
  ) +
  theme_minimal()

14.1.1 Interpretasi

Peta menunjukkan bahwa nilai rate_sid74 berbeda antarwilayah.

Wilayah dengan warna yang lebih terang memiliki nilai yang relatif lebih tinggi, sedangkan warna yang lebih gelap menunjukkan nilai yang lebih rendah.

Selanjutnya, kita akan membentuk hubungan ketetanggaan antarwilayah menggunakan Queen Contiguity dan Rook Contiguity.

14.2 Queen Contiguity pada Polygon Nyata

Pada data polygon nyata, hubungan ketetanggaan dapat dibentuk menggunakan Queen Contiguity.

Dengan pendekatan ini, dua wilayah dianggap bertetangga jika berbagi sisi atau titik sudut.

Fungsi poly2nb() digunakan untuk membentuk daftar tetangga, sedangkan card() digunakan untuk menghitung jumlah tetangga setiap wilayah.

nb_nc_queen <- poly2nb(
  nc,
  queen = TRUE,
  row.names = nc$NAME
)

summary(card(nb_nc_queen))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     2.0     4.0     5.0     4.9     6.0     9.0

14.2.1 Interpretasi

Hasil tersebut menunjukkan bahwa jumlah tetangga setiap wilayah berbeda-beda.

Secara umum:

  • jumlah tetangga minimum adalah 2 wilayah;
  • rata-rata jumlah tetangga sekitar 4,9 wilayah;
  • jumlah tetangga maksimum adalah 9 wilayah.

Artinya, ada wilayah yang hanya memiliki sedikit tetangga, tetapi ada juga wilayah yang memiliki hubungan dengan banyak wilayah di sekitarnya.

Selanjutnya, kita lihat lima wilayah yang memiliki jumlah tetangga paling banyak.

tibble(
  wilayah = nc$NAME,
  jumlah_tetangga = card(nb_nc_queen)
) %>%
  arrange(desc(jumlah_tetangga)) %>%
  slice_head(n = 5)
## # A tibble: 5 × 2
##   wilayah jumlah_tetangga
##   <chr>             <int>
## 1 Iredell               9
## 2 Moore                 9
## 3 Wilkes                8
## 4 Chatham               8
## 5 Halifax               7

Dari hasil tersebut, wilayah dengan jumlah tetangga terbanyak adalah:

  • Iredell = 9 tetangga;
  • Moore = 9 tetangga;
  • Wilkes = 8 tetangga;
  • Chatham = 8 tetangga;
  • Halifax = 7 tetangga.

Perbedaan jumlah tetangga ini dipengaruhi oleh posisi dan bentuk masing-masing wilayah pada peta.

Intinya: pada polygon nyata, jumlah tetangga antarwilayah tidak selalu sama karena bentuk dan posisi wilayah berbeda-beda.

14.3 Rook Contiguity pada Polygon Nyata

Pada Rook Contiguity, dua wilayah dianggap bertetangga hanya jika berbagi sisi batas.

Hubungan ketetanggaan dibentuk menggunakan poly2nb() dengan queen = FALSE.

nb_nc_rook <- poly2nb(
  nc,
  queen = FALSE,
  row.names = nc$NAME
)

summary(card(nb_nc_rook))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    2.00    3.00    5.00    4.62    6.00    9.00

14.3.1 Interpretasi

Hasil tersebut menunjukkan bahwa pada Rook Contiguity:

  • jumlah tetangga minimum adalah 2 wilayah;
  • rata-rata jumlah tetangga sekitar 4,62 wilayah;
  • jumlah tetangga maksimum adalah 9 wilayah.

Jumlah tetangga setiap wilayah dapat berbeda karena bentuk dan posisi wilayah pada peta tidak sama.

Selanjutnya, kita bandingkan jumlah hubungan ketetanggaan yang dihasilkan oleh Queen dan Rook.

sum(card(nb_nc_queen))
## [1] 490
sum(card(nb_nc_rook))
## [1] 462

Hasil menunjukkan bahwa:

  • Queen menghasilkan total 490 hubungan;
  • Rook menghasilkan total 462 hubungan.

Jumlah hubungan pada Queen lebih banyak karena Queen menghitung wilayah yang berbagi sisi maupun titik sudut, sedangkan Rook hanya menghitung wilayah yang berbagi sisi.

Catatan: Hubungan contiguity umumnya bersifat dua arah. Jika A bertetangga dengan B, maka B juga bertetangga dengan A. Karena itu, satu pasangan wilayah dapat terhitung dua kali pada jumlah di atas.

15 Visualisasi Jaringan Ketetanggaan

Setelah hubungan ketetanggaan terbentuk, kita dapat memvisualisasikannya dalam bentuk jaringan ketetanggaan.

Setiap titik mewakili satu wilayah, sedangkan garis menunjukkan hubungan antarwilayah yang dianggap bertetangga.

Sebelum membuat jaringan, data terlebih dahulu ditransformasikan ke sistem koordinat proyeksi.

Selanjutnya, dibuat satu titik representatif untuk setiap polygon menggunakan st_point_on_surface().

nc_proj <- st_transform(nc, 32119)

nc_point <- st_point_on_surface(nc_proj)
## Warning: st_point_on_surface assumes attributes are constant over geometries
coords_nc <- st_coordinates(nc_point)

Selanjutnya, jaringan ketetanggaan Queen digambarkan di atas peta wilayah.

plot(st_geometry(nc_proj), border = "grey70")
plot(
  nb_nc_queen,
  coords_nc,
  add = TRUE
)

15.0.1 Interpretasi

Pada gambar di atas:

  • batas abu-abu menunjukkan wilayah polygon;
  • titik menunjukkan posisi representatif setiap wilayah;
  • garis menunjukkan hubungan ketetanggaan berdasarkan Queen Contiguity.

Semakin banyak garis yang terhubung pada suatu wilayah, semakin banyak tetangga yang dimiliki wilayah tersebut.

Intinya: visualisasi jaringan membantu kita melihat secara langsung bagaimana hubungan ketetanggaan antarwilayah terbentuk.

16 K-Nearest Neighbors dengan Package spdep

Pada bagian ini, K-Nearest Neighbors (KNN) diterapkan pada data polygon nyata menggunakan package spdep.

Misalkan setiap wilayah ditentukan memiliki 4 tetangga terdekat.

Fungsi knearneigh() digunakan untuk mencari tetangga terdekat, kemudian hasilnya diubah menjadi objek ketetanggaan menggunakan knn2nb().

knn4 <- knearneigh(
  coords_nc,
  k = 4
)

nb_knn4 <- knn2nb(
  knn4,
  row.names = nc$NAME
)

card(nb_knn4)
##   [1] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
##  [38] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
##  [75] 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4

16.0.1 Interpretasi

Hasil card() menunjukkan bahwa setiap wilayah memiliki tepat 4 tetangga.

Hal ini sesuai dengan nilai k = 4 yang sudah ditentukan sebelumnya.

unique(card(nb_knn4))
## [1] 4

Nilai 4 menunjukkan bahwa seluruh wilayah memiliki jumlah tetangga yang sama, yaitu 4 wilayah terdekat.

Selanjutnya, hubungan KNN tersebut diubah menjadi matriks pembobot spasial yang sudah distandarisasi per baris.

lw_knn4 <- nb2listw(
  nb_knn4,
  style = "W",
  zero.policy = TRUE
)

W_knn4 <- listw2mat(lw_knn4)

round(W_knn4[1:8, 1:8], 3)
##             Ashe Alleghany Surry Currituck Northampton Hertford Camden Gates
## Ashe        0.00      0.25  0.00      0.00        0.00     0.00   0.00  0.00
## Alleghany   0.25      0.00  0.25      0.00        0.00     0.00   0.00  0.00
## Surry       0.00      0.25  0.00      0.00        0.00     0.00   0.00  0.00
## Currituck   0.00      0.00  0.00      0.00        0.00     0.00   0.25  0.00
## Northampton 0.00      0.00  0.00      0.00        0.00     0.25   0.00  0.00
## Hertford    0.00      0.00  0.00      0.00        0.25     0.00   0.00  0.25
## Camden      0.00      0.00  0.00      0.25        0.00     0.00   0.00  0.00
## Gates       0.00      0.00  0.00      0.00        0.00     0.25   0.00  0.00

16.0.2 Interpretasi Matriks Bobot

Karena setiap wilayah memiliki 4 tetangga, maka setelah standardisasi baris masing-masing tetangga memperoleh bobot:

\[ \frac{1}{4}=0.25 \]

Nilai 0 menunjukkan wilayah yang tidak termasuk empat tetangga terdekat.

Intinya: pada KNN dengan k = 4, setiap wilayah memiliki 4 tetangga. Setelah distandarisasi, masing-masing tetangga memperoleh bobot 0.25.

17 Distance Band dengan Package spdep

Pada pendekatan Distance Band, dua wilayah dianggap bertetangga jika jaraknya masih berada dalam batas tertentu.

Pada contoh ini, batas jarak ditentukan secara otomatis berdasarkan jarak maksimum menuju tetangga terdekat pertama.

nb_1nn <- knn2nb(
  knearneigh(coords_nc, k = 1)
)
## Warning in knn2nb(knearneigh(coords_nc, k = 1)): neighbour object has 30
## sub-graphs
jarak_1nn <- unlist(
  nbdists(nb_1nn, coords_nc)
)

dmax_auto <- max(jarak_1nn) * 1.01

dmax_auto
## [1] 39716.15

Nilai batas jarak yang diperoleh sekitar 39.716 meter atau sekitar 39,7 km.

Selanjutnya, batas tersebut digunakan untuk membentuk hubungan ketetanggaan menggunakan fungsi dnearneigh().

nb_dist <- dnearneigh(
  coords_nc,
  d1 = 0,
  d2 = dmax_auto,
  row.names = nc$NAME
)
## Warning in dnearneigh(coords_nc, d1 = 0, d2 = dmax_auto, row.names = nc$NAME):
## neighbour object has 4 sub-graphs
summary(card(nb_dist))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.00    2.00    3.00    2.68    3.00    5.00

17.0.1 Interpretasi

Hasil tersebut menunjukkan bahwa dengan batas jarak yang digunakan:

  • jumlah tetangga minimum adalah 1 wilayah;
  • rata-rata jumlah tetangga sekitar 2,68 wilayah;
  • jumlah tetangga maksimum adalah 5 wilayah.
sum(card(nb_dist) == 0)
## [1] 0

Hasil 0 menunjukkan bahwa tidak ada wilayah yang tidak memiliki tetangga.

Artinya, semua wilayah sudah terhubung dengan minimal satu wilayah lain berdasarkan batas jarak yang digunakan.

Intinya: Distance Band menentukan tetangga berdasarkan batas jarak. Batas yang terlalu kecil dapat menyebabkan suatu wilayah tidak memiliki tetangga.

18 Membandingkan Beberapa Matriks Bobot

Setiap metode ketetanggaan dapat menghasilkan struktur hubungan yang berbeda.

Untuk melihat perbedaannya, kita bandingkan Queen, Rook, KNN k = 4, dan Distance Band berdasarkan jumlah tetangga yang dihasilkan.

perbandingan <- tibble(
  metode = c(
    "Queen",
    "Rook",
    "KNN k=4",
    "Distance Band"
  ),
  minimum_tetangga = c(
    min(card(nb_nc_queen)),
    min(card(nb_nc_rook)),
    min(card(nb_knn4)),
    min(card(nb_dist))
  ),
  rata_rata_tetangga = c(
    mean(card(nb_nc_queen)),
    mean(card(nb_nc_rook)),
    mean(card(nb_knn4)),
    mean(card(nb_dist))
  ),
  maksimum_tetangga = c(
    max(card(nb_nc_queen)),
    max(card(nb_nc_rook)),
    max(card(nb_knn4)),
    max(card(nb_dist))
  )
)

kable(
  perbandingan,
  digits = 2,
  caption = "Perbandingan Struktur Ketetanggaan"
)
Perbandingan Struktur Ketetanggaan
metode minimum_tetangga rata_rata_tetangga maksimum_tetangga
Queen 2 4.90 9
Rook 2 4.62 9
KNN k=4 4 4.00 4
Distance Band 1 2.68 5

18.0.1 Interpretasi

Dari tabel di atas dapat dilihat bahwa:

  • Queen memiliki rata-rata sekitar 4,90 tetangga;
  • Rook memiliki rata-rata sekitar 4,62 tetangga;
  • KNN k = 4 selalu menghasilkan tepat 4 tetangga untuk setiap wilayah;
  • Distance Band menghasilkan rata-rata sekitar 2,68 tetangga.

Perbedaan ini menunjukkan bahwa cara kita mendefinisikan ketetanggaan akan menghasilkan struktur hubungan spasial yang berbeda.

Kesimpulan: tidak ada satu jenis matriks pembobot yang selalu cocok untuk semua data. Pemilihannya harus disesuaikan dengan cara hubungan spasial antarwilayah ingin didefinisikan.