Вычисление расстояния между двумя точками долготы / широты в одном кадре data.frame

Для начала вот структура таблицы, которую я использую:

df <- structure(list(customer_id = c(353808874L, 69516747L, 357032052L, 
307735090L, 307767260L), id = c("8474", "8107", 
"1617436", "7698", "1617491"), lon1 = c(-115.032623, -115.155029, 
-115.270386, -115.19426, -115.177589), lat1 = c(36.0437202, 36.1366234, 
36.1678734, 36.2635803, 36.2218285), lon2 = c(-115.037022076035, 
-115.150112230012, -115.27341017806, -115.193072645577, -115.174902476442
), lat2 = c(36.0410001245783, 36.141137860928, 36.1700923382169, 
36.2682687632778, 36.2240270452917)), row.names = c(NA, 5L), class = "data.frame")

Я попытался использовать информацию из нескольких разных вопросов о переполнении стека, но ни один из них не достиг желаемого результата.

Один из них был такой:

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)

Но я не мог заставить его выдать то, что я ищу. Я, конечно, не привязан к этому, так что если у кого-то есть что-то более эффективное, я весь в ушах!

РЕДАКТИРОВАТЬ: Мой предполагаемый результат довольно прост. Всего три столбца distance_between, представляющие расстояние между lon / lat1 и lon / lat2:

+-------------+----+------------------+
| customer_id | id | distance_between |
+-------------+----+------------------+

person gooponyagrinch    schedule 22.01.2020    source источник
comment
Отвечает ли это на ваш вопрос? Как рассчитать расстояние и время между двумя местоположениями   -  person jay.sf    schedule 22.01.2020
comment
Попробуйте library(geosphere);distm(df[c('lon1', 'lat1')], df[c('lon2', 'lat2')])   -  person akrun    schedule 22.01.2020
comment
@akrun Я все время получаю следующую ошибку: Error: vector memory exhausted (limit reached?) Думаю, я должен был заметить, что приведенный выше фрейм данных был лишь небольшой выборкой из гораздо большего. Любые идеи?   -  person gooponyagrinch    schedule 22.01.2020
comment
@ jay.sf - Нет. Я все время пытаюсь установить пакет VTrack, но моя среда, похоже, не позволяет мне   -  person gooponyagrinch    schedule 22.01.2020
comment
@ Dave2e Я внесу правку   -  person gooponyagrinch    schedule 22.01.2020
comment
stackoverflow.com/q/36817423/5977215. Кроме того, geosphere довольно медленный и неэффективный. Я рекомендую library(geodist). Я также провел несколько тестов здесь   -  person SymbolixAU    schedule 23.01.2020


Ответы (1)


Это легко решить с помощью функции distGeo (аналогичной вашим функциям выше) из пакета geosphere:

library(geosphere)
#calculate distances in meters
df$distance<-distGeo(df[,c("lon1", "lat1")], df[,c("lon2", "lat2")])

#remove columns
df[, -c(3:6)]

customer_id      id distance
1   353808874    8474 498.2442
2    69516747    8107 668.4088
3   357032052 1617436 366.9541
4   307735090    7698 531.0785
5   307767260 1617491 343.3051
person Dave2e    schedule 22.01.2020
comment
Работал как шарм! Однако вопрос: измеряемое расстояние в км? - person gooponyagrinch; 23.01.2020
comment
Расстояние рассчитывается в метрах. - person Dave2e; 23.01.2020