calculating the geographic distance between coordinates

Dear fellow R users,
I have a matrix where column 1 is longitude, and column 2 is latitude. Each row also has a name, simply numbers from 1 to 837. I want to calculate the geographical distance between each row of the matrix, so row 1 with row 2, row 1, with row3 and so on, so that I end up with a matrix of the distance between each point. I think I should use the geosphere package and then distm, but I am not sure how to proceed afterwards - should I do a looping function for each row to calculate distance? I am very new to R and in over my head so please let me know if you have any tips :slight_smile:

st_distance() from the sf package will do this for you. If you're looking for more specific help, please post a sample of your data.

1 Like

Thanks for your suggestion! Yes here is a sample of my dataimage

st_distance looks like it requires the data in the sf format, so does a table, like I have, not work as an input in this function?

Yes, you would have to convert it to an sf object first.

Thanks for posting your data, but I can't copy the data from your screenshot into my R session -- better would be to post the output of running dput(head(your_data)) which will generate a copy and paste friendly format of your data.

I ran the code you suggested and got this as output, is this the format you meant?

dput(head(species))

structure(list(longitude = c(-106.425668, -96.111617, -96.5,
-96.5, -96.5, -96.5), latitude = c(23.18127, 15.779873, 19.68,
19.68, 19.68, 19.68)), row.names = c(NA, 6L), class = "data.frame")

Yes, that's exactly right! Take a look at the following example -- first we take your species data frame and convert it to an sf object by using st_as_sf() and specifying the column names of the coordinates and the coordinate reference system. Then, st_distance() creates a matrix of the distances between all the points.

library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1

species <- structure(list(longitude = c(-106.425668, -96.111617, -96.5,
-96.5, -96.5, -96.5), latitude = c(23.18127, 15.779873, 19.68,
19.68, 19.68, 19.68)), row.names = c(NA, 6L), class = "data.frame")

species_sf <- st_as_sf(species, coords = c("longitude", "latitude"), crs = 4326)

st_distance(species_sf)
#> Units: [m]
#>         [,1]      [,2]      [,3]      [,4]      [,5]      [,6]
#> [1,]       0 1356919.2 1099211.9 1099211.9 1099211.9 1099211.9
#> [2,] 1356919       0.0  433617.2  433617.2  433617.2  433617.2
#> [3,] 1099212  433617.2       0.0       0.0       0.0       0.0
#> [4,] 1099212  433617.2       0.0       0.0       0.0       0.0
#> [5,] 1099212  433617.2       0.0       0.0       0.0       0.0
#> [6,] 1099212  433617.2       0.0       0.0       0.0       0.0

Created on 2020-06-11 by the reprex package (v0.3.0)

1 Like

Thank you soooo much, I actually got the updated version of sf to work and now I could run the code. Does the stdistance automatically generate a matrix?

Glad you got it working! If you take a look at the st_distance() documentation, you'll see that when the by_element argument is FALSE (the default), you get a matrix with all the distances:

by_element logical; if TRUE , return a vector with distance between the first elements of x and y , the second, etc. if FALSE , return the dense matrix with all pairwise distances.

1 Like

Ah perfect. Thanks again : )

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.