生成成对 'distance' 矩阵
Generating a pairwise 'distance' matrix
我正在尝试从包含两个相邻点之间的距离的数据框中生成我最能描述为成对距离矩阵的东西。这些不是欧几里德距离,它们本质上是海岸线上各点之间的距离,因此距离不是直线。我能够使用地理空间数据在包 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
我想生成以下 'distance' 矩阵:
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
有什么建议吗?
我觉得你可能过于关注实际距离,而你的问题更多的是求和问题。
至少据我了解,你不需要寻找最短路线或类似的问题,而只需要添加数字即可。因此,从 a
到 b
,意味着从变量 mat
添加行 a
到 b-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)
})
这样就可以了(虽然可能有点慢):
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)
这是一个累积距离,所以采用 cum
计算 sum
然后进行 dist
ance 计算:
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
我正在尝试从包含两个相邻点之间的距离的数据框中生成我最能描述为成对距离矩阵的东西。这些不是欧几里德距离,它们本质上是海岸线上各点之间的距离,因此距离不是直线。我能够使用地理空间数据在包 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
我想生成以下 'distance' 矩阵:
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
有什么建议吗?
我觉得你可能过于关注实际距离,而你的问题更多的是求和问题。
至少据我了解,你不需要寻找最短路线或类似的问题,而只需要添加数字即可。因此,从 a
到 b
,意味着从变量 mat
添加行 a
到 b-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)
})
这样就可以了(虽然可能有点慢):
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)
这是一个累积距离,所以采用 cum
计算 sum
然后进行 dist
ance 计算:
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