当您想计算具有纬度/经度坐标的点之间的距离时,geosphere 包中的distm 函数为您提供了几种方法:distCosine、distHaversine、distVincentySphere 和distVincentyEllipsoid。其中,distVincentyEllipsoid 被认为是最准确的。在这些答案中,我展示了如何计算两个不同点列表之间的距离:
但是,您的情况有点不同,因为您想在带有坐标的点列表中进行比较。通过稍微改变我在这些答案中展示的方法,你可以达到同样的效果。说明如何使用您提供的数据执行此操作:
数据:
points <- structure(list(p = structure(1:5, .Label = c("A", "B", "C", "D", "E"), class = "factor"),
lon = c(100.113, 99.8961, 99.8829, 101.2457, 102.1314),
lat = c(17.5406, 20.0577, 20.0466, 16.8041, 19.8881)),
.Names = c("p", "lon", "lat"), class = "data.frame", row.names = c(NA, -5L))
请注意,我添加了一个变量p,其中包含点的名称。
原方法:
首先你创建一个距离矩阵:
distmat <- distm(points[,c('lon','lat')], points[,c('lon','lat')], fun=distVincentyEllipsoid)
给出:
> distmat
[,1] [,2] [,3] [,4] [,5]
[1,] 0.0 279553.803 278446.927 145482.3 335897.8
[2,] 279553.8 0.000 1848.474 387314.3 234708.0
[3,] 278446.9 1848.474 0.000 386690.7 235998.8
[4,] 145482.3 387314.334 386690.666 0.0 353951.5
[5,] 335897.8 234707.958 235998.784 353951.5 0.0
当您现在将最近的点分配给每个点时:
points$nearest <- points$p[apply(distmat, 1, which.min)]
每个点将被分配给自己作为最近点:
> points
p lon lat nearest
1 A 100.1130 17.5406 A
2 B 99.8961 20.0577 B
3 C 99.8829 20.0466 C
4 D 101.2457 16.8041 D
5 E 102.1314 19.8881 E
适应:
您可以通过将距离矩阵distmat 中的0 值替换为:
distmat[distmat==0] <- NA
当您现在将最近的点分配给每个点时:
points$nearest <- points$p[apply(distmat, 1, which.min)]
你得到正确的值:
> points
p lon lat nearest
1 A 100.1130 17.5406 D
2 B 99.8961 20.0577 C
3 C 99.8829 20.0466 B
4 D 101.2457 16.8041 A
5 E 102.1314 19.8881 B