R 查找两个大型数据集之间的最近坐标

R 查找两个大型数据集之间的最近坐标,r,dataframe,geospatial,nearest-neighbor,R,Dataframe,Geospatial,Nearest Neighbor,我的目标是根据两个数据集中的坐标确定数据集2中与数据集1中每个条目最近的条目。数据集1包含180000行(仅1800个唯一坐标),数据集2包含4500行(完整4500个唯一坐标) 我试图复制stackoverflow上类似问题的答案。例如: 但是,这些并不能以我想要的方式解决问题(它们要么连接数据帧,要么检查单个数据帧内的距离) 和中的解决方案是迄今为止我找到的最接近的解决方案 我在这篇文章中遇到的问题是,它计算出了单个数据帧内坐标之间的距离,我无法理解在RANN::nn2中更改哪些参数来跨

我的目标是根据两个数据集中的坐标确定数据集2中与数据集1中每个条目最近的条目。数据集1包含180000行(仅1800个唯一坐标),数据集2包含4500行(完整4500个唯一坐标)

我试图复制stackoverflow上类似问题的答案。例如:

但是,这些并不能以我想要的方式解决问题(它们要么连接数据帧,要么检查单个数据帧内的距离)

和中的解决方案是迄今为止我找到的最接近的解决方案

我在这篇文章中遇到的问题是,它计算出了单个数据帧内坐标之间的距离,我无法理解在
RANN::nn2
中更改哪些参数来跨两个数据帧进行更改

不起作用的建议代码:

library(RANN)
dataset1[,4]<- nn2(data=dataset1, query=dataset2, k=2)
数据: r详细信息

数据集1输入(未缩小到唯一坐标)

数据集2输入


我写了一个关于这个的答案。该功能经过修改,可用于报告距离并避免硬编码。请注意,它计算欧几里德距离


您可以使用
RANN::nn2
,但需要确保使用正确的语法。以下作品

as.data.frame(RANN::nn2(df2[,c(2,3)],df1[,c(2,3)],k=1))

我写了一个关于这个的答案。该功能经过修改,可用于报告距离并避免硬编码。请注意,它计算欧几里德距离


您可以使用
RANN::nn2
,但需要确保使用正确的语法。以下作品

as.data.frame(RANN::nn2(df2[,c(2,3)],df1[,c(2,3)],k=1))
资料

解决方案。注意“3:2”以获得“经度/纬度”,按该顺序

library(raster)

d <- pointDistance(x[,3:2], y[,3:2], lonlat=TRUE, allpairs=T) 
i <- apply(d, 1, which.min)

x$SRC_ID = y$SRC_ID[i]
x$distance = d[cbind(1:nrow(d), i)]
x

#   id HIGH_PRCN_LAT HIGH_PRCN_LON SRC_ID   distance
#1   1      52.88144     -2.873778     44   74680.48
#2   2      57.80945     -2.234544   5688  238553.51
#3   4      34.02335     -3.098445  61114  137385.18
#4   5      63.80879     -2.439163     23  340642.70
#5   6      53.68881     -7.396112     44  308458.73
#6   7      63.44628     -5.162345     23  256176.88
#7   8      21.60755     -8.633113    440  908292.28
#8   9      78.32444      3.813290     76 1064419.47
#9  10      66.85533     -3.994326     55  185119.29
#10  3      51.62354     -8.906553     54  251580.45
库(光栅)
d数据

解决方案。注意“3:2”以获得“经度/纬度”,按该顺序

library(raster)

d <- pointDistance(x[,3:2], y[,3:2], lonlat=TRUE, allpairs=T) 
i <- apply(d, 1, which.min)

x$SRC_ID = y$SRC_ID[i]
x$distance = d[cbind(1:nrow(d), i)]
x

