Saya mengalami masalah yang menjengkelkan dan saya mencoba mencari solusi otomatis untuk. Versi singkatnya adalah saya memiliki shapefile dan tabel data yang dibuat untuk wilayah di dalam negara. Tabel data yang dibuat TIDAK memiliki semacam kode GID / admin standar untuk dicocokkan dengan shapefile, dan nama wilayah juga tidak sama persis. Mari kita lihat lebih dekat; inilah bingkai data dummy + shapefile saya.
library(rgdal)
#load in shapefile
arm <- readOGR("D:/Country-Shapefiles/ARM_adm_shp", layer = "ARM_adm1")
#create dummy data frame
id <- c(100:110)
name <- c("Aragatsotn", "Ararat", "Armavir", "Gaghark'unik'", "Kotayk", "Lorri",
"Shirak", "Syunik'", "Tavush", "Vayots' Dzor", "Yerevan City")
value <- runif(11, 0.0, 1.0)
df <- data.frame(id, name, value)
Jadi yang saya miliki adalah tabel dengan ID acak, nama wilayah, dan nilai yang akan diplot dengan peta choropleth. Terlihat seperti ini:
> df
id name value
1 100 Aragatsotn 0.6923852
2 101 Ararat 0.5762024
3 102 Armavir 0.4688358
4 103 Gaghark'unik' 0.4702253
5 104 Kotayk 0.9347992
6 105 Lorri 0.1937813
7 106 Shirak 0.5162604
8 107 Syunik' 0.4332389
9 108 Tavush 0.9889513
10 109 Vayots' Dzor 0.2182024
11 110 Yerevan City 0.5791886
Melihat atribut shapefile yang menarik, kami mendapatkan ini:
> arm@data[c("ID_1", "NAME_1")]
ID_1 NAME_1
0 1 Aragatsotn
1 2 Ararat
2 3 Armavir
3 4 Erevan
4 5 Gegharkunik
5 6 Kotayk
6 7 Lori
7 8 Shirak
8 9 Syunik
9 10 Tavush
10 11 Vayots Dzor
Idealnya, df
akan menyertakan semacam ID admin yang cocok untuk bergabung ke shapefile. Sayangnya, siapa pun yang membuat data yang saya gunakan tidak mengikuti konvensi ini. Atau, akan sangat bagus untuk mencocokkan nama wilayah itu sendiri ... tetapi seperti yang Anda lihat, ada sedikit variasi dalam setiap nama.
Mencocokkan dengan tangan selalu merupakan solusi cadangan, tetapi siapa yang mau meluangkan waktu untuk melakukan itu? ;) Tapi sungguh, bahkan mencegah kemalasan, proyek yang sedang saya kerjakan akan memetakan lusinan negara, jadi saya mencari solusi otomatis yang dapat melakukan segalanya tanpa harus melakukan apa pun dengan tangan. Apakah ini mungkin? Bisakah saya mencocokkan nama-nama wilayah-paling-ini dengan shapefile?
Sidenote: Saya mencari grepl
kecocokan string parsial untuk setiap posting ini , tapi saya tidak yakin apakah ini solusi potensial karena saya perlu menggambar dari nama kolom daripada memasukkan setiap nama wilayah dengan tangan.
EDIT: Ketika saya mencocokkan ID dengan tangan, apa yang telah saya lakukan adalah membuat kolom baru di bingkai data saya dan menambahkan istilah pencocokan tepat dari shapefile. Sayangnya, karena kekhasan data, urutan nama tidak cocok, jadi ini masih memerlukan beberapa input manual. Saya berharap untuk semacam solusi yang sepenuhnya otomatis (jika itu mungkin).
sumber
Jawaban:
Saya akan pergi untuk
stringdist
paket yang telah mengimplementasikan banyak algoritma untuk menghitung kesamaan parsial (jarak) dari string termasukJaro-winkler
. Inilah solusi cepat untuk Anda:itu output:
Anda dapat bermain dengan parameter maxDist dari metode amatch. Meskipun 3 berfungsi terbaik dengan data sampel Anda!
sumber
arm.data
kearm@data
dan itu akan bekerja dengan baik.arm@data
, itu akan membuat kekacauan besar (catatan tidak cocok dengan geometri yang benar)Saya ingin menambahkan beberapa detail pada jawaban Farid Cher karena ini adalah masalah yang sangat umum. Menggunakan
amatch
dapat melakukan keajaiban, tetapi denganSpatial
benda - benda ini Anda tidak boleh menggunakanbase::merge
dan tidak mengakses@data
slot. Itu pasti akan menyebabkan kekacauan yang mengerikan (base::merge
mengubah urutan catatan, dan mereka tidak lagi cocok dengan geometri).Sebagai gantinya, gunakan
sp::merge
metode ini, dengan menggunakanSpatialPolygonsDataFrame
argumen pertama dimerge
. Perhatikan juga potensi masalah memiliki duplikat catatan. Dan saya menambahkan data sehingga contohnya mandiri dan dapat direproduksi.Ini
gagal dengan pesan
Karena ada dua catatan untuk "Aragatsotn" di
df
. Anda bisa melakukannyaTapi biasanya pendekatan waras adalah menggunakan sesuatu seperti
Sekarang, penggabungan tidak berfungsi dengan baik dalam hal ini karena nama tidak cocok. Jadi bisa digunakan
Hampir di sana, tetapi "Yerevan City" tidak cocok dengan "Erevan". Dalam hal ini Anda dapat meningkat
maxDist
Tetapi meningkatkan
maxDist
tidak akan selalu berhasil atau memberikan kecocokan yang salah karena nama varian bisa sangat berbeda. Jadi dalam banyak kasus Anda akhirnya akan melakukan beberapa penggantian manual seperti:Dalam kedua kasus diikuti oleh
Dalam hal apa pun Anda akan ingin memeriksa apakah
sum(table(i) > 1) == 0
; Meskipunmerge
harus gagal pula jika ada pertandingan duplikatsumber
merge
. Agregat spasial berguna untuk kasus yang berbeda (jika, dalam contoh ini,NAME_1
memiliki duplikat.)