Ich habe ein nerviges Problem, für das ich eine automatisierte Lösung finden möchte. Die Kurzfassung ist, dass ich ein Shapefile und eine Tabelle mit erstellten Daten für Regionen innerhalb von Ländern habe. Die erstellte Datentabelle enthält KEINE standardisierten GIDs / Admin-Codes, die mit Shapefiles übereinstimmen, und die Regionsnamen stimmen auch nicht genau überein. Lasst uns genauer hinschauen; Hier ist mein Dummy-Datenrahmen + Shapefile.
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)
Ich habe also eine Tabelle mit scheinbar zufälligen IDs, Regionsnamen und einem Wert, der mit einer Choroplethenkarte aufgezeichnet werden soll. Sieht aus wie das:
> 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
Wenn wir uns die interessanten Shapefile-Attribute ansehen, haben wir Folgendes:
> 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
Idealerweise df
würde eine Art übereinstimmender Administrator-IDs enthalten sein, um sie mit dem Shapefile zu verbinden. Wer auch immer die von mir verwendeten Daten erstellt hat, hat diese Konventionen leider nicht befolgt. Alternativ wäre es großartig, die Regionsnamen selbst abzugleichen ... aber wie Sie sehen können, gibt es bei jedem Namen geringfügige Abweichungen.
Matching per Hand ist immer eine Backup-Lösung, aber wer möchte sich die Zeit dafür nehmen? ;) Aber abgesehen von Faulheit wird das Projekt, an dem ich arbeite, Dutzende und Dutzende verschiedener Länder abbilden. Deshalb suche ich nach einer automatisierten Lösung, die alles kann, ohne etwas von Hand tun zu müssen. Ist das möglich? Kann ich diese fast Regionsnamen irgendwie mit den Shapefiles abgleichen?
Nebenbemerkung: Ich suche nach Teilzeichenfolgenübereinstimmungen grepl
für diesen Beitrag , bin mir aber nicht sicher, ob dies eine mögliche Lösung ist, da ich aus den Spaltennamen ziehen muss, anstatt jeden Regionsnamen manuell einzugeben .
BEARBEITEN: Wenn ich die IDs von Hand abgleichen möchte, habe ich eine neue Spalte in meinem Datenrahmen erstellt und die genau übereinstimmenden Begriffe aus dem Shapefile hinzugefügt. Aufgrund der Besonderheiten der Daten stimmt die Reihenfolge der Namen leider auch nicht überein, sodass noch einige manuelle Eingaben erforderlich sind. Ich hoffe auf eine vollständig automatisierte Lösung (wenn es überhaupt möglich ist).
quelle
Antworten:
Ich würde mich für ein
stringdist
Paket entscheiden, das viele Algorithmen implementiert hat, um die partielle Ähnlichkeit (Entfernung) von Strings einschließlich zu berechnenJaro-winkler
. Hier ist eine schnelle Lösung für Sie:es gibt aus:
Sie können mit dem Parameter maxDist der amatch-Methode spielen. Obwohl 3 am besten mit Ihren Beispieldaten funktioniert!
quelle
arm.data
zuarm@data
und es würde gut funktionieren.arm@data
, das würde ein großes Durcheinander verursachen (Datensätze, die nicht ihren korrekten Geometrien entsprechen)Ich möchte Farid Chers Antwort einige Details hinzufügen, da dies ein sehr häufiges Problem ist. Die Verwendung
amatch
kann Wunder bewirken, aber mit diesenSpatial
Objekten sollten Sie den Steckplatz nicht verwendenbase::merge
und nicht darauf zugreifen@data
. Das würde unweigerlich zu einem schrecklichen Durcheinander führen (base::merge
ändert die Reihenfolge der Datensätze und sie würden nicht mehr mit den Geometrien übereinstimmen).Verwenden Sie stattdessen die
sp::merge
Methode, indem Sie dasSpatialPolygonsDataFrame
erste Argument in verwendenmerge
. Beachten Sie auch das potenzielle Problem, dass Datensätze dupliziert wurden. Und ich habe Daten hinzugefügt, damit das Beispiel in sich geschlossen und reproduzierbar ist.Diese
schlägt mit Nachricht fehl
Weil es zwei Datensätze für "Aragatsotn" in gibt
df
. Du könntest es tunAber normalerweise besteht der vernünftige Ansatz darin, etwas Ähnliches zu verwenden
Jetzt funktioniert das Zusammenführen in diesem Fall nicht gut, da die Namen nicht übereinstimmen. So können Sie verwenden
Fast da, aber "Yerevan City" passte nicht zu "Erevan". In diesem Fall können Sie erhöhen
maxDist
Das Erhöhen
maxDist
funktioniert jedoch nicht immer oder führt zu falschen Übereinstimmungen, da Variantennamen sehr unterschiedlich sein können. In vielen Fällen werden Sie am Ende einige manuelle Ersetzungen vornehmen, wie z.In beiden Fällen gefolgt von
In jedem Fall möchten Sie überprüfen, ob
sum(table(i) > 1) == 0
; obwohlmerge
sollte auf jeden Fall fehlschlagen , wenn es doppelte Streichhölzer.quelle
merge
. Das räumliche Aggregat ist für verschiedene Fälle nützlich (wenn in diesem BeispielNAME_1
Duplikate vorhanden waren)