我有一个数据框,其中包含UTM(Universal Transverse Mercator)坐标中的地点列表及其地理位置。
它看起来像这样:
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
应该是一个返回接近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
答案 0 :(得分:2)
您还可以使用sp::spDists
返回距离矩阵,然后找到符合条件的每列/行的元素。
例如:
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
答案 1 :(得分:0)
我认为你需要交叉加入 Place坐标。这样做的原因是任何一对地方可能是最近邻居,并且假设你没有可以排除某些对的任何先验信息,你需要检查所有这些。
获取数据框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]))
现在您需要做的就是找到每对地方的最小距离。