2013-11-07 4 views
0

В R у меня есть простой цикл с функцией внутри. Он принимает фрейм данных и просматривает строку непосредственно перед тем, как найти расстояние, а затем заполняет столбец dist. Все работает отлично, но для выполнения более 120 000 строк (более 5 минут) требуется много времени. Было бы полезно оценить способ (вероятно, векторизованный) ускорить эту функцию. Просто для полного раскрытия, я задал аналогичный вопрос раньше, но параметры, которые мне нужны, в конечном итоге изменились, и я не смог адаптировать этот ответ к новым изменениям.Ускорение простого цикла с векторизации в R

Образец данных:

lat <- c(32.88084254, 32.88058801, 32.88034199, 32.88027623, 32.88022759) 
lon <- c(-117.23543042, -117.23606292, -117.23654377, -117.23723468, -117.23788206) 
tripData <- data.frame(cbind(lat, lon)) 
tripData["dists"] <- NA 


for (i in 2:nrow(tripData)) { 
tripData$dists[i] <- geodist(tripData[i, c("lat")], 
           tripData[i, c("lon")], 
           tripData[i-1, c("lat")], 
           tripData[i-1, c("lon")], 
           units="km")*1000 
} 

ответ

4

Предполагая, что вы используете функцию geodist из пакета GMT, это документация утверждает, что она уже является векторизация:

gmt::geodist(tripData[2:5, "lat"], 
     tripData[2:5, "lon"], 
     tripData[1:4, "lat"], 
     tripData[1:4, "lon"], 
     units="km")*1000 

Небольшая заметка: прекратить делать data.frame(cbind(lat, lon)). Вы ничего не получаете по сравнению с data.frame(lat,lon), и вы рискуете многого.

+1

+1 Или, в более общем смысле, 'tripData $ lat [-1]' и 'tripData $ lat [- nrow (tripData)]', но это немного больше. –

+0

Это прекрасно, так намного быстрее. Мне нужно внимательно прочитать документацию. Кроме того, спасибо за наконечник. Весь мой R является самоучкой, поэтому я заканчиваю тем, что упускаю из виду много особенных особенностей. – Misc

2

Вы можете векторизации вызовов функций с несколькими аргументами, используя mapply (многомерный sapply).

n <- nrow(tripdata) 
mapply(geodist, 
     tripdata$lat[-1], tripdata$lon[-1], 
     tripdata$lat[-n], tripdata$lon[-n], 
     moreArgs=list(units="km"))*1000 
Смежные вопросы