在数据框中找到距离给定点最近的 3 个点
Find nearest 3 points to a given point in a dataframe
我有一个带有纬度和经度的数据框,如下所示:
x y set
61 -112
63 -113
61 -113
62 -111 point
61 -111
64 -120
我想找到距离 set
列中标记为 point
的点最近的三个点。然后,对于这三个最接近的点,我想将set
列修改为closest
。像这样:
x y set
61 -112 closest
65 -113
62 -113 closest
62 -111 point
62 -111 closest
64 -120
我该怎么做?
dists <- geosphere::distHaversine(dat[dat$set=="point",c("y","x")], dat[,c("y","x")])
dists
# [1] 123339.4 151513.9 153862.4 0.0 111319.5 505814.4
dat$set[dat$set != "point" & rank(dists) < 5] <- "closest"
dat
# x y set
# 1 61 -112 closest
# 2 63 -113 closest
# 3 61 -113
# 4 62 -111 point
# 5 61 -111 closest
# 6 64 -120
我们使用< 5
的原因是自距离(point
到point
)最接近(0
),所以我们需要等级2 -4。这假设有一个 "point"
;如果还有更多,您可能需要 outer
(产生 matrix
的距离)并在填充 $set
.
之前查看每一行
我是从 sp 标签推断纬度和经度,所以选择了 Haversine 距离计算,因为它很快,粗坐标的出现并不意味着亚毫米精度的要求(即, Vincenty 椭球公式)。如果需要,还有其他距离计算。
首先是另一种使用 geosphere
的方法(使用 distm
制作距离矩阵),然后我将展示如何使用 terra::nearby
方法(适用于 long/lat 和平面坐标)。
m <- matrix(c(61, -112, 63, -113, 61, -113, 62, -111, 61, -111, 64, -120), ncol=2, byrow=TRUE)
# note that the order should be long/lat !!!
m <- m[, 2:1]
d <- geosphere::distm(m)
diag(d) <- NA
i <- order(d[4,])[1:3]
i
#[1] 5 1 2
m[i,]
# [,1] [,2]
#[1,] -111 61
#[2,] -112 61
#[3,] -113 63
现在 terra
。下面为所有点获取最近的 3 个邻居。
library(terra)
v <- vect(m, crs="+proj=lonlat")
nearby(v, k=3)
# id k1 k2 k3
#1 1 3 5 4
#2 2 4 3 1
#3 3 1 5 4
#4 4 5 1 2
#5 5 1 3 4
#6 6 2 3 4
使用 terra 版本 1.3.15(目前是开发版本)你也可以
nearby(v[4,], v, k=4)
# id k1 k2 k3 k4
#[1,] 1 4 5 1 2
以k=4
个邻居为第一个点本身。
要获取开发版本,请执行
install.packages('terra', repos='https://rspatial.r-universe.dev')
我有一个带有纬度和经度的数据框,如下所示:
x y set
61 -112
63 -113
61 -113
62 -111 point
61 -111
64 -120
我想找到距离 set
列中标记为 point
的点最近的三个点。然后,对于这三个最接近的点,我想将set
列修改为closest
。像这样:
x y set
61 -112 closest
65 -113
62 -113 closest
62 -111 point
62 -111 closest
64 -120
我该怎么做?
dists <- geosphere::distHaversine(dat[dat$set=="point",c("y","x")], dat[,c("y","x")])
dists
# [1] 123339.4 151513.9 153862.4 0.0 111319.5 505814.4
dat$set[dat$set != "point" & rank(dists) < 5] <- "closest"
dat
# x y set
# 1 61 -112 closest
# 2 63 -113 closest
# 3 61 -113
# 4 62 -111 point
# 5 61 -111 closest
# 6 64 -120
我们使用< 5
的原因是自距离(point
到point
)最接近(0
),所以我们需要等级2 -4。这假设有一个 "point"
;如果还有更多,您可能需要 outer
(产生 matrix
的距离)并在填充 $set
.
我是从 sp 标签推断纬度和经度,所以选择了 Haversine 距离计算,因为它很快,粗坐标的出现并不意味着亚毫米精度的要求(即, Vincenty 椭球公式)。如果需要,还有其他距离计算。
首先是另一种使用 geosphere
的方法(使用 distm
制作距离矩阵),然后我将展示如何使用 terra::nearby
方法(适用于 long/lat 和平面坐标)。
m <- matrix(c(61, -112, 63, -113, 61, -113, 62, -111, 61, -111, 64, -120), ncol=2, byrow=TRUE)
# note that the order should be long/lat !!!
m <- m[, 2:1]
d <- geosphere::distm(m)
diag(d) <- NA
i <- order(d[4,])[1:3]
i
#[1] 5 1 2
m[i,]
# [,1] [,2]
#[1,] -111 61
#[2,] -112 61
#[3,] -113 63
现在 terra
。下面为所有点获取最近的 3 个邻居。
library(terra)
v <- vect(m, crs="+proj=lonlat")
nearby(v, k=3)
# id k1 k2 k3
#1 1 3 5 4
#2 2 4 3 1
#3 3 1 5 4
#4 4 5 1 2
#5 5 1 3 4
#6 6 2 3 4
使用 terra 版本 1.3.15(目前是开发版本)你也可以
nearby(v[4,], v, k=4)
# id k1 k2 k3 k4
#[1,] 1 4 5 1 2
以k=4
个邻居为第一个点本身。
要获取开发版本,请执行
install.packages('terra', repos='https://rspatial.r-universe.dev')