【问题标题】:Coordinate descent iteration on lat/long values in R [closed]R中纬度/经度值的坐标下降迭代[关闭]
【发布时间】:2015-08-19 03:31:04
【问题描述】:

我想在一组点上执行坐标下降迭代,这些点的纬度和经度在数组中给出。迭代应该帮助我估计一组纬度和经度点的最近位置。我有一个纬度/经度值的数组“a”和“b”。两个数组都表示同一组位置。

       Longitude     Latitude
  1.    100.1130      17.5406
  2.     99.8961      20.0577
  3.     99.8829      20.0466
  4.    101.2457      16.8041
  5.    102.1314      19.8881

【问题讨论】:

  • 也许有一些帮助here
  • 我不明白为什么这需要迭代。无论迭代如何,到给定点的最近点的集合是否总是相同的?如果dist 函数的其中一种方法有效,您可以快速计算出每个点的最小距离。

标签: r sum distance latitude-longitude


【解决方案1】:

当您想计算具有纬度/经度坐标的点之间的距离时,geosphere 包中的distm 函数为您提供了几种方法:distCosinedistHaversinedistVincentySpheredistVincentyEllipsoid。其中,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

【讨论】:

  • 我想我的问题是错误的。我不想在同一组 5 个点中找到最近的点。我想将 5 个点中的每一个迭代 100 次,并从这 100 次迭代中找到最近的点。例如:我想迭代点 A 100 次,并在这 100 次迭代中找到最近的纬度/经度。同样,我想对所有其他点都这样做。简而言之,对每个点进行 100 次迭代,并在这些迭代中找到最近的点,而不是在数据集中。
  • @Ross 您能否具体说明“迭代 A 点 100 次”是什么意思?您必须向我们提供有关您希望如何迭代的更多信息。由于您的问题现在写得不清楚。
  • 在每次迭代中,程序应使用具有非零权重的位置的 L1 多元中值更新每个位置。
  • @Ross 也许你可以展示你用来获取wab 矩阵的代码。您也可以包含您尝试过的代码,即使它不起作用。
  • 我刚刚通过随机样本生成了 Wab 矩阵。 Wab 矩阵中的值并不重要。可以是任意随机数。
【解决方案2】:

您可以为此使用dist() 函数:

mat2 <- dist(mat,method = "euclidean")
           1.         2.         3.         4.
2. 2.52642792                                 
3. 2.51654168 0.01724674                      
4. 1.35108902 3.52240445 3.51724752           
5. 3.09591583 2.24172484 2.25407952 3.20866335

最近的五个点有距离

> head(sort(mat2),5)
#[1] 0.01724674 1.35108902 2.24172484 2.25407952 2.51654168

距离矩阵中的点对可以很容易地从它们的索引中推导出来:

> head(order(mat2),5)
#[1] 5 3 7 9 2

索引是从左上角开始按列计数的条目,所以mat2[5]=0.01724674是点2和点3之间的距离,mat2[3]=1.351089是点1和点4之间的距离,等等。

我们可以定义一个函数来提取这些对:

dist_pairs <- function(x,y){
  idx1 = ceiling(x / (y - 1))
  idx2 = x %% (y - 1) + idx1
  return(c(idx1, idx2))
} 

其中第二个参数是原始矩阵中的行数; 5 在这种情况下。例如,

> dist_pairs(9, nrow(mat))
#[1] 3 4

表示距离矩阵中的第 9 项包含点 3 和 4 之间的距离。

编辑

通过查看@Jaap 的答案并重新阅读 OP,我意识到您有兴趣找到最接近每个数据点的点,而不一定是对您的集合中最小的那些对进行排名彼此之间的距离。

要获取此信息,可以按照@Jaap 建议的类似方式修改代码:

mat3 <- as.matrix(mat2)
diag(mat3) <- NA
mat <- as.data.frame(mat)
mat$closest <- apply(mat3,1,which.min)
> mat
#  Longitude Latitude closest
#1  100.1130  17.5406       4
#2   99.8961  20.0577       3
#3   99.8829  20.0466       2
#4  101.2457  16.8041       1
#5  102.1314  19.8881       2

数据

mat <- as.matrix(read.table(text="     Longitude        Latitude
      100.1130      17.5406
       99.8961      20.0577
       99.8829      20.0466
      101.2457      16.8041
      102.1314      19.8881", header=T))

【讨论】:

  • 我认为对于纬度/经度,您可能想要使用大圆距离。 sp或者其他包里面有函数。
  • 总的来说我完全同意。在这种特定情况下,坐标值似乎足够接近,“平坦地球”近似值可能是合理适用的。
猜你喜欢
  • 2012-02-03
  • 1970-01-01
  • 1970-01-01
  • 2013-04-04
  • 2015-02-27
  • 1970-01-01
  • 2021-07-18
  • 1970-01-01
相关资源
最近更新 更多