2017-08-20 1 views
2

Je veux créer une "matrice" de la distance entre les coordonnées multiples les uns avec les autres. De préférence en utilisant dplyr/geosphere. J'ai déjà vu que le paquet de la géosphère offre cela. J'ai réussi à créer la distance entre deux vecteurs mais j'ai des difficultés à créer la matrice complète.Geosphere/dplyr: créer une matrice de distance entre les coordonnées

Ceci est le tableau d'exemple avec plusieurs coordonnées.

df <- data.frame(latitude = c(49.48609,-8.14671,11.28625), 
       longitude = c(8.463678,143.05793,-11.18285)) 

    latitude longitude 
1 49.48609 8.463678 
2 -8.14671 143.057930 
3 11.28625 -11.182850 

Et c'est la sortie Je cherche:

latitude longitude distance-latlon1 distance-latlon2 distance-latlon3     
1 49.48609  8.463678 NA     *latlon2><latlon1 *latlon3><latlon1 
2 -8.14671 143.057930 *latlon1><latlon2 NA     *latlon3><latlon2 
3 11.28625 -11.182850 *latlon1><latlon3 *latlon2><latlon3 NA 

J'ai essayé à l'aide géosphère, mais je ne ai trouvé un moyen de calculer la distance entre deux colonnes (qui, dans ce résultat snippet dans un 0).

library(geosphere) 
df$distance <- distVincentyEllipsoid(df[,c('longitude','latitude')], 
            df[,c('longitude','latitude')]) 

Répondre

2

Vous avez besoin de la fonction distm du geosphere -package. Avec:

# create a distance matrix 
m <- distm(df[2:1], df[2:1], fun = distVincentyEllipsoid) 

# replace the diagonal with NA 
diag(m) <- NA 

# make column names for the distance matrix 
colnames(m) <- paste0('r',1:nrow(df)) 

# bind the distance matrix to the dataframe 
cbind.data.frame(df, m) 

vous obtenez:

latitude longitude  r1  r2  r3 
1 49.48609 8.463678  NA 13792423 4606658 
2 -8.14671 143.057930 13792423  NA 17189185 
3 11.28625 -11.182850 4606658 17189185  NA 
0

On peut utiliser la fonction st_distance de l'emballage sf, qui utilise des fonctions de geosphere pour calculer la distance que l'objet est en saillie sf lon-lat (EPSG 4326). df2 est l'exemple de sortie.

# Load packages 
library(dplyr) 
library(sf) 

# Create example data frame 
df <- data.frame(latitude = c(49.48609,-8.14671,11.28625), 
       longitude = c(8.463678,143.05793,-11.18285)) 

# COnvert to sf object 
df_sf <- st_as_sf(df, coords = c("longitude", "latitude")) 

# Set the projection as ESPG 4326 (long_lat) 
st_crs(df_sf) <- 4326 

# Apply the st_distance function 
dist_m <- st_distance(df_sf) 

# Combine with df 
df2 <- df %>% 
    mutate(`distance-latlon1` = as.numeric(dist_m[, 1]), 
     `distance-latlon2` = as.numeric(dist_m[, 2]), 
     `distance-latlon3` = as.numeric(dist_m[, 3])) 

# Replace 0 with NA 
df2[df2 == 0] <- NA 

df2 
    latitude longitude distance-latlon1 distance-latlon2 distance-latlon3 
1 49.48609 8.463678    NA   13792423   4606658 
2 -8.14671 143.057930   13792423    NA   17189185 
3 11.28625 -11.182850   4606658   17189185    NA 

Voici une autre façon de combiner dist_m avec df.

library(tidyr) 

# Convert dist_m to data frame 
dist_df <- dist_m %>% 
    as.table() %>% 
    as_data_frame() %>% 
    spread(Var2, n) %>% 
    select(-Var1) %>% 
    mutate_all(as.numeric) %>% 
    setNames(paste0("distance-latlon", 1:nrow(df))) 

# Combine with df 
df2 <- df %>% 
    bind_cols(dist_df) 

# Replace 0 with NA 
df2[df2 == 0] <- NA