Я анализирую свою историю местоположений в Google (сбрасывается с здесь , если кому-то интересно). Теперь в набор данных не входит ни одного поля, содержащего название города, но, учитывая, что для каждой строки есть комбинация широта / долгота, мы можем вычислить ее самостоятельно.
Учитывая, что мой набор данных имеет длину 1,2 млн строк, используя бесплатные API геокодирования вне таблицы (трафик c явно задушен).
Данные
Пара аэропортов
airport_coords <-
structure(
list(
V1 = c("LIMC", "LIRF"),
V2 = c("MXP", "FCO"),
V3 = c("MALPENSA", "FIUMICINO"),
V4 = c("MILANO", "ROME"),
V5 = c("ITALY", "ITALY"),
V6 = c(45L, 41L),
V7 = c(37L, 48L),
V8 = c(53L, 46L),
V9 = c("N", "N"),
V10 = c(8L, 12L),
V11 = c(43L, 15L),
V12 = c(40L, 11L),
V13 = c("E", "E"),
V14 = c(234L, 4L),
V15 = c(45.631, 41.813),
V16 = c(8.728,
12.253)
),
row.names = c(NA,-2L),
class = "data.frame"
)
А вот несколько строк упрощенной версии история местоположений от Google
loc_history <-
structure(list(latitudeGPS = c(41.8713521, 41.8713478, 41.8714064,
41.8714201, 41.8713419, 41.8713981, 41.8713237, 41.8714538, 41.8713845,
41.8714139, 41.8714417, 41.8714538, 41.8714417, 41.8714538, 41.8714538,
41.8714538, 41.8714538, 41.8714538, 41.8714594, 41.8714594),
longitudeGPS = c(12.4414861, 12.441478, 12.4415342, 12.4415539,
12.4414757, 12.4415345, 12.4414538, 12.4415871, 12.441514,
12.4415466, 12.4415735, 12.4415871, 12.4415735, 12.4415871,
12.4415871, 12.4415871, 12.4415871, 12.4415871, 12.4415954,
12.4415954)), row.names = c(NA, 20L), class = "data.frame")
Лоскутное решение
Мой подход заключается в том, чтобы вычислить расстояние между координатами широты и долготы и аэропортом городов, которые меня интересуют (от это набор данных), предполагая, что если расстояние <50 км, я смотрю на город, где расположен аэропорт (который должен быть достаточно точным для моих нужд). Я написал следующее <code>for l oop (я знаю ...), которое работает, хотя и очень медленно. Я ищу способы превратить этот мусорный бак в нечто более быстрое, используя векторизованные функции, такие как семейство apply
.
library(raster) # for pointDistance
library(dplyr)
# Init empty df to store results
dist <- data.frame(
dist_mt = NA,
city = NA
)
for (i in 1:nrow(loc_history)) {
# Tmp df to store computed distances
tmp <- data.frame(
dist_mt = NA,
city = NA
)
for (x in 1:nrow(airport_coords)) {
# Coompute point - airport distance
v <- pointDistance(c(data[i,]$latitudeGPS,
data[i,]$longitudeGPS),
c(airport_coords[x,]$V15,
airport_coords[x,]$V16),
lonlat = TRUE)
# Append to tmp dataframe
tmp[x,]$dist_mt <- v
tmp[x,]$city <- airport_coords[x,]$V4 # Keep city label
}
# Append city if distance < 50km
if (min(tmp$dist_mt) <= 50000) {
dist[i,] <- filter(tmp, dist_mt == min(dist_mt))
} else {
dist[i,]$city <- "other"
}
}
Performance
Для обработки l oop требуется около 4 секунд ~ 1.0000 строк. При наличии 1,2 млн. Строк для его запуска потребуется ~ 80 минут.