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
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.
Thanks for your suggestion! Yes here is a sample of my data
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)
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 ofx
andy
, the second, etc. ifFALSE
, return the dense matrix with all pairwise distances.
Ah perfect. Thanks again : )
This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.