对角线上具有非零值的R距离矩阵(rdist.earth)

时间:2018-03-12 23:00:38

标签: r geographic-distance

空间距离矩阵的对角线上的条目应为零,bc表示每个位置与其自身之间的距离。但是rdist.earth() fields中的R package函数有时会在对角线上给出非零值:

> # Set number of decimals of output display
> options(digits=8)
> # Some longitude, latitude data
> LLdat
     lon      lat
 1 -105.85878 43.65797
 2 -105.81812 43.57009
 3 -105.80796 43.57748
 > 
 > # Create distance matrix
 > library(fields)
 > distmat <- rdist.earth(LLdat,LLdat)
 > distmat
      1              2          3
1 0.0000000 6.410948951394 6.12184338
2 6.4109490 0.000059058368 0.72150586
3 6.1218434 0.721505863563 0.00000000

在上述距离矩阵中,对角线上的第二个条目为0.000059058368,以英里为单位(默认单位),而其他两个为0.0000000。首先,为什么第二列的条目显示的数字多于其他两个?为什么第二对角线上的条目不像其他条目那样从零到8位小数?这种差异似乎不足以归因于浮点舍入误差。

现在将rdist.earth()的输出与不同包geosphere和函数distGeo()的输出进行比较,后者计算两点之间的距离(不是全距离矩阵)。在这里,我们计算每个点与自身之间的距离。输出向量单位为米:

> library(geosphere)
> distmat2 <- distGeo(LLdat,LLdat)
> distmat2
[1] 0 0 0

因此,对于distGeo(),所有三个距离度量都是一致的,并且恰好为零。

有什么我想念的吗?或者这是否表示rdist.earth()存在问题?

2 个答案:

答案 0 :(得分:2)

不幸的是,这是一个舍入错误。

如果查看源代码,可以复制问题:

<?php

$test = '\x68\x65\x6C\x6C\x6F';

if ("$test" === '\x68\x65\x6C\x6C\x6F') //echos true, even with double quotes around the variable
{
    echo 'true';
}
else if ("$test" === 'hello') //How can I get this condition to be true rather than the previous statement without placing double quotes around my original string I declared?
{
    echo 'false';
}

?>

该函数首先计算中间矩阵pp:

x1 <- LLdat

R <- 3963.34
coslat1 <- cos((x1[, 2] * pi)/180)
sinlat1 <- sin((x1[, 2] * pi)/180)
coslon1 <- cos((x1[, 1] * pi)/180)
sinlon1 <- sin((x1[, 1] * pi)/180)

pp <- cbind(coslat1 * coslon1, coslat1 * sinlon1, sinlat1) %*% 
    t(cbind(coslat1 * coslon1, coslat1 * sinlon1, sinlat1))
return_val = (R * acos(ifelse(abs(pp) > 1, 1 * sign(pp), pp)))

似乎对角线都是一样的。但是:

print (pp)

             [,1]         [,2]         [,3]
[1,] 1.0000000000 0.9999986917 0.9999988071
[2,] 0.9999986917 1.0000000000 0.9999999834
[3,] 0.9999988071 0.9999999834 1.0000000000

答案 1 :(得分:1)

正如@thc解释的那样,它确实是一个数字问题,显然与formula choice有关。特别注意,在使用acos之前,所有值都非常接近1.在x处的acos的导数是 - (1-x ^ 2)^( - 1/2),向-Inf偏移为x转到1,因此公式敏感并不奇怪。

至于处理这个问题,您可以在维基百科页面中实现其他一个提议的和更稳定的解决方案,使用geosphere作为seem to have更加谨慎的实施,或者当然您可以只需设置diag(M) <- 0。但是,后一种选择可能并不可取,因为当这些数字在太空中的距离非常接近时,这些数字问题也可能会保持非对角线条件。