R 找出与每个点在给定距离内的点
我有一个数据框,它有一个位置列表,以及它们在UTM(通用横向墨卡托)坐标系中的地理位置 它看起来像这样:R 找出与每个点在给定距离内的点,r,distance,lapply,euclidean-distance,R,Distance,Lapply,Euclidean Distance,我有一个数据框,它有一个位置列表,以及它们在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 foo <- function(x, y) dist(c(x,
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
foo <- function(x, y) dist(c(x, y), method = "euclidian") < 1000
我想确定,对于每个位置(数据帧的每一行),哪些其他位置在给定的欧几里德距离内。在这种情况下,我想找出哪些地方距离1公里以内
我试过这样的方法:
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
foo <- function(x, y) dist(c(x, y), method = "euclidian") < 1000
我想你需要交叉连接位置坐标。这样做的原因是,任何一对位置都可能是最近的邻居,并且假设您没有任何先验信息可以排除某些位置对,那么您需要检查所有位置对 获取数据帧
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]))
df.cross您还可以使用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)
d如果我不正确,请纠正我,但是距离函数不应该接受两个点,即两个x和两个y值吗?是的。我想计算每行之间的距离。这应该是所有行的sqr((X_UTM[1]-X_UTM[i])^2-(Y_UTM[1]-Y_UTM[i])^2),然后记录[i]小于1000的行。你能不能dst@user20650工作起来很有魅力!回答得很好。只需将as.data.frame添加到apply的结果中。谢谢。不客气。莱安德罗:你可能更喜欢stack
而不是as.data.frame
亲爱的@Tim Biegeleisen,谢谢你的回答。在运行您分享的脚本时,我遇到了以下问题:dist中的错误(x[1],x[2],x[3],x[4]):无效的距离方法您需要重新定义dist
函数,为两个笛卡尔点取两个x值和两个值。工作正常。只需补充一点,spDist在sp包中。非常感谢。dist
也可以正常工作,就像@user20650一样。此外,我的答案将无法返回任何重合点-即,任何距离为零的点都将被忽略。忽略“self”的更好方法是将对角线设置为NA
,如user20650的评论中所述。非常好,但是有没有一种方法可以可视化这些集群?事实上,它对我来说不正常。不标记距离内的点。这是考虑在半径范围内还是仅在水平距离内?
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