【问题标题】:Matrix of pairwise distances成对距离矩阵
【发布时间】:2014-12-28 15:05:57
【问题描述】:

我有一组点坐标,我想用它来生成距离矩阵。更具体地说,我有两组点,大小为 n 的 A 和大小为 m 的 B,作为 2d 坐标给出,并且我希望在矩阵中具有来自 A 的点和来自 B 的点之间的所有欧几里德距离,并且没有其他距离。

编辑:如果情况更复杂怎么办:如果我有我的矩阵但现在我想将它的每一行除以从 A 到集合 B 中所有点的第一个点的欧几里得距离之和:即,对每一行距离进行归一化。有没有有效的方法来做到这一点?

【问题讨论】:

  • 看起来你对在 SO since your previous question 上发布问题了解不多...尽管你可以看看 ?dist
  • 我的问题到底有什么问题?你能具体说明吗?我会知道以供将来参考。
  • 阅读thisthis

标签: r distance


【解决方案1】:

基础 R 中的 dist(...) 函数不会有帮助,因为它会计算自动距离(给定数据集中每个点到每个其他点的距离)。你想要跨距离。包proxy 中有一个dist(...) 函数是为此而设计的。

使用@BenBolker 提供的数据集,

library(proxy)   # note that this masks the dist(...) fn in base R...
result <- dist(A,B)
result[1:5,1:5]
#           [,1]      [,2]      [,3]      [,4]      [,5]
# [1,] 0.5529902 0.7303561 0.1985409 0.6184414 0.7344280
# [2,] 0.7109408 0.9506428 0.1778637 0.7216595 0.9333687
# [3,] 0.2971463 0.3809688 0.4971621 0.4019629 0.3995298
# [4,] 0.4985324 0.5737397 0.4760870 0.5986826 0.5993541
# [5,] 0.4513063 0.7071025 0.3077415 0.4289675 0.6761988

【讨论】:

    【解决方案2】:
    set.seed(101)
    n <- 10; m <- 20
    A <- data.frame(x=runif(n),y=runif(n))
    B <- data.frame(x=runif(m),y=runif(m))
    

    我们想要

    sqrt((x_{1,i}-x_{2,j})^2+(y_{1,i}-y_{2,j})^2)
    

    对于每个 i=1:nj=1:m

    你可以通过

    dists <- sqrt(outer(A$x,B$x,"-")^2 + outer(A$y,B$y,"-")^2)
    

    在这种情况下是一个 10x20 矩阵。换句话说,我们正在寻找每对 x 值和每对 y 值之间的差异("-" 是对减法运算符的引用),然后求平方、加和取平方根。

    如果你想通过总和来标准化每一行,我建议

    norm.dists <- sweep(dists,MARGIN=1,STATS=rowSums(dists),FUN="/")
    

    【讨论】:

    • 您能否解释一下“-”位的确切含义以及可以放在那里的其他内容?
    • 只是出于好奇:如果我想要一个与距离不同的函数,只是坐标的任意函数,我会怎么做?
    • 如果您可以将其分解为对标量的成对操作,那么您可以将outer() 与不同的功能一起使用。如果你想计算一个函数f(x_{1i},x_{2j},y{1i},y_{2j}),那可能很难有效地向量化。能给我举个例子吗? (PS:看来@jlhoward 建议的proxy::dist() 采用了任意函数​​。)