2016-05-05 6 views
1

Ich versuche, zwei Datensätze, die GPS-Koordinaten enthalten, so dass ich mit einem Dataset mit Variablen aus beiden Datensätze zusammengeführt bin. Ich versuche, eine Funktion zu verwenden, um dies zu erreichen. Das Problem ist, dass die GPS-Koordinaten von beiden Datensätzen nicht genau übereinstimmen. Die Aufgabe besteht also darin, die Variablen eines Datensatzes mit den Variablen des anderen Datensatzes zu vergleichen, indem die engste Paarung der GPS-Koordinaten gefunden wird.Versuchen, eine Funktion zu erstellen, um zwei Datensätze durch die nächstgelegene GPS-Koordinate zu verbinden

Ich hatte Erfolg mit dem Fuzzy-Join-Paket, konnte aber nur teilweise Übereinstimmung (~ 75%) erhalten. Mit der unten stehenden Funktion hoffte ich, einen höheren Übereinstimmungsgrad zu erreichen. Ein Datensatz ist kürzer als der andere, daher bestand die Idee darin, zwei for-Schleifen zu verwenden, wobei jede for-Schleife durch jeden Datensatz geht.

Ein "Anker" (Abstand zwischen den ersten Beobachtungen beider Datensätze) wird festgelegt, so dass der neue (kürzere) Abstand der neue Anker wird, wenn der Abstand zwischen den beiden Punkten kleiner als der Anker ist. Die for-Schleife wird fortgesetzt, bis die kürzeste Entfernung gefunden wurde, und die Variablen aus beiden Datensätzen werden an das Ende eines neuen Datensatzes angehängt, der hier als pairedData bezeichnet wird. Ich sollte mit einem Datensatz belassen werden, solange der kürzeste Datensatz (6314 Zeilen) mit Daten aus beiden Datensätzen verwendet wurde.

Ich denke, die Funktion sollte funktionieren, aber rbind() ist super langsam, und ich habe Probleme bei der Implementierung von rbindlist(). Irgendwelche Ideen, wie ich das erreichen könnte?

combineGPS <- function(harvest,planting) { 
require(sp) 
require(data.table) 
longH <- harvest$long 
latH <- harvest$lat 
longP <- planting$long 
latP <- planting$lat 
rowsH <- nrow(harvest) 
rowsP <- nrow(planting) 
harvestCoords <- cbind(longH,latH) 
harvestPoints <- SpatialPoints(harvestCoords) 
plantingCoords <- cbind(longP,latP) 
plantingPoints <- SpatialPoints(plantingCoords) 

#planting Daten kürzer als Erntedaten

#need jede Reihe von Pflanzdaten zu nehmen (6314) und am nächsten Ernte Datenpunkt (16626) finden, dann bringen

anchor <- spDistsN1(plantingPoints[1,],harvestPoints[1,],longlat=FALSE) 
pairedData <- data.frame(long=numeric(), 
       lat=numeric(), 
       variety=factor(), 
       seedling_rate=numeric(), 
       seed_spacing=numeric(), 
       speed=numeric(), 
       yield=numeric(), 
       stringsAsFactors=FALSE) 

for (p in 1:rowsP){ 
    for (h in 1:rowsH){ 

    if(spDistsN1(plantingPoints[p,],harvestPoints[h,],longlat=FALSE) <= anchor){ 
    anchor <- spDistsN1(plantingPoints[p,],harvestPoints[h,],longlat=FALSE) 
    pairedData[p,]<-c(planting[p,]$long, planting[p,]$lat, planting[p,]$variety, planting[p,]$seedling_rate, planting[p,]$seed_spacing, planting[p,]$speed, harvest[h,]$yield) 
    }  

     } 
    } 
    return(pairedData) 
} 
doesItWork=combineGPS(harvest,planting) 
doesItWork 

Antwort

0

Wenn ich Ihre Frage richtig verstehe, bin ich nicht sicher, warum Sie die for Schleife über die Erntedaten benötigen. Die Funktion spDistsN1 gibt eine Matrix der Abstände zum angegebenen Punkt zurück. Ich denke, Sie sollten Ihre Erntedaten als pts und die Pflanzdaten als pt Eingang für diese Funktion verwenden, und dann finden Sie den Index mit der kürzesten Entfernung zu jedem pt. Nur die Pflanzdaten überstreichen. Spart viel Zeit. Geben Sie auch longlat in spDistsN1 nicht an, da Ihre Daten SpatialPoints sind und die Funktion nicht angibt, dass diese Objekte angegeben werden sollen.

Beispiel Loop:

for (p in 1:rowsP){ 
    #Get the distance from the pth planting point to all of the havest points 
    Dists <- spDistsN1(pts = harvestPoints, pt = plantingPoints[p,]) 

    #Find the index of the nearest harvest point to p. This is the minimum of Dists. (Note that there may be more than one minimum) 
    NearestHarvest <- which(Dists == min(Dists)) 

    #Add information to the paired data 
    pairedData[p,]<-c(planting[p,]$long, planting[p,]$lat, planting[p,]$variety, planting[p,]$seedling_rate, planting[p,]$seed_spacing, planting[p,]$speed, harvest[NearestHarvest,]$yield) 
    } 

Lassen Sie mich wissen, ob dies ist, was Sie suchen.

Sie können auch den Datenrahmen pairedData mit den Pflanzdaten initialisieren und in der Schleife for nur die Ernteertragsdaten in den Datenrahmen pairedData einfügen. Dies spart Ihnen auch einige Zeit in der Schleife.

0

Sie müssen jede Zeile in der Erntedatei (16626) einer Reihe in der Pflanzdatei (6314) zuordnen und nicht umgekehrt. Das Bild unten zeigt die Koordinaten der Ernte- und Pflanzengps auf einer xy-Ebene. Die roten Punkte sind die Harvesterpunkte.

Planter Harvester GPS

Die Präzisionslandmaschine ist eine mehrreihige Pflanzer & Harvester. Das GPS-Gerät ist in der Maschine untergebracht. d.h.Jeder GPS-Punkt bezieht sich auf viele Reihen von Erntegut. In diesem Fall deckt der Blumenkübel 2X Reihen im Vergleich zur Erntemaschine pro Fahrt ab. Dies erklärt, warum die Erntedatei ~ 2X + Datenpunkte hat.

Der grundlegende Ansatz wäre Brute-Force-Suche, da die GPS-Koordinaten nicht zwischen den Dateien überlappen. Ich habe das in R und Python gelöst, indem ich das gesamte Feld in kleinere einheitliche Gitter segmentierte und die Suche auf die nächsten benachbarten Gitter beschränkte. In Bezug auf die Effizienz dauert es ~ 3-4 Minuten zu lösen und hat einen Durchschnitt von ~ 3 Metern als der Abstand zwischen den Pflanz- und Erntepunkten, was vernünftig ist.

Sie können den Code auf meinem Github

finden
Verwandte Themen