J'ai besoin d'un moyen efficace de calculer une matrice de distances entre une série de points. Le hic, c'est que vous pouvez seulement aller du point 'i' au point 'k' en passant par tous les points 'j' entre les deux. Par exemple, imaginez une île avec 5 plages et vous voulez calculer la distance entre toutes les plages le long de la côte car vous ne pouvez pas traverser l'île (y compris dans les deux sens: dans le sens des aiguilles d'une montre ou dans le sens inverse).Calculer la matrice des distances cumulées dans R
Voici quelques exemples de données. (Remarque: vous devez installer le paquet « géosphère » utiliser la fonction « Distm », qui calcule la distance entre les coordonnées GPS le long de la surface de la Terre)
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
Maintenant, comment remplir cellules restantes? A titre d'exemple:
alongshore.dist.mat[1,3] = 7.1650632 + 7.8265783 = 14.991642
... le site représentant 1 -> site 2 -> site 3. Par contre:
alongshore.dist.mat[3,1] = 8.5483605 + 8.5365807 + 7.0131279 = 24.098069
... représentant le site 3 -> site 4 -> Site 5 -> site 1.
Je suppose que la fonction "cumsum" peut être utilisée efficacement, mais je ne sais pas exactement comment la configurer. J'espère une solution pour éviter les boucles, car je travaille en réalité avec des données contenant des dizaines de points.
Si cela est une île , c'est-à-dire un «anneau» mathématique, vous avez une définition ambiguë puisque vous pouvez le contourner dans les deux sens. Le triangle inférieur devrait probablement être pour une direction et le triangle supérieur pour l'autre, c'est-à-dire pas vraiment une mesure de «distance» traditionnelle. –
Je suis d'accord avec vous, c'est pourquoi je mentionne les deux directions ("dans le sens des aiguilles d'une montre" ou "sens inverse des aiguilles d'une montre"). Ce n'est pas une matrice symétrique; les triangles supérieur et inférieur sont différents. Il peut être utile de penser à déplacer "des" lignes de la matrice "vers" les colonnes de la matrice. – MCNC