2016-10-24 2 views
0

Ich habe zwei Datenrahmen, einer ist mit 0,8 Millionen Reihen mit x und Y Koordinaten, ein anderer Datenrahmen ist von 70000 Reihen mit X und Y Koordinaten. Ich möchte Logik und Code in R wissen, wo ich den Datenpunkt von Bild 1 mit dem nächsten Punkt in Datenrahmen 2 verknüpfen möchte. Gibt es ein Standardpaket dafür?Den nächsten Punkt von anderen Datenrahmen finden

Ich bin für die Schleife geschachtelt. Aber das ist sehr langsam, da es für 0,8 Millionen * 70000 iteriert wird, was sehr zeitaufwendig ist.

Bitte helfen -

+1

Bitte fügen Sie einige Daten (nur ein Ausschnitt, z. B. mit 'dput (Kopf (Ihre_Daten))'), Code und Ihre erwartete Ausgabe. – Jimbou

+0

Geodaten finden Sie unter http://stackoverflow.com/questions/31766351/calculating-the-distance-between-points-in-different-data-frames, für die euklidische Distanz siehe http://stackoverflow.com/questions/26720367/how-to-find-the-Abstand zwischen zwei Datenrahmen und http://stackoverflow.com/questions/22231773/calculating-the-euclidean-dist-between-each-row-of-a-dataframe -mit-allen-anderen-ro. Ich habe diese gefunden, indem ich nach googlen, um die Entfernung zwischen zwei Datenfeldern zu berechnen. Schau dir auch die anderen Hits aus der Google-Suche an, da ist schon einiges dabei. –

Antwort

2

fand ich einen schnellen Weg, um das erwartete Ergebnis mit der data.table Bibliothek zu erhalten:

library(data.table) 

time0 <- Sys.time() 

Hier einige Zufallsdaten:

df1 <- data.table(x = runif(8e5), y = runif(8e5)) 
df2 <- data.table(x = runif(7e4), y = runif(7e4)) 

Unter der Annahme, (x , y) sind die Koordinaten in einem orthonormalen Koordinatensystem, Sie können das Quadrat der Entfernung wie folgt berechnen:

dist <- function(a, b){ 
       dt <- data.table((df2$x-a)^2+(df2$y-b)^2) 
       return(which.min(dt$V1))} 

Und jetzt können Sie diese Funktion auf Ihre Daten angewandt, um das erwartete Ergebnis zu erhalten:

results <- df1[, j = list(Closest = dist(x, y)), by = 1:nrow(df1)] 

time1 <- Sys.time() 
print(time1 - time0) 

Es tooked mich etwa 30 Minuten das Ergebnis auf einem langsamen Computer zu bekommen.

EDIT:

Als gefragt, ich habe severals andere Lösungen versucht, mit sapply oder mit adply aus dem plyr Paket. Ich habe diese Lösungen auf kleineren Datenrahmen getestet, um es schneller zu machen.

library(data.table) 
library(plyr) 
library(microbenchmark) 

######################## 
## Test 1: data.table ## 
######################## 

dt1 <- data.table(x = runif(1e4), y = runif(1e4)) 
dt2 <- data.table(x = runif(5e3), y = runif(5e3)) 

dist1 <- function(a, b){ 
       dt <- data.table((dt2$x-a)^2+(dt2$y-b)^2) 
       return(which.min(dt$V1))} 

results1 <- function() return(dt1[, j = list(Closest = dist1(x, y)), by = 1:nrow(dt1)]) 

################### 
## Test 2: adply ## 
################### 

df1 <- data.frame(x = runif(1e4), y = runif(1e4)) 
df2 <- data.frame(x = runif(5e3), y = runif(5e3)) 

dist2 <- function(df){ 
       dt <- data.table((df2$x-df$x)^2+(df2$y-df$y)^2) 
       return(which.min(dt$V1))} 

results2 <- function() return(adply(.data = df1, .margins = 1, .fun = dist2)) 

#################### 
## Test 3: sapply ## 
#################### 

df1 <- data.frame(x = runif(1e4), y = runif(1e4)) 
df2 <- data.frame(x = runif(5e3), y = runif(5e3)) 

dist2 <- function(df){ 
       dt <- data.table((df2$x-df$x)^2+(df2$y-df$y)^2) 
       return(which.min(dt$V1))} 

results3 <- function() return(sapply(1:nrow(df1), function(x) return(dist2(df1[x,])))) 

microbenchmark(results1(), results2(), results3(), times = 20) 

#Unit: seconds 
#  expr  min  lq  mean median  uq  max neval 
# results1() 4.046063 4.117177 4.401397 4.218234 4.538186 5.724824 20 
# results2() 5.503518 5.679844 5.992497 5.886135 6.041192 7.283477 20 
# results3() 4.718865 4.883286 5.131345 4.949300 5.231807 6.262914 20 

Die erste Lösung scheint deutlich schneller zu sein als die beiden anderen. Dies gilt umso mehr für einen größeren Datensatz.

+0

+1! In dieser Frage schlagen Leute bereits Lösungen vor: http://stackoverflow.com/questions/22231773/calculating-the-euclidean-dist-between-each-row-of-a-dataframe-with-all-other-ro. Ich würde sehr daran interessiert sein zu sehen, wie Sie gegen diese Lösungen vorgehen (ich denke, es sollte ein bisschen schneller sein). –

+0

@PaulHiemstra Ist es nicht eine perfekte Betrogene? – Frank

+0

@Frank Ich bin mir nicht sicher, wie die im anderen Post vorgeschlagene Lösung möglicherweise nicht an Datenrahmen mit dieser Größe angepasst werden kann ... – Hugo

Verwandte Themen