Which train provides the best (or worst) service?

Sunny Ng
Good Service
Published in
3 min readFeb 11, 2019

Arguing about which subway route is the worst is one of New Yorkers’ favorite past-times—up there with shitting on Chicago “pizza” and being annoyed about tourists. Everyone thinks their route is the worst with their own personal anecdotes: residents of Central Queens gripe about train traffic stalling on the Queens Boulevard Line during rush-hours; North Brooklyn hipsters love to hate the L train — the most reliable line with computerized signals and the lowest headways; according to those who rely on it, apparently the R train hardly ever comes around these days.

Well, argue no more! goodservice.io now provides historical stats on how each route is performing—using the data that have been used to drive the website, but with some fancy-looking graphs. Now you can routes more objectively.

Screenshot of the new Stats pane for each train on goodservice.io

There’s quite a bit of information to unpack here, so allow me to explain.

Status History

goodservice.io currently uses 4 different statuses to describe service levels for each train and each line. Here is the definition of each status, in the order of how service levels are assigned:

  • Delay: If any of the trains currently running on that route’s estimated arrival time to the final station of its line has been delayed by over five minutes.
  • Service Change: If any of the trains running on the route is making a different stopping pattern than what was scheduled (which makes comparing service levels with the published schedules impossible) in the next hour.
  • Not Good: If the difference between estimated actual headways (i.e. time between each train’s arrival to each station) and the scheduled headways exceeds by two minutes. For instance, when the R train is scheduled every 12 minutes, there exists at least a gap between two trains that is over 14 minutes long.
  • Good Service: If none of the above is true and the trains are actually running on that route.

Note: if no trains are detected on a route where trains are scheduled, the No Service status is displayed. If trains are not scheduled for the route and there are no trains running on them, then the status is Not Scheduled. (When a route is Not Scheduled, its stats are not included in the graphs.)

Average Maximum Headway Discrepancy

This section provides data on the average maximum discrepancy between scheduled and estimated actual headway at any given time.

It sounds like a lot of big words, but let’s just say the average discrepancy on the number 1 train is +2.7 minutes, it means that at any time, we expect that a gap of+2.7 minutes more than what is scheduled exists between at least one pair of trains. For instance, when trains are scheduled to run every 8 minutes, you’d expect at least one gap of 10.7 minutes between any two consecutive trains.

Now you may wonder why I keep track of the maximum headway discrepancy instead of average or median. The main reason is that abnormally short gaps between trains shouldn’t be rewarded and shouldn’t count as something that counter-balances long gaps in service. For example, a train arriving every 7 minutes evenly is preferable to a train that arrives 2 minutes after the first train, followed by another 5 minutes after and then another train 14 minutes later.

Delays

The definition of delays is covered in a previous blog post. Since delays are currently tracked per trip, and there can be multiple trips delayed as attributed to one incident, to simplify the statistic, all delayed trips that occur for each route within each hour are grouped as one incident. The number of minutes delayed for each affected trip is used to calculate the average and longest durations of delays.

I used the Nivo graphing library for React to create the graphs. Please leave comments on what you think, including suggestions on how this can be further improved. Better yet, submit a pull request on GitHub!

goodservice.io is an open-source project to provide New York City subway riders a more detailed and up-to-date status page using public APIs. Please contribute on GitHub. Feel free to send me your feedback on Twitter to @_blahblahblah.

--

--