查找哪些点在每个点的给定距离内

Find which points are within a given distance of each point

我有一个数据框,其中包含 UTM(通用横轴墨卡托)坐标中的地点及其地理位置列表。

看起来像这样:

Place    X_UTM   Y_UTM
    1 574262.0 6140492
    2 571251.2 6141669
    3 570841.9 6142535
    4 570233.8 6141213
    5 578269.2 6140304
    6 575067.1 6137444

我想为每个地方(数据框的每一行)识别其他哪些地方在给定的欧氏距离内。在这种情况下,我想找到哪些地方比 1 公里更近。

我试过这样的事情:

foo <- function(x, y) dist(c(x, y), method = "euclidian") < 1000

这应该是一个函数,returns 距离小于 1000 米的点。那么:

x <- lapply(df(,c(i, x, y)), FUN = foo)

其中 i"Place"x"X_UTM"y"Y_UTM"。这根本不起作用。

我之后的输出应该是这样的(不是从上面给出的数字中获得的):

# Place Closest
#     1    2, 5
#     2       1
#     3      NA
#     4       5
#     5    1, 4
#     6      NA

我认为您将需要 cross join 地点坐标。这样做的原因是任何一对 Places 都可能是最近的邻居,并且假设您没有任何可以排除某些对的先验信息,您需要检查所有这些。

获取数据框 df 交叉连接的一种方法是将其与自身合并,将 by = NULL 作为参数设置到 merge:

df.cross <- merge(x = df, y = df, by = NULL)
df.cross$distance <- apply(df.cross[, c('X_UTM.x', 'X_UTM.y', 'Y_UTM.x', 'Y_UTM.y')],
      1,
      function(x) dist(x[1], x[2], x[3], x[4]))

现在您需要做的就是找到每对地点的最小距离。

你也可以用sp::spDists到return一个距离矩阵,然后找到每个column/row满足你条件的元素

例如:

d <- read.table(text='Place   X_UTM        Y_UTM
1       574261.98   6140492.13
2       571251.23   6141669.26
3       570841.92   6142534.86
4       570233.75   6141212.5
5       578269.25   6140303.78
6       575067.07   6137444.36', header=TRUE)
library(sp) 
i <- apply(spDists(as.matrix(d[, c('X_UTM', 'Y_UTM')])), 2, 
           function(x) paste(which(x < 1000 & x != 0), collapse=', '))

data.frame(Place=d$Place, Closest=i)

##   Place Closest
## 1     1        
## 2     2       3
## 3     3       2
## 4     4        
## 5     5        
## 6     6