Ich mache eine Trajektorienanalyse mit R und PostgreSQL. Um Gruppen von Trajektoriensegmenten zu bilden, in denen aufeinanderfolgende Positionen räumlich-zeitlich nahe sind, habe ich die folgende Tabelle erstellt. Was mir noch fehlt ist die Spalte group_id
, worum geht es in meiner Frage.Bilden von Gruppen von räumlich-zeitlich nahen Trajektorien in R oder PostgreSQL
bike_id1 datetime bike_id2 near group_id
1 2016-05-28 11:00:00 2 TRUE 1
1 2016-05-28 11:00:05 2 TRUE 1
1 2016-05-28 11:00:10 2 FALSE NA
[...]
2 2016-05-28 11:00:05 3 TRUE 1
2 2016-05-28 11:00:10 3 TRUE 1
Dies ist das Ergebnis von Mehrfachvergleiche zwischen jeder Trajektorie mit jedem anderen (alle Kombinationen ohne Wiederholungen) und eine innere Verknüpfung auf datetime
(immer auf ein Vielfaches von 5 Sekunden abgetastet). Es zeigt, dass für bestimmte Positionen Fahrrad 1 und 2 gleichzeitig abgetastet wurden und räumlich nahe beieinander liegen (eine beliebige Schwelle).
Jetzt möchte ich einzigartige IDs für die Segmente geben, wo zwei Fahrräder räumlich-zeitlich nahe sind (group_id
). Hier stecke ich fest: Ich möchte die group_id
Gruppen mit mehreren Trajektorien zu respektieren. Die Methode zum Zuweisen der group_id
sollte erkennen, dass, wenn Fahrrad 1 und 2 in einer Gruppe unter 2016-05-28 11:00:05
sind, dann 3 zu der gleichen Gruppe gehört, wenn es in der Nähe von 2 bei demselben Zeitstempel ist (2016-05-28 11:00:05
).
Gibt es Tools in R oder PostgreSQL, die mir bei dieser Aufgabe helfen würden? Eine Schleife durch den Tisch zu führen, scheint der falsche Weg zu sein.
EDIT: Wie @wildplasser darauf hingewiesen, dies scheint ein Lücke-und-Inseln Problem zu sein, die traditionell unter Verwendung von SQL gelöst. Er hat freundlicherweise einige Beispieldaten erstellt, die ich etwas erweitert habe und in die Frage einbeziehen werde.
CREATE TABLE nearness
-- (seq SERIAL NOT NULL UNIQUE -- surrogate for conveniance
(bike1 INTEGER NOT NULL
, bike2 INTEGER NOT NULL
, stamp timestamp NOT NULL
, near boolean
, PRIMARY KEY(bike1,bike2,stamp)
);
INSERT INTO nearness(bike1,bike2,stamp,near) VALUES
(1,2, '2016-05-28 11:00:00', TRUE)
,(1,2, '2016-05-28 11:00:05', TRUE)
,(1,2, '2016-05-28 11:00:10', TRUE)
,(1,2, '2016-05-28 11:00:20', TRUE) -- <<-- gap here
,(1,2, '2016-05-28 11:00:25', TRUE)
,(1,2, '2016-05-28 11:00:30', FALSE)
,(4,5, '2016-05-28 11:00:00', FALSE)
,(4,5, '2016-05-28 11:00:05', FALSE)
,(4,5, '2016-05-28 11:00:10', TRUE)
,(4,5, '2016-05-28 11:00:15', TRUE)
,(4,5, '2016-05-28 11:00:20', TRUE)
,(2,3, '2016-05-28 11:00:05', TRUE) -- <<-- bike 1, 2, 3 are in one grp @ 11:00:05
,(2,3, '2016-05-28 11:00:10', TRUE) -- <<-- no group here
,(6,7, '2016-05-28 11:00:00', FALSE)
,(6,7, '2016-05-28 11:00:05', FALSE)
;
Sie müssen die Lücken erkennen, so dass Sie zuerst definieren müssen, was eine Lücke ist. Danach können Sie die Nicht-Lücken aufzählen. – wildplasser
Sie meinen, mit Cumsum in Übereinstimmung mit [dieser Methode] (http://stackoverflow.com/a/36064324/4139249) verwenden? Der Kern des Problems würde dann immer noch bestehen bleiben: Wie kann man den Fall aufzählen und trotzdem beachten, wo eine 'bike_id'-' datetime'-Kombination bereits einer Gruppe zugewiesen wurde (besonders da die 'bike_id' in der Spalte' bike_id1' liegen kann) oder 'bike_id2') – Ratnanil
Der * natürliche Schlüssel * für Ihre Umgebung/Assoziationstabelle scheint {bike_id1, bike_id2, datetime} zu sein. Ihr" segments "-Ergebnis hat {bike_id1, bike_id2, anfintime (-> endtime)} als Schlüssel . Sie können diese aufzählen (nachdem Sie sie erkannt haben), auch wenn sie sich überlappen ["Cumsum": Entschuldigung, ich lese nicht R] – wildplasser