Есть ли функция R, которая может заменить цикл, который использует несколько столбцов нескольких фреймов данных? - PullRequest
0 голосов
/ 25 мая 2019

Цель состоит в том, чтобы рассчитать расстояние между всеми счетчиками трафика вдоль шоссе и всеми заправочными станциями в Бельгии.Поэтому мне нужно расстояние от каждой стойки до каждой станции.В кадре данных Бельгии вы можете найти продольные и поперечные расстояния счетчиков, в кадрах данных станций вы можете найти те из АЗС.

Пока я использовал цикл for, это прекрасно работает для небольших кадров данных, ноочень медленный для огромных, что характерно для циклов.

Stations1<-Stations[,c("lon","lat")] names(Stations1)<-NULL BELGIUM1<-BELGIUM[,c("lon","lat")] names(BELGIUM1)<-NULL

distancesToStation <- data.frame(matrix(NA,nrow = nrow(Stations),ncol = nrow(BELGIUM)))

     for (i in 1:nrow(BELGIUM)) {
     for (j in 1:nrow(Stations)){
          distancesToStation[j,i] = gmapsdistance(origin = 
                 paste0(Stations1[j,1],"+",Stations1[j,2]),
                 destination =  
                           paste0(BELGIUM1[i,1],"+",BELGIUM1[i,2]),
                 mode = "driving",key = "X")[[2]]/1000 

}}

save(distancesToStation, file = 'DistanceMatrix.Rdata')

Этот код отлично работает для небольших кадров данных,Есть ли способ ускорить это?

1 Ответ

0 голосов
/ 25 мая 2019

Сначала генерируются все комбинации с перекрестным соединением merge(..., ..., by = NULL), а затем просто используется векторизованный подход для gmapsdistance.Обратите внимание, что у меня нет API или чего-то еще, поэтому эту часть я не смог протестировать.

BELGIUM <- data.frame(counters = 1:10
                      , lat = runif(10, 10, 20)
                      , lon = runif(10, 40, 50))

STATIONS <- data.frame(station = LETTERS[1:10]
                       , lat = runif(10, 10, 20)
                       , lon = runif(10, 40, 50))

All_Combos <- merge(BELGIUM, STATIONS, by = NULL)

All_Combos$distancesToStation = gmapsdistance(origin = paste0(All_Combos$lat.y,"+",All_Combos$lon.y),
                                   destination =  paste0(All_Combos$lat.x,"+",All_Combos$lat.x),
                                   mode = "driving",key = "X")[[2]]/1000 
...