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.
Bitte fügen Sie einige Daten (nur ein Ausschnitt, z. B. mit 'dput (Kopf (Ihre_Daten))'), Code und Ihre erwartete Ausgabe. – Jimbou
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. –