如何计算R中独立测向的位置之间的距离

如何计算R中独立测向的位置之间的距离,r,distance,latitude-longitude,haversine,R,Distance,Latitude Longitude,Haversine,我已经看完了几个答案,但还没能把它应用到我的问题上。见: 我必须停下来。对于每一站,我想找出到loc的距离 我的位置 loc <- data.frame(station = c('Baker Street','Bank'), lat = c(51.522236,51.5134047), lng = c(-0.157080, -0.08905843), postcode = c('NW

我已经看完了几个答案,但还没能把它应用到我的问题上。见:

我必须停下来。对于每一站,我想找出到loc的距离

我的位置

loc <- data.frame(station = c('Baker Street','Bank'),
                  lat = c(51.522236,51.5134047),
                  lng = c(-0.157080, -0.08905843),
                  postcode = c('NW1','EC3V')
                  )
我的站点

stop <- data.frame(station = c('Angel','Barbican','Barons Court','Bayswater'),
                   lat = c(51.53253,51.520865,51.490281,51.51224),
                   lng = c(-0.10579,-0.097758,-0.214340,-0.187569),
                   postcode = c('EC1V','EC1A', 'W14', 'W2'))
最后,我想要这样的东西:

df <- data.frame(loc = c('Baker Street','Bank','Baker Street','Bank','Baker Street','Bank','Baker Street','Bank'), 
                 stop = c('Angel','Barbican','Barons Court','Bayswater','Angel','Barbican','Barons Court','Bayswater'), 
                 dist = c('x','x','x','x','x','x','x','x'), 
                 lat = c(51.53253,51.520865,51.490281,51.51224,51.53253,51.520865,51.490281,51.51224), 
                 lng = c(-0.10579,-0.097758,-0.214340,-0.187569,-0.10579,-0.097758,-0.214340,-0.187569),
                 postcode = c('EC1V','EC1A', 'W14', 'W2','EC1V','EC1A', 'W14', 'W2')
                 )
我的数据集比较大,所以我正在寻找一种有效的方法来解决这个问题

关于如何实现这一点有什么想法吗?

这利用expand.grid并合并一些创造性的变量重命名。这是一个小人手,但它是相当有效的,因为操作是矢量化的

library(dplyr)
df <- expand.grid(station = loc$station, stop = stop$station) %>%
  merge(loc, by = 'station') %>%
  rename(loc = station, lat1 = lat, lng1 = lng, station = stop) %>%
  select(-postcode) %>%
  merge(stop, by = 'station') %>%
  rename(stop = station, lat2 = lat, lng2 = lng)
#           stop          loc     lat1        lng1     lat2      lng2 postcode
# 1        Angel Baker Street 51.52224 -0.15708000 51.53253 -0.105790     EC1V
# 2        Angel         Bank 51.51340 -0.08905843 51.53253 -0.105790     EC1V
# 3     Barbican Baker Street 51.52224 -0.15708000 51.52087 -0.097758     EC1A
# 4     Barbican         Bank 51.51340 -0.08905843 51.52087 -0.097758     EC1A
# 5 Barons Court Baker Street 51.52224 -0.15708000 51.49028 -0.214340      W14
# 6 Barons Court         Bank 51.51340 -0.08905843 51.49028 -0.214340      W14
# 7    Bayswater Baker Street 51.52224 -0.15708000 51.51224 -0.187569       W2
# 8    Bayswater         Bank 51.51340 -0.08905843 51.51224 -0.187569       W2
如果你好奇哈弗森公式是如何工作的

latrad1 <- df$lat1 * pi/180
latrad2 <- df$lat2 * pi/180
dlat <- df$dlat * pi/180
dlng <- df$dlng * pi/180
a <- sin(dlat / 2)^2 + sin(dlng / 2)^2 * cos(latrad1) * cos(latrad2)
dist_rad <- 2 * atan2(sqrt(a), sqrt(1-a))
df %>%
  mutate(dist_meters_byhand = dist_rad * 6378137) %>%
  select(stop, loc, dist_meters_geosphere = dist_meters, dist_meters_byhand)
#           stop          loc dist_meters_geosphere dist_meters_byhand
# 1        Angel Baker Street              3732.422           3732.422
# 2        Angel         Bank              2423.989           2423.989
# 3     Barbican Baker Street              4111.786           4111.786
# 4     Barbican         Bank              1026.091           1026.091
# 5 Barons Court Baker Street              5328.649           5328.649
# 6 Barons Court         Bank              9054.998           9054.998
# 7    Bayswater Baker Street              2387.231           2387.231
# 8    Bayswater         Bank              6825.897           6825.897

没有@Ben的那么聪明,也可能没有@Ben的那么快,但这里有另一种方法:

library(geosphere)

master_df <- data.frame()

for (i in 1:nrow(loc)){
  this_loc <- loc[i, 1]
  temp_df <- cbind(stop, 
                   data.frame(loc = this_loc, 
                   dist = distm(as.matrix(stop[, 2:3]), c(loc[i, 2], loc[i, 3]))))
  master_df <- rbind(master_df, temp_df)
}

geosphere软件包默认使用haversine,如果需要准确度,这可能会很有用。

我可能没有正确地阅读问题,但您是否试图找到stop数据帧中的每个点与loc数据帧中的每个点之间的距离?@Awhstin是的,准确地说……从stop到loc的每个距离都是一致的,如果用loc代替圆圈,用stop代替dat,并确保从每个数据帧中保留任何列,则有一个基本的R方法可以在这里工作。问题不是重复的,但答案是相似的。@eipi10非常感谢您指出您的帖子,非常有用。半径和距离的单位是多少?比如说,我想要一个离圆心5公里的距离,我将设置什么样的半径值,以及如何解释距离。如果这是一个明显的问题,很抱歉。单位是米,因为这是Distaversine返回的。谢谢你的回答,非常有用。什么算是靠得很近?这是否适用于同一国家(即英国)内的数据点,或者我需要如此大距离的球坐标?另外,您答案中的距离单位是多少?我已经按照Jacob的建议,使用geosphere软件包将结果更改为米。谢谢您的帮助。我注意到,如果我尝试你的方法,我不会得到唯一的距离,即距离天使到贝克街与距离天使到银行相同?
library(geosphere)

master_df <- data.frame()

for (i in 1:nrow(loc)){
  this_loc <- loc[i, 1]
  temp_df <- cbind(stop, 
                   data.frame(loc = this_loc, 
                   dist = distm(as.matrix(stop[, 2:3]), c(loc[i, 2], loc[i, 3]))))
  master_df <- rbind(master_df, temp_df)
}