Оптимизация поднабора с помощью цикла for в R

Я использую R и RStudio для анализа каналов общественного транспорта GTFS и для создания графиков с использованием ggplot2. Код в настоящее время работает нормально, но довольно медленно, что проблематично при работе с очень большими CSV, как это часто бывает здесь.

Самая медленная часть кода выглядит следующим образом (с некоторым контекстом): цикл for, который выполняет итерацию по фрейму данных и помещает каждую уникальную поездку во временный фрейм данных, из которого извлекаются экстремальные значения прибытия и отправления (первая и последняя строки):

# Creates an empty df to contain trip_id, trip start and trip end times
Trip_Times <- data.frame(Trip_ID = character(), Departure = character(), Arrival = character(), stringsAsFactors = FALSE) 

# Creates a vector containing all trips of the analysed day
unique_trips = unique(stop_times$trip_id)

# Iterates through stop_times for each unique trip_id and populates previously created data frame
for (i in seq(from = 1, to = length(unique_trips), by = 1)) {
  temp_df <- subset(stop_times, trip_id == unique_trips[i])
  Trip_Times[nrow(Trip_Times) + 1, ] <- c(temp_df$trip_id[[1]], temp_df$departure_time[[1]], temp_df$arrival_time[[nrow(temp_df)]])
} 

stop_times df выглядит следующим образом с некоторыми фидами, содержащими более 2,5 миллионов строк, дающих около 200 000 уникальных отключений, следовательно, 200 000 циклов итераций...

head(stop_times)
trip_id arrival_time departure_time stop_sequence
1 011_0840101_A14      7:15:00        7:15:00             1
2 011_0840101_A14      7:16:00        7:16:00             2
3 011_0840101_A14      7:17:00        7:17:00             3
4 011_0840101_A14      7:18:00        7:18:00             4
5 011_0840101_A14      7:19:00        7:19:00             5
6 011_0840101_A14      7:20:00        7:20:00             6

Кто-нибудь сможет посоветовать мне, как оптимизировать этот код, чтобы получить более быстрые результаты. Я не верю apply можно использовать здесь, но я вполне могу ошибаться.

2 ответа

Решение

Это должно быть просто с dplyr...

library(dplyr)

Trip_Times <- stop_times %>%
              group_by(trip_id) %>%
              summarise(departure_time=first(departure_time),
                        arrival_time=last(arrival_time))

Мы можем использовать data.table

library(data.table)
setDT(stop_times)[, .(departure_time = departure_time[1L], 
                    arrival_time = arrival_time[.N]) , by = trip_id]
Другие вопросы по тегам