2016-08-02 10 views
1

Ich habe einen Datenrahmen (df), der die Breiten- und Längenkoordinaten (Lat, Long) sowie die Tiefe (Tiefe) einer Temperaturmessung für jeden Eintrag enthält. Im Wesentlichen hat jeder Eintrag (x, y, z) = (Lat, Long, Depth) eine Ortsinformation für jede Temperaturmessung.R: Finde Duplikate, die innerhalb eines bestimmten Wertes liegen

Ich versuche, die Daten zu bereinigen, indem doppelte Messorte gefunden und entfernt werden. Der einfache Teil ist das Entfernen der genauen Duplikate, als solche behandelt:

df = df[!(duplicated(df$Lat) & duplicated(df$Long) & duplicated(df$Depth)),] 

aber das Problem ist, dass die Werte von lat/long für einige Einträge sind nur leicht ab, den obigen Code Bedeutung wird nicht Fange sie, aber sie sind immer noch eindeutig dupliziert (zB lat = 39,252880 & lat = 39,252887).

Gibt es eine Möglichkeit, Duplikate zu finden, die innerhalb eines bestimmten absoluten oder prozentualen Anteils der ersten Instanz liegen?

Ich schätze jede Hilfe, danke!

+4

Sie könnten alle Werte auf die von Ihnen bevorzugte Toleranz runden und dann nach Duplikaten suchen. In Ihrem Beispiel würde das Runden auf drei Dezimalstellen den Breitengrad = 39,253 für beide Punkte ergeben. Oder vielleicht wäre es sinnvoller, den räumlichen Abstand zwischen den einzelnen Messungen zu berechnen und Gruppen von Punkten zu finden, die sich in einem kritischen Abstand zueinander befinden. Suchen Sie dann in diesen Clustern nach Zeilen mit derselben Tiefe und mitteln Sie diese. Siehe [diese SO-Antwort] (http://stackoverflow.com/a/21006437/496488), um die räumlichen Abstände zu finden und Punktecluster zu identifizieren. – eipi10

+0

Bei der ersten Methode können Sie Ihren Code verkürzen: 'df.new = df [! Duplicated (rund (df [, c (" lat "," long "," depth ")], 3)),]'. – eipi10

Antwort

0

Basierend auf dieser post war ich in der Lage, eine Lösung zu finden. Ich habe die Funktion modifiziert, um eine engere Toleranz für "Duplikate" auf 0,001 zu haben, ansonsten ist die Funktion unverändert. Die Anwendung ändert sich jedoch leicht auf:

output=data.frame(apply(dataDF,2,fun)) 

denn ich wollte die Werte innerhalb einer Spalte vergleichen, anstatt in einer einzigen Zeile.

fortzusetzen, habe ich dann für die spätere Verwendung künstliche Indizes zu meinem Ausgangsdatenrahmen hinzufügen:

output$ind = 1:nrow(output) 

Der Hauptteil der Zeilenindizes zu finden, wo die Funktion TRUE für die drei Standortinformationsfelder zurückgegeben (lat, lang, tief). Der folgende Code findet die Indizes, bei denen alle drei wahr waren, erstellt einen temporären Datenrahmen mit nur diesen Einträgen (noch logische), findet die Indizes der Duplikate und kehrt sie dann um, um die Indizes zurückzugeben, die aus dem vollständigen, ursprünglichen Datensatz entfernt werden (entschuldige die schlechten Variablennamen):

ind = which(with(output,(Lat=='TRUE' & Long=='TRUE' & Depth=='TRUE'))) 
temp = dataDF[ind,] 
temp$ind = ind 
ind2 = duplicated(temp[,1:3]) 
rem = ind[ind2] 

df.final = dataDF[-rem,] 

Hoffentlich hilft das! Es ist ein wenig kompliziert und die Funktion ist sehr langsam für große Datensätze aber es wird die Arbeit erledigt.

Verwandte Themen