【问题标题】:Generating a pairwise 'distance' matrix生成成对的“距离”矩阵
【发布时间】:2023-03-10 18:49:01
【问题描述】:

我正在尝试从包含两个相邻点之间距离的数据框中生成我最能描述为成对距离矩阵的内容。这些不是欧几里得距离,它们本质上是海岸线上点之间的距离,因此距离不是直线。我能够使用地理空间数据在包riverdist 中生成一个距离矩阵,但这只是两点之间的完整距离,我现在正在尝试做两点之间距离的一个子集。

我一直在寻找一种方法来做到这一点,但一直空手而归。任何帮助将非常感激。

这是一个例子:

我有这些数据:

mat <- matrix(
 c(
     3, #distance between 1 and 2
    10, #distance between 2 and 3
     7, #distance between 3 and 4
     9  #distance between 4 and 5
),
nrow=4, ncol=1, dimnames =     list(c("site1","site2","site3","site4"),c("dist")))

> mat
  dist
site1    3
site2   10
site3    7
site4    9

我想生成以下“距离”矩阵:

     site1 site2 site3 site4 site5
site1    0
site2    3     0     
site3   13    10     0   
site4   20    17     7     0
site5   29    26    16     9     0

对于这项任务,原始数据可能会更好地组织如下:

     SiteA SiteB Dist
   1 site1 site2    3
   2 site2 site3   10
   3 site3 site4    7
   4 site4 site5    9

有什么建议吗?

【问题讨论】:

    标签: r matrix pairwise pairwise-distance


    【解决方案1】:

    我认为您可能过于关注实际距离,而您的问题更多的是求和问题。

    至少据我了解,您不需要寻找最短路线或类似问题,只需添加数字即可。所以从ab,意味着从变量mat 中添加行ab-1。唯一困难的事情是处理 from 和 to 向后或相同的情况。无论如何,我明白了:

    dist <- function(a,b) abs(sum(if(a>1 && b>1) mat$dist[(a:b)-1][-1] else mat$dist[(a:b)-1]))
    distmat <- sapply(1:5, function(i) {
      sapply(1:5, dist, i)
    })
    

    【讨论】:

      【解决方案2】:

      这是一个累积距离,所以取一个cumulative sum,然后进行distance 计算:

      mat <- c(3,10,7,9)
      dist(cumsum(c(0,mat)))
      #   1  2  3  4
      #2  3         
      #3 13 10      
      #4 20 17  7   
      #5 29 26 16  9
      

      【讨论】:

      • 太简单了。谢谢!我不知道用谷歌搜索什么来找到答案,我需要的词是累积的。再次感谢!
      • @Aislin809 - 不用担心。如果它解决了您的问题,请点击答案旁边的复选标记,以便其他人知道它已解决。
      【解决方案3】:

      这样就可以了(尽管可能有点慢):

      dist = function(mat){
          tmp_mat = c(0, mat)
          dist_mat = diag(0, length(mat)+1)
          for (i in 1:length(mat))
              dist_mat[(i+1):(length(mat)+1),i] = cumsum(tmp_mat[-(1:i)])
      
          dist_mat = dist_mat + t(dist_mat)
          return (dist_mat)
          }
      dist(mat)
      

      【讨论】: