2016-10-24 2 views
0

У меня есть два кадра данных: один из них содержит 0,8 миллиона строк с координатами x и Y, другой фрейм данных - 70000 строк с координатами X и Y. Я хочу знать логику и код в R, где я хочу связать точку данных от кадра 1 до ближайшей точки в кадре данных 2. Есть ли стандартный пакет для этого?Поиск ближайшей точки из другого фрейма данных

Я бегу в гнездо для цикла. Но это очень медленно, так как он получает итерацию на 0,8 миллиона * 70000 раз, что очень трудоемко.

Пожалуйста, помогите -

+1

Пожалуйста, добавьте некоторые данные (только фрагмент, например, используя 'dput (head (your_data))'), код и ожидаемый результат. – Jimbou

+0

Для геопространственных данных см. Http://stackoverflow.com/questions/31766351/calculating-the-distance-between-points-in-different-data-frames, для эвклидовой дистанции см. Http://stackoverflow.com/questions/26720367/how-to-find-the-distance-between-two-data-frames и http://stackoverflow.com/questions/22231773/calculating-the-euclidean-dist-between-each-row-of-a-dataframe -с-все-другой-ро. Я нашел их по googling для 'r рассчитать расстояние между двумя data.frames'. Также просматривайте другие хиты из этого поискового поиска Google, их уже достаточно много. –

ответ

2

я нашел более быстрый способ получить ожидаемый результат, используя data.table библиотеку:

library(data.table) 

time0 <- Sys.time() 

Вот некоторые случайные данные:

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

Предполагая, что (х , y) - координаты в ортонормированной системе координат, вы можете вычислить квадрат расстояния следующим образом:

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

И теперь вы можете применять эту функцию к данным, чтобы получить ожидаемый результат:

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

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

Это tooked меня около 30 минут, чтобы получить результат на медленном компьютере.

EDIT:

Как спросил, я попытался severals других решений с использованием sapply или с использованием adply из plyr пакета. Я тестировал эти решения на меньших кадрах данных, чтобы ускорить их работу.

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 

Первое решение кажется значительно быстрее, чем 2 других. Это более верно для более крупного набора данных.

+0

+1! В этом вопросе люди уже предлагают решения: http://stackoverflow.com/questions/22231773/calculating-the-euclidean-dist-between-each-row-of-a-dataframe-with-all-other-ro. Мне было бы очень интересно увидеть, как вы решаете тарифы против них (я думаю, что это должно быть справедливо быстрее). –

+0

@PaulHiemstra Разве это не идеальный обман? – Frank

+0

@Frank Я не уверен, что решение, предлагаемое в другом посте, не может быть адаптировано к кадрам данных с этим размером ... – Hugo

Смежные вопросы