我有两个数据集,一个有 488,286 行以及经度和纬度坐标,另一个有 245,077 行以及经度和纬度坐标。第二个也有与坐标相关的其他数据。我想在第二个数据集中找到与第一个数据集中的所有点最接近的点。我无法共享原始数据,因此为了简单起见,我将在此处生成一些随机点:
df1<-cbind(runif(488286,min=-180, max=-120), runif(488286, min=50, max=85))
df2<-cbind(runif(245077,min=-180, max=-120), runif(245077, min=50, max=85))
我尝试只使用 distm 函数,但数据太大,所以我尝试像这样分解它:
library(geosphere)
closest<-apply(df1, 1, function(x){
mat<-distm(x, df2, fun=distVincentyEllipsoid)
return(which.min(mat))
})
我认为这有效,但运行时间太长,以至于我实际上还没有看到结果(仅尝试使用数据子集(。我真的需要一种更快的方法来做到这一点,因为我让它运行了 2 天,但它没有完成。它不必使用 distm,只需使用任何更快、更准确的方法即可。
提前感谢!
也许这对你有用:
library(sf)
library(RANN)
df1<-data.frame("lon" = runif(2000,min=-180, max=-120), "lat" = runif(2000, min=50, max=85))
df2<-data.frame("lon" = runif(1430,min=-180, max=-120), "lat" = runif(1430, min=50, max=85))
df1_sf <- st_as_sf(df1, coords = c("lon", "lat"),
crs = 4326, agr = "constant")
df2_sf <- st_as_sf(df2, coords = c("lon", "lat"),
crs = 4326, agr = "constant")
nearest <- nn2(df2_sf, df1_sf, k = 1, treetype = 'bd', searchtype = 'priority')
df2_sf[nearest$nn.idx,]
RANN
是 C++ 中 nn-Library 的包装器,所以它应该很快。尽管如此,我还是减少了这个答案的分数。
首先,我将df1
和df2
转换为sf
对象。然后我将它们输入到nn2
算法,这是一个knn算法并返回一个列表。列表中nn.idx
向量包含df2
中每个点的索引 df1
中每个点。
更新:您还可以并行化
library(parallel)
c4 <- parallel::makeCluster(4)
df1_split <- split(df1_sf, cut(1:nrow(df1_sf), 4, labels = FALSE))
clusterExport(c2, "df2_sf")
clusterEvalQ(c2, library(RANN))
system.time(
idxlist_parallel <- clusterApply(c2, df1_split,
function(x) nn2(df2_sf, x, k = 1, treetype = 'bd', searchtype = 'priority'))
)