#   id HIGH_PRCN_LAT HIGH_PRCN_LON SRC_ID   distance
#1   1      52.88144     -2.873778     44   74680.48
#2   2      57.80945     -2.234544   5688  238553.51
#3   4      34.02335     -3.098445  61114  137385.18
#4   5      63.80879     -2.439163     23  340642.70
#5   6      53.68881     -7.396112     44  308458.73
#6   7      63.44628     -5.162345     23  256176.88
#7   8      21.60755     -8.633113    440  908292.28
#8   9      78.32444      3.813290     76 1064419.47
#9  10      66.85533     -3.994326     55  185119.29
#10  3      51.62354     -8.906553     54  251580.45
库(光栅)

d如果它们是横向和纵向的,则需要考虑使用
geosphere::distHaversine
获得正确的距离。但是,找到最近的点就像答案中所建议的那样有效。如果它们是横向和纵向的,你需要考虑使用
geosphere::distHaversine
来获得正确的距离。但是找到最接近的点就像答案中建议的那样有效。
df1[,c(4,5)]谢谢你的解决方案,使用RANN::nn2的第二个版本工作得非常快,尽管有几十万行。您的评论中提供的snipbit似乎将用数据集2中最近条目的行号填充数据集1的第4列。您对如何将其修改为从数据集2输入SRC_ID值有何建议?@Kickball:
df1[,c(4,5)]谢谢您,成功地将SRC_ID分配给了数据集1。我应该在前面提到,但是你知道RANN:nn2是否有一个类似的函数,它使用理想的椭球/文森特距离或球面/哈弗斯距离?这对我的研究更有效。除了找到geosphere::distVincentyEllipsoid之外,我没有多少运气,但我不知道如何使代码适应不同的函数。如果您有任何想法,将不胜感激@Kickball刚离开我的办公室。如果我是你,我会发布另一个问题,参考这个解决方案,并询问如何为其他方法实现它。不幸的是,我脑子里没有答案,现在我正在用手机回复。祝您好运。
df1[,c(4,5)]感谢您提供的解决方案,使用RANN::nn2的第二个版本运行得非常快,尽管有几十万行。您的评论中提供的snipbit似乎将用数据集2中最近条目的行号填充数据集1的第4列。您对如何将其修改为从数据集2输入SRC_ID值有何建议?@Kickball:
df1[,c(4,5)]谢谢您,成功地将SRC_ID分配给了数据集1。我应该在前面提到,但是你知道RANN:nn2是否有一个类似的函数,它使用理想的椭球/文森特距离或球面/哈弗斯距离?这对我的研究更有效。除了找到geosphere::distVincentyEllipsoid之外,我没有多少运气,但我不知道如何使代码适应不同的函数。如果您有任何想法,将不胜感激@Kickball刚离开我的办公室。如果我是你,我会发布另一个问题,参考这个解决方案,并询问如何为其他方法实现它。不幸的是,我脑子里没有答案,现在我正在用手机回复。祝你好运。谢谢你的详细回复,包括可视化!不幸的是,当我在全尺寸数据集上运行您的代码时,以下错误被抛出
,感谢您的详细响应,包括可视化!不幸的是,当我针对全尺寸数据集运行代码时,在
I
library(data.table)
#Euclidean distance 
mydist <- function(a, b, df1, x, y){

          dt <- data.table(sqrt((df1[[x]]-a)^2 + (df1[[y]]-b)^2))

          return(data.table(Closest.V1  = which.min(dt$V1),
                            Distance    = dt[which.min(dt$V1)]))
           }

