我需要一种有效的方法来计算一系列点之间的距离矩阵。问题是,你只能从点“我”到达。指出' k'通过所有点' j'之间。例如,想象一个拥有5个海滩的岛屿,您想要计算沿海岸线所有海滩之间的距离,因为您无法穿越岛屿(包括两个方向:顺时针或逆时针)。
以下是一些示例数据。 (注意:您需要安装包' geosphere'才能使用' distm'功能,它计算沿地球表面的GPS坐标之间的距离)
library("geosphere")
longitude = c(-119.003, -119.067, -119.121, -119.089, -119.003)
latitude = c(33.503, 33.539, 33.485, 33.413, 33.440)
long.lat.mat = as.matrix(cbind(longitude, latitude))
# Use "distm" to calculate Euclidean (straight-line) distances between sites (in km)
euclid.dist.mat = distm(long.lat.mat) / 1000
# Create an empty matrix of alongshore distances (from "rows" to "columns")
alongshore.dist.mat = matrix(ncol=dim(long.lat.mat)[1], nrow=dim(long.lat.mat)[1], data=NA)
# Diagonal is zero. Adjacent sites are the same as Euclidean distance
diag(alongshore.dist.mat) = 0
diag(alongshore.dist.mat[,-1]) = diag(euclid.dist.mat[,-1])
alongshore.dist.mat[1,dim(long.lat.mat)[1]] = euclid.dist.mat[1,dim(long.lat.mat)[1]]
alongshore.dist.mat[lower.tri(alongshore.dist.mat)] = t(alongshore.dist.mat)[lower.tri(t(alongshore.dist.mat))]
# > alongshore.dist.mat
# [,1] [,2] [,3] [,4] [,5]
# [1,] 0.0000000 7.1650632 NA NA 7.0131279
# [2,] 7.1650632 0.0000000 7.8265783 NA NA
# [3,] NA 7.8265783 0.0000000 8.5483605 NA
# [4,] NA NA 8.5483605 0.0000000 8.5365807
# [5,] 7.0131279 NA NA 8.5365807 0.0000000
现在,如何填补剩余的细胞?举个例子:
alongshore.dist.mat[1,3] = 7.1650632 + 7.8265783 = 14.991642
...代表网站1 - >网站2 - > 3.相比之下:
alongshore.dist.mat[3,1] = 8.5483605 + 8.5365807 + 7.0131279 = 24.098069
...代表网站3 - >网站4 - >网站5 - >网站1.
我怀疑" cumsum"功能可以有效使用,但不确定如何设置它。我希望有一个避免for循环的解决方案,因为我实际上正在处理包含几十个点的数据。
答案 0 :(得分:0)
您可以先构建两个位置之间所有边的矩阵:
dists <- expand.grid(x=1:5, y=1:5)
dists$weight <- alongshore.dist.mat[as.matrix(dists)]
dists <- subset(dists, x != y & !is.na(weight))
dists
# x y weight
# 2 2 1 7.165063
# 5 5 1 7.013128
# 6 1 2 7.165063
# 8 3 2 7.826578
# 12 2 3 7.826578
# 14 4 3 8.548360
# 18 3 4 8.548360
# 20 5 4 8.536581
# 21 1 5 7.013128
# 24 4 5 8.536581
现在,您可以构建图形并计算所有对最短路径:
library(igraph)
g <- graph.data.frame(dists, vertices=data.frame(x=1:5))
shortest.paths(g)
# 1 2 3 4 5
# 1 0.000000 7.165063 14.991642 15.549709 7.013128
# 2 7.165063 0.000000 7.826578 16.374939 14.178191
# 3 14.991642 7.826578 0.000000 8.548360 17.084941
# 4 15.549709 16.374939 8.548360 0.000000 8.536581
# 5 7.013128 14.178191 17.084941 8.536581 0.000000