Filtering, selecting, and editing feeds
Source:vignettes/filtering-editing.Rmd
filtering-editing.RmdGTFSwizard separates three related operations:
- filtering removes records and prunes related GTFS tables;
- selection stores groups or subsets as metadata without removing rows;
- editing changes times or trip structure in the returned object.
Assign each result to a new object when you need to compare scenarios.
Filter a feed
Filter functions keep related identifiers consistent across the feed.
route_ids <- gtfs$routes$route_id[1:2]
route_feed <- filter_route(gtfs, route_ids)
service_id <- gtfs$trips$service_id[1]
service_feed <- filter_service(gtfs, service_id)
time_feed <- filter_time(gtfs, from = "06:00:00", to = "09:00:00")filter_stop() and filter_time()
deliberately retain partial trips. This is useful for corridor,
express-service, and time-window experiments. The retained trip can
therefore begin or end at a different stop than it did in the source
feed.
stop_ids <- gtfs$stops$stop_id[1:5]
partial_feed <- filter_stop(gtfs, stop_ids)Service patterns describe exact sets of services active on calendar
dates. Filtering a pattern retains precisely its represented dates and
services. With no explicit pattern, filter_servicepattern()
uses the most frequent active pattern.
typical_feed <- filter_servicepattern(gtfs)
#> Warning: GTFSwizard: no `servicepattern` supplied; using `servicepattern-1`,
#> the most frequent pattern.Use filter_date() only with dates inside the feed
calendar. Calendar and calendar-date tables are rebuilt to represent the
retained dates.
active_date <- gtfs$dates_services$date[
lengths(gtfs$dates_services$service_id) > 0
][1]
date_feed <- filter_date(gtfs, active_date)Select or group without filtering
selection() resembles dplyr::group_by() but
stores GTFS-specific selection metadata while leaving all feed tables
unchanged. Bare names create groups; logical expressions restrict the
records represented by those groups.
grouped <- selection(gtfs, route_id, direction_id)
attr(grouped, "selection")$groups
#> # A tibble: 6 × 6
#> route_id direction_id n_stop_calls routes trips stops
#> <chr> <int> <int> <list> <list> <list>
#> 1 6 0 1260 <chr [1]> <chr [63]> <chr [20]>
#> 2 6 1 1280 <chr [1]> <chr [64]> <chr [20]>
#> 3 7 0 150 <chr [1]> <chr [15]> <chr [10]>
#> 4 7 1 150 <chr [1]> <chr [15]> <chr [10]>
#> 5 8 0 290 <chr [1]> <chr [29]> <chr [10]>
#> 6 8 1 290 <chr [1]> <chr [29]> <chr [10]>
selected <- selection(
gtfs,
route_id,
route_id %in% route_ids
)
selected <- unselection(selected)Edit scheduled times
The editing functions return modified copies. They do not write back to the zip archive or object from which the feed was loaded.
trip_ids <- gtfs$trips$trip_id[1:2]
stop_ids <- gtfs$stops$stop_id[1:3]
delayed <- delay_trip(gtfs, trip = trip_ids, duration = 300)
faster <- edit_speed(gtfs, trips = trip_ids, stops = stop_ids, factor = 1.2)
fixed_dwell <- set_dwelltime(
gtfs, duration = 30, trips = trip_ids, stops = stop_ids
)
scaled_dwell <- edit_dwelltime(
gtfs, trips = trip_ids, stops = stop_ids, factor = 1.5
)duration is expressed in seconds. A speed or dwell-time
factor is a multiplier: values above one increase the
stated quantity and values between zero and one decrease it.
Edited times at or beyond 48 hours are wrapped into the next service-day clock range. To preserve non-decreasing stop times, the package may clamp subsequent times when wrapping would otherwise reverse their order. Extremely large adjustments can therefore change the intended durations; inspect the resulting timetable before using or exporting the scenario.
Split trips
split_trip() can create split + 1
approximately equal consecutive parts, or split at selected internal
stop IDs. It keeps the original stop order and updates references
handled by the package.
trip_id <- gtfs$trips$trip_id[1]
split_equal <- split_trip(gtfs, trip = trip_id, split = 1)
#> GTFSwizard: building straight-line shapes from ordered stop coordinates.
trip_stops <- gtfs$stop_times$stop_id[gtfs$stop_times$trip_id == trip_id]
if (length(trip_stops) > 2) {
split_at_stop <- split_trip(gtfs, trip = trip_id, stops = trip_stops[2])
}
#> GTFSwizard: building straight-line shapes from ordered stop coordinates.The first and final stops are not valid split boundaries. When
several trips are edited together, stop IDs are interpreted within each
selected trip. Each split boundary stop appears in both adjacent parts.
Supply either split or stops, not both; each
selected trip must have a matching internal stop when using
stops.
Merge and export scenarios
By default, merge_gtfs() suffixes identifiers and their
foreign-key references to avoid collisions between feeds.
merged <- merge_gtfs(
filter_route(gtfs, gtfs$routes$route_id[1]),
filter_route(gtfs, gtfs$routes$route_id[2])
)Export only when the scenario is ready. write_gtfs()
writes a new archive at the requested path and does not overwrite the
original unless the same path is explicitly supplied.
output <- tempfile(fileext = ".zip")
write_gtfs(delayed, output)
unlink(output)