80

I have geocoded points in long, lat format, and I want to calculate the distance between them using R. This seems pretty straight forward, yet I can't find a function that will do it easily. I've been attempting to do it with the gdistance package, but it seems very convoluted and oriented to graphing, I just need a number. Something like distanceBetween(pointA,pointB) that returns a number.

Jaap
  • 81,064
  • 34
  • 182
  • 193
SteveO7
  • 2,430
  • 3
  • 32
  • 40

2 Answers2

109

Loading the geosphere package you can use a number of different functions

library(geosphere)
distm(c(lon1, lat1), c(lon2, lat2), fun = distHaversine)

Also:

distHaversine()
distMeeus()
distRhumb()
distVincentyEllipsoid()
distVincentySphere()

...

CephBirk
  • 6,422
  • 5
  • 56
  • 74
PereG
  • 1,796
  • 2
  • 22
  • 23
  • These all look useful as well! Reading their descriptions they use just slightly different calculations. I couldn't find the forest through the trees! – SteveO7 Sep 02 '15 at 22:59
  • 8
    A small note. The method geosphere:distm is not vectorized. To vectorize it use the *apply* functions. – DotPi Sep 07 '16 at 14:49
  • 2
    @DotPi It says in the documentation (version `1.5-5`) for `distm` that the first two arguments can be `Nx2` matrices (ie. collections of points), so I don't see the need for `apply` here? – oens Dec 15 '16 at 20:57
  • 2
    @oens Thats for getting a matrix of distances from combining different points not just a Nx1 list of distances between the points – Hack-R Jul 20 '17 at 18:44
  • 20
    The distances returned by `distm` are meters by default. The documentation for `distm` does not mention the unit in which distances are returned by default, but this is mentioned in `distHaversine` documentation. – Mikko Aug 11 '17 at 08:32
  • @DotPi do you have an example of how you would vectorize with apply? else it's runs veryyyyyy slow. – nerdlyfe Jun 26 '18 at 22:28
  • @ElChapo: There is not enough space in comments to add an example with code sample. I think it is fair to post your query as a new question if you can include sample data and your current attempt. – DotPi Jun 27 '18 at 06:08
  • here's the vectorized version: ```dist_geo <- function(lat_a, lon_a, lat_b, lon_b) { if(anyNA(c(lat_a, lon_a, lat_b, lon_b))) return(NA) round(distm(c(lon_a, lat_a), c(lon_b, lat_b), fun = distHaversine)/1000,2) } dgeo$distance_km=mapply(lat_a=dgeo$latitude, lon_a=dgeo$longitude, lat_b=dgeo$latitude_lag, lon_b=dgeo$longitude_lag, FUN = dist_geo)``` – Pablo Casas Mar 19 '19 at 20:09
  • you don't need to vectorize. distm(cbind(lon1,lat1),cbind(lon2,lat2)) returns the matrix of distances between all pairs of points, distHaversine(cbind(lon1,lat1),cbind(lon2,lat2)) returns the vector of distances between pairs of points. – Simon Woodward Jul 23 '21 at 02:56
24

Agree with @PereG on answer above, but think that the order of latitude and longitude is the other way around: lon, lat. This will affect your results for distance matrix. So correct is:

library(geosphere)
distm (c(lon1, lat1), c(lon2, lat2), fun = distHaversine)

Source: ftp://cran.r-project.org/pub/R/web/packages/geosphere/geosphere.pdf

Agustín Indaco
  • 550
  • 5
  • 17