Вычисление расстояния между двумя широтами и длинами внутри фрейма данных

#r #geosphere

#r #Геосфера

Вопрос:

У меня есть набор данных, который включает широту и долготу для каждого отдельного адреса свойства. Кроме того, я создал две новые колонки (icelat, icelog), которые включают широту и долготу для одного конкретного здания в штате Юта.

Данные выглядят следующим образом:

                                RowID PropertyAddressLatitude PropertyAddressLongitude  icelat    icelog
1: 000D655E-1AEA-E811-80C3-3863BB430E3F                38.65195                -109.4085 40.2351 -111.6384
2: 000F655E-1AEA-E811-80C3-3863BB430E3F                38.50952                -109.4763 40.2351 -111.6384
3: 0012CB31-D004-E911-80C7-3863BB43E813                      NA                       NA 40.2351 -111.6384
4: 0013655E-1AEA-E811-80C3-3863BB430E3F                38.54184                -109.5031 40.2351 -111.6384
5: 0014655E-1AEA-E811-80C3-3863BB430E3F                      NA                       NA 40.2351 -111.6384
6: 0015655E-1AEA-E811-80C3-3863BB430E3F                      NA                       NA 40.2351 -111.6384
 

Я хотел бы создать новый столбец под названием «расстояние», который представляет собой расстояние в милях от широты и долготы каждого объекта до конкретного здания в штате Юта.

Я пробовал несколько различных методов использования пакета Geosphere, но не могу заставить его просматривать все наблюдения ‘propertyaddresslatity’ и ‘PropertyAddressLongitude’ и автоматически выполнять вычисления с ‘icelat’ и ‘icelog’.

Ответ №1:

Единицы измерения по умолчанию будут в метрах, поэтому я произведу преобразование на месте.

 meter2mile <- 0.000621371
dat[, distance := meter2mile * geosphere::distVincentyEllipsoid(
        cbind(PropertyAddressLongitude, PropertyAddressLatitude),
        cbind(icelog, icelat)) ]
dat
#                                   RowID PropertyAddressLatitude PropertyAddressLongitude  icelat    icelog distance
# 1: 000D655E-1AEA-E811-80C3-3863BB430E3F                38.65195                -109.4085 40.2351 -111.6384 161.7148
# 2: 000F655E-1AEA-E811-80C3-3863BB430E3F                38.50952                -109.4763 40.2351 -111.6384 166.0397
# 3: 0012CB31-D004-E911-80C7-3863BB43E813                      NA                       NA 40.2351 -111.6384       NA
# 4: 0013655E-1AEA-E811-80C3-3863BB430E3F                38.54184                -109.5031 40.2351 -111.6384 163.4240
# 5: 0014655E-1AEA-E811-80C3-3863BB430E3F                      NA                       NA 40.2351 -111.6384       NA
# 6: 0015655E-1AEA-E811-80C3-3863BB430E3F                      NA                       NA 40.2351 -111.6384       NA
 

Данные

 dat <- as.data.table(structure(list(RowID = c("000D655E-1AEA-E811-80C3-3863BB430E3F", "000F655E-1AEA-E811-80C3-3863BB430E3F", "0012CB31-D004-E911-80C7-3863BB43E813", "0013655E-1AEA-E811-80C3-3863BB430E3F", "0014655E-1AEA-E811-80C3-3863BB430E3F", "0015655E-1AEA-E811-80C3-3863BB430E3F"), PropertyAddressLatitude = c(38.65195, 38.50952, NA, 38.54184, NA, NA), PropertyAddressLongitude = c(-109.4085, -109.4763, NA, -109.5031, NA, NA), icelat = c(40.2351, 40.2351, 40.2351, 40.2351, 40.2351, 40.2351), icelog = c(-111.6384, -111.6384, -111.6384, -111.6384, -111.6384, -111.6384)), row.names = c(NA, -6L), class = c("data.table", "data.frame")))
 

(Я сделал вывод data.table из ваших выборочных данных, пожалуйста, сообщите, если это было неверно.)

Комментарии:

1. Идеально! Теперь, когда я вижу, как ты это сделал, это тоже имеет смысл. Вот почему я люблю этот сайт … узнавайте что-то новое буквально каждый раз, когда я публикую вопрос.

2. Кстати, мой выбор distVincentyEllipsoid не является строго обязательным. В зависимости от вашего баланса производительности и точности, вы можете выбрать distHaversine , distGeo , или distMeeus , в зависимости от ваших данных, убеждений и нескольких вещей за пределами моей рулевой рубки.

3. В любом случае я обычно использую эллипсоид, поскольку разработчик пакета Geosphere сказал, что это часто самый точный расчет.

4. Это одна из причин, по которой я его использую (и в моем приложении я ищу расстояния в субметровом масштабе). Однако это может быть значительно медленнее, чем distHaversine . Если вы смотрите на сотни миль, то указанные вами точки отличаются друг от друга менее чем на 200 метров. Более низкая производительность является проблемой только тогда, когда вы делаете это миллионы раз (что я и делаю).