setDT(df1)[, j = mydist(HIGH_PRCN_LAT, HIGH_PRCN_LON, setDT(df2), 
                        "HIGH_PRCN_LAT", "HIGH_PRCN_LON"), 
                         by = list(id, HIGH_PRCN_LAT, HIGH_PRCN_LON)]
  #     id HIGH_PRCN_LAT HIGH_PRCN_LON Closest.V1 Distance.V1
  # 1:   1      52.88144     -2.873778          5   0.7990743
  # 2:   2      57.80945     -2.234544          8   2.1676868
  # 3:   4      34.02335     -3.098445         10   1.4758202
  # 4:   5      63.80879     -2.439163          3   4.2415854
  # 5:   6      53.68881     -7.396112          2   3.6445416
  # 6:   7      63.44628     -5.162345          3   2.3577811
  # 7:   8      21.60755     -8.633113          9   8.2123762
  # 8:   9      78.32444      3.813290          7  11.4936496
  # 9:  10      66.85533     -3.994326          1   1.9296370
  # 10:  3      51.62354     -8.906553          2   3.2180026
as.data.frame(RANN::nn2(df2[,c(2,3)],df1[,c(2,3)],k=1))
#    nn.idx   nn.dists
# 1       5  0.7990743
# 2       8  2.1676868
# 3      10  1.4758202
# 4       3  4.2415854
# 5       2  3.6445416
# 6       3  2.3577811
# 7       9  8.2123762
# 8       7 11.4936496
# 9       1  1.9296370
# 10      2  3.2180026
x = structure(list(id = c(1L, 2L, 4L, 5L, 
6L, 7L, 8L, 9, 10L, 3L), 
    HIGH_PRCN_LAT = c(52.881442267773, 57.8094538200198, 34.0233529, 
    63.8087900198, 53.6888144440184, 63.4462810678651, 21.6075544376207, 
    78.324442654172, 66.85532539759495, 51.623544596), HIGH_PRCN_LON = c(-2.87377812157822, 
    -2.23454414781635, -3.0984448341, -2.439163178635, -7.396111601421454, 
    -5.162345043546359, -8.63311254098095, 3.813289888829932, 
    -3.994325961186105, -8.9065532453272409), SRC_ID = c(NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA), distance = c(NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA)), row.names = c(NA, 10L), class = "data.frame")

y = structure(list(SRC_ID = c(55L, 54L, 23L, 11L, 44L, 21L, 76L, 
 5688L, 440L, 61114L), HIGH_PRCN_LAT = c(68.46506, 50.34127, 61.16432, 
 42.57807, 52.29879, 68.52132, 87.83912, 55.67825, 29.74444, 34.33228
 ), HIGH_PRCN_LON = c(-5.0584, -5.95506, -5.75546, -5.47801, -3.42062, 
 -6.99441, -2.63457, -2.63057, -7.52216, -1.65532)), row.names = c(NA, 
 10L), class = "data.frame")
library(raster)

d <- pointDistance(x[,3:2], y[,3:2], lonlat=TRUE, allpairs=T) 
i <- apply(d, 1, which.min)

x$SRC_ID = y$SRC_ID[i]
x$distance = d[cbind(1:nrow(d), i)]
x

#   id HIGH_PRCN_LAT HIGH_PRCN_LON SRC_ID   distance
#1   1      52.88144     -2.873778     44   74680.48
#2   2      57.80945     -2.234544   5688  238553.51
#3   4      34.02335     -3.098445  61114  137385.18
#4   5      63.80879     -2.439163     23  340642.70
#5   6      53.68881     -7.396112     44  308458.73
#6   7      63.44628     -5.162345     23  256176.88
#7   8      21.60755     -8.633113    440  908292.28
#8   9      78.32444      3.813290     76 1064419.47
#9  10      66.85533     -3.994326     55  185119.29
#10  3      51.62354     -8.906553     54  251580.45
plot(x[,3:2], ylim=c(0,90), col="blue", pch=20)
points(y[,3:2], col="red", pch=20)
for (i in 1:nrow(x)) {
    j <- y$SRC_ID==x$SRC_ID[i]
    arrows(x[i,3], x[i,2], y[j,3], y[j,2],length=.1) 
}

text(x[,3:2], labels=x$id, pos=1, cex=.75)
text(y[,3:2], labels=y$SRC_ID, pos=3, cex=.75)