0

I have a dataframe consisting of three columns, "Point_name" "longitude" and "latitude"

Point_Name              Longitude   Latitude
University of Arkansas  36.067832   -94.173655
Lehigh University       40.601458   -75.360063
Harvard University      42.379393   -71.115897

Is there an R package I can use to calculate distances between each point? The aim is to get R to "measure" the distance between points and then produce either a dataframe of points that have another point within "X" (eg. 500 meters) distance radius or produce a dataframe like this one...

Point_Name              Longitude   Latitude    Nearest_Point       Distance_km
University of Arkansas  36.067832   -94.173655  Lehigh University   1750        
Lehigh University       40.601458   -75.360063  Harvard University  450
Harvard University      42.379393   -71.115897  Lehigh University   450
rg255
  • 4,119
  • 3
  • 22
  • 40
  • This might help. I have not tried it: http://r.789695.n4.nabble.com/Geographic-distance-between-lat-long-points-in-R-td3442338.html In particular, you might try the code provided by dirknbr. – Mark Miller Feb 10 '14 at 09:08
  • When I use the code provided by dirknbr I do not get the same result as when I use the website: http://www.movable-type.co.uk/scripts/latlong.html which also gives code, but not in R. If nobody answers within 24 hours I might try to convert the code at the second website to R and see if I can reproduce estimates. – Mark Miller Feb 10 '14 at 09:28

1 Answers1

0

How about this

df<-read.table(header=T, text="Point_Name|Longitude|Latitude
University of Arkansas|36.067832|-94.173655
Lehigh University|40.601458|-75.360063
Harvard University|42.379393|-71.115897", sep="|")

great_circle_distance <- function(lat1, long1, lat2, long2) {
  a <- sin(0.5 * (lat2*pi/180 - lat1*pi/180))
  b <- sin(0.5 * (long2*pi/180 - long1*pi/180))
  12742 * asin(sqrt(a * a + cos(lat1*pi/180) * cos(lat2*pi/180) * b * b))
}

cross<-expand.grid(1:nrow(df),1:nrow(df))

cross$dist<-apply(cross,1,function(x){great_circle_distance(df[x[1],3],
                                               df[x[1],2],
                                               df[x[2],3],
                                               df[x[2],2])
}
      )

cross$from<-df[cross$Var1,1]
cross$to<-df[cross$Var2,1]

require(plyr)
ddply(cross[cross$Var1!=cross$Var2,],.(from),summarise,min(dist),to[dist==min(dist)])

from       ..1                ..2
1     Harvard University  475.3078  Lehigh University
2      Lehigh University  475.3078 Harvard University
3 University of Arkansas 2090.8387  Lehigh University
Troy
  • 8,581
  • 29
  • 32
  • The units for lat long provided in the original post are degrees. The function from Rosetta Stone converts them to radians: http://rosettacode.org/wiki/Haversine_formula#R Your code does not include the code to convert to radians, which might explain why your distances are so large. – Mark Miller Feb 10 '14 at 10:31
  • Sorry should be km, but forgot the inputs were in degrees not radians. I've updated the formula and it should be in km – Troy Feb 10 '14 at 10:35
  • thanks @troy - I've tested it out on my full dataset which worked a charm, using `colnames(df)=c("A","km","B"):df=df[with(df,order(-km)),]:df$A[df$km<=0.2]` I was able to filter out those with another point within a certain radius (200 meters in this version) – rg255 Feb 10 '14 at 14:55