0

I am trying to calculate distance between one location and all other locations from their latitudes and longitudes.

I have been using distanceTrack from the argosfilter package to calculate the distance between consectuive locations which works very simply as this is a the code I need to make it work:

 lat<-lizard$Latitude lon<-lizard$Longitude distanceTrack(lat, lon) 

But now I am wanting to calculate the distance between the first location and the second location, and then the distance between the first and third location, etc. for all locations.

I have been looking for a way to do this quickly as the only way I have been able to do it is manually copying and pasting the desired coordinates into a different csv file and then uploading it to R and running the above code, which is arduous. I am thinking an apply function or something similar might work. So would an apply function be the right way forward? And I don't know how to write the code to specify the rows to calculate the distance between, so any help with that would be great.

9
  • You might want to check out sp::spDistsN1 or geosphere::distVincentyEllipsoid (and related functions in the geosphere package). Commented Apr 12, 2015 at 4:21
  • Do you want the distance between every combination of points (e.g. 1-2, 1-3, 1-4, 2-3, 2-4, 3-4), or just between the first point and all subsequent points (e.g. 1-2, 1-3, 1-4)? Commented Apr 12, 2015 at 4:53
  • I am wanting the distance between the first point and all subsequent points. Commented Apr 12, 2015 at 6:00
  • @BenWestwood, my answer covers that (ignore the thing about combinations). Let me know if it's what you're looking for. Commented Apr 12, 2015 at 22:37
  • @bgoldst, this appears to be what I want from running it on an example. But on my actual data I get the following error: Error in if (lat1 == lat2 & lon1 == lon2) distance <- 0 else { : argument is of length zero. Is this just because the 2 locations are the same? And how do you fix this? Commented Apr 14, 2015 at 2:13

2 Answers 2

3
 earthDist <- function (lon1, lat1, lon2, lat2){ rad <- pi/180 a1 <- lat1 * rad a2 <- lon1 * rad b1 <- lat2 * rad b2 <- lon2 * rad dlon <- b2 - a2 dlat <- b1 - a1 a <- (sin(dlat/2))^2 + cos(a1) * cos(b1) * (sin(dlon/2))^2 c <- 2 * atan2(sqrt(a), sqrt(1 - a)) R <- 6378.145 d <- R * c return(d) } earthDist(lon[1], lat[1], lon, lat) 
Sign up to request clarification or add additional context in comments.

Comments

-1

Sample input data I'll use:

p <- data.frame(lat=runif(6,-90,90), lon=runif(6,-180,180) ); p; ## lat lon ## 1 -27.85808 160.23800 ## 2 31.14363 -45.22589 ## 3 -50.01119 48.84754 ## 4 68.11402 71.46464 ## 5 45.58087 -104.46365 ## 6 87.49930 -88.12699 

If you only want the distances between the first point and all subsequent points, you can do this:

d <- sapply(2:nrow(p), function(x) distance(p$lat[x],p$lat[1],p$lon[x],p$lon[1]) ); d; ## [1] 17517.58 9037.04 12806.45 12557.67 13196.02 

If you want all combinations of points, it's more complicated. In the below, I've switched from a simple vector to a data.frame for the result, so the two point indexes can be stored alongside each distance value:

d <- setNames(do.call(rbind.data.frame,combn(1:nrow(p),2,simplify=F)),c('p1','p2')); d$dist <- sapply(1:nrow(d), function(r) distance(p$lat[d$p1[r]],p$lat[d$p2[r]],p$lon[d$p1[r]],p$lon[d$p2[r]]) ); d; ## p1 p2 dist ## 1 1 2 17517.583 ## 2 1 3 9037.040 ## 3 1 4 12806.448 ## 4 1 5 12557.672 ## 5 1 6 13196.020 ## 6 2 3 12868.340 ## 7 2 4 7815.027 ## 8 2 5 5276.540 ## 9 2 6 6338.329 ## 10 3 4 13259.829 ## 11 3 5 17961.347 ## 12 3 6 15757.656 ## 13 4 5 7363.244 ## 14 4 6 2694.062 ## 15 5 6 4669.714 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.