NYC Subway Crime Rates and Ridership, 1998–2026
NYPD subway complaints by month, day, hour and station since 2014, with ridership where available; transit-system felonies since fiscal 1998
No synthetic records. Complaints and arrests come from NYPD records; fare-evasion shares are MTA estimates. Monthly paid rides before March 2020 are modelled from official yearly totals, and total entries are estimated throughout. Check paid_rides_method and data_dictionary.csv before using a rate.
- Records
- Administrative records
- Covers
- Subway complaints by month, day, hour and station, January 2014 to June 2026 (June incomplete); paid rides by month July 1997 to September 2026, by day from March 2020, by station from February 2017; Transit arrests January 2014 to June 2026; transit-system major felonies by fiscal year 1998 to 2026.
- Place
- New York City subway (NYPD premises 'TRANSIT - NYC SUBWAY'), by station complex; the fiscal series counts the whole transit system, and the context file the whole city and its buses
- Version
- 2.0,
- Licence
- Mixed: CC BY 4.0 for what we added; the government's records under their publishers' terms; code MIT (LICENSE.md)
- Built for
- Per subway ride, major felonies fell for thirty years. Felony assault broke from the fall. (version 1.0)
This dataset pairs complaints recorded in the New York City subway by the New York City Police Department (NYPD), January 2014 to June 2026, with ridership from the Metropolitan Transportation Authority (MTA), so that complaint counts can be compared as rates per million paid rides and per million estimated entries, paid or not. The complaint files cover months, days, hours, stations and victim groups, and subway_complaint_records.csv has one row per complaint, with categorical fields and gaps kept from the source. A separate series covers major felonies across the transit system back to fiscal 1998. Start with subway_crime_monthly.csv: one row per month, with counts, rides and rates already combined.
The story in these files
Every few months a headline asks whether the subway is safe, and most answers count crimes. A count alone cannot say whether a ride became riskier. The subway carried 1.7 billion paid rides in 2019 and 640 million in 2020, so the same number of crimes meant something very different in the two years. To ask about risk you need two things side by side: what happened, and how many people were there when it happened.
This dataset puts them side by side: the NYPD's records of complaints in the subway, with the codes that tell an assault on a police officer from any other assault or a pickpocketing from a phone taken from a sleeping rider, and the MTA's counts of entries to the system. Around them sits the context a careful reader asks for next: recorded crime across the whole city and on its buses, arrests by transit police, the shelter census, Central Park's weather, and a dated list of the laws, policing announcements and service changes that help explain changes in the series.
Three tensions run through the files, and they are what make them worth more than a table of rates. The first is the denominator, the number of rides or entries a complaint count is divided by: the MTA counts paid rides, and the share of people who do not pay more than doubled after 2019, so the choice of denominator alone moves a comparison. The second is that a complaint records police work as well as crime; theft of services, the offence that covers fare evasion, shows how far the two can part. The third is that some numbers here are counted and some are modelled, and the monthly paid rides before March 2020 are the largest modelled piece; the MTA's station counts, summed, now let you test that model month by month. The monthly table carries the method and reporting flags, and the finer files carry the reporting flags of their month or year, so the distinctions travel with the data.
Start here
Open subway_crime_monthly.csv first. Each row is a month, by the month the crime began, and it already holds the rates, so no join is needed to start. Compare *_per_m_paid (per million paid rides) with *_per_m_entries (per million estimated entries, paid or not). For a recent comparison, use January to May rather than June 2026, which is still filling in, and remember that complete marks a reporting window, not a final count. The example below works out the January-to-May felony-assault rate for 2019, 2025 and 2026 both ways.
import pandas as pd
m = pd.read_csv("subway_crime_monthly.csv", dtype={"month": "string", "complete": "boolean",
"paid_rides": "Int64", "entries_est": "Int64",
"late_reports_all": "Int64", "late_reports_six_major": "Int64"})
# January-May rate for each year: total complaints divided by total rides or entries,
# not the mean of monthly rates; a window with any missing entries stays missing
w = m[m["month"].str[5:].isin(["01", "02", "03", "04", "05"])]
g = w.groupby("year").agg(felony_assault=("felony_assault", "sum"), paid=("paid_rides", "sum"),
entries=("entries_est", lambda x: x.sum() if x.notna().all() else pd.NA))
g["per_m_paid"] = 1e6 * g["felony_assault"] / g["paid"]
g["per_m_entries"] = 1e6 * g["felony_assault"] / g["entries"].astype("Float64")
print(g.loc[[2019, 2025, 2026]].round(2))
It prints:
felony_assault paid entries per_m_paid per_m_entries
year
2019 157 702461957 730969778 0.22 0.21
2025 267 523745387 580922734 0.51 0.46
2026 272 537074361 599623313 0.51 0.45
How the files join:
- Join
subway_ridership_monthly.csvandcity_context_monthly.csvtosubway_crime_monthly.csvonmonth: one row each per month, January 2014 to June 2026. - For
subway_crime_daily.csvandsubway_crime_by_hour.csv, first add up the complaint counts bymonth; fortransit_arrests_monthly.csv, add uparrestsbymonth. Then join onmonth. Add up counts, never rates or flags. subway_complaints_by_offence_monthly.csvandsubway_complaints_by_code_monthly.csvjoin the monthly table onmonth, many rows to one.fare_evasion_quarterly.csvjoinssubway_ridership_monthly.csvonyearandquarter, one quarter to three months.- For one year,
subway_station_crosswalk.csvjoinssubway_stations_annual.csvoncomplex_id, many places to one complex; across years the join multiplies rows, so never add up the crosswalk's complaints after it.subway_complaint_records.csvjoins the station table oncomplex_idandyear(leave outlate_reportrows to match the monthly table). - For
transit_major_felonies_fiscal.csv, add up the monthly table's counts and rides byfiscal_yearand recompute the rates; the monthly table starts halfway through fiscal 2014, so its first whole fiscal year is 2015. The fiscal file counts the whole transit system, not the subway premises. events.csvjoinssources.csvonsource_id.- Keep every row of the monthly table when joining: an estimate the MTA has not published stays empty.
A few terms
A few terms used throughout. law_category is the NYPD's legal category: felony, misdemeanour or violation. The six major felonies are murder, rape, robbery, felony assault, burglary and grand larceny, leaving out grand larceny of a motor vehicle; the subway-premises records hold no murders. key_code (the NYPD's KY_CD) is the broad offence code and pd_code (PD_CD) the finer internal code within it. A station complex is the MTA's grouping of stations joined by passageways. Fiscal years run from July to June and are named for the year they end in.
Five questions to start with
-
Compared with 2019, how have recorded felony rates changed per paid ride and per estimated entry? The MTA counts paid rides. About 4% of subway entries in early 2019 were unpaid, and about 10% in early 2025. If entries and recorded complaints stayed the same, a higher unpaid share would mean fewer paid rides and so a higher rate per paid ride. Compare the monthly table's rates per paid ride and per estimated entry, then use
subway_ridership_monthly.csvto move the unpaid share one percentage point above or below the MTA's estimate: the same complaints, two denominators, and a choice about which one to report.Files:
subway_crime_monthly.csv,subway_ridership_monthly.csv,fare_evasion_quarterly.csv -
Which offences fell with ridership in 2020, and which did not? In 2020 the subway carried 38% of its 2019 rides. Grand larcenies fell by half, closer to the fall in riders, but felony assaults stayed at 96% of their 2019 number and robberies at 105%. The daily and monthly files let you measure, offence by offence, how closely recorded complaints track ridership, and ask what the offences that held steady have in common.
Files:
subway_crime_annual.csv,subway_crime_monthly.csv,subway_crime_daily.csv -
Which station complexes have the highest major felony complaint rates per entry: the busy hubs, or quieter stations? Counts and rates rank stations differently. In 2025 the Bronx's station complexes recorded almost three times Manhattan's rate of major felony complaints per entry. The station table pairs matched complaints with MTA station entries for each complex and year. Compare the rankings by count and by rate, then recalculate them without the complaints matched less surely, using
station_matchin the record file.Files:
subway_stations_annual.csv,subway_station_crosswalk.csv,subway_complaint_records.csv -
Are major felony complaint rates higher at weekends than on weekdays? From 2023 to 2025 the rate of major felony complaints per ride was about twice as high at weekends as on weekdays. Use the daily file to compare this gap across months and offences. The hourly file shows when complaints began, but there are no hourly ridership figures here, so it cannot show whether rates per ride differ by hour.
Files:
subway_crime_daily.csv,subway_crime_by_hour.csv -
Theft of services: what do complaints, arrests and the MTA's survey each measure? Complaints of theft of services, the offence that covers fare evasion, went from 54 in 2019 to 13,009 in 2025. Arrests for it in the Transit jurisdiction went from 2,712 to 12,475 over the same years, yet they were 22,776 in 2014, when complaints numbered 50. The MTA's own survey has the unpaid share rising from about 4% to 10%. Three records of one behaviour move three different ways. Set side by side month by month, they show where and when they diverge; they cannot by themselves divide that divergence between behaviour and record-keeping.
Files:
transit_arrests_monthly.csv,subway_crime_monthly.csv,fare_evasion_quarterly.csv,city_context_monthly.csv
20 more questions are listed below and set out in QUESTIONS.md.
For learning and teaching
subway_complaint_records.csv holds 187,739 complaint records: the 187,630 complaints in the monthly table (January 2014 to June 2026) and the 109 late reports, filed in 2026 about earlier years, two of them about 2005 and 2006 (late_report is true; leave them out to reproduce the monthly table). Each row has the fields the NYPD publishes: when the offence began, ended and was reported, the offence and its codes, attempted or completed, the place, and the age group and sex of the victim and of the suspect as recorded. Most columns are categorical, from a handful of values (law category, borough, day of the week) to hundreds (station, offence code): a good set for classification (predicting a category), encoding (turning labels into numbers) and clustering (grouping similar records). Identical rows are separate complaints, so do not remove them as duplicates.
Its gaps are real. Empty cells correspond to blanks or (null) in the NYPD's file and to nothing else: there is no end date for 16,297 complaints, no suspect age group for 33,830 and no suspect sex for 31,482. Values the NYPD recorded as UNKNOWN or U are kept as they are, so a missing value and a value recorded as unknown can be told apart. missing_values.csv counts the empty cells in every file and says why they are empty.
Two kinds of information are left out on purpose: the complaint number, and the race of victims and suspects. The file is for learning, not for identifying anyone or modelling race.
Before you use these numbers
These are recorded crimes, not crime. A complaint is a report the police recorded, so the counts move with policing as well as with crime: where officers are, what they look for and how they write it down. Theft of services shows how far the two can part. Its complaints rose from 54 in 2019 to 13,009 in 2025, while arrests for it in the Transit jurisdiction rose from 2,712 to 12,475; in 2014 those arrests numbered 22,776 and the complaints 50. In 2014 an arrest for theft of services rarely came with a complaint record; by 2025 the complaints outnumbered the arrests. Read the complaint count as a record of enforcement, not as a measure of fare evasion. The six major felonies are offences victims mostly report themselves, but they are not immune.
Monthly rides before March 2020 are modelled. Through December 2019 each year's official total is spread over its months by one inferred monthly pattern; January and February 2020 together are 2020's official total less the daily figures from March. paid_rides_method says which applies to each row. The yearly totals are counted; the split into months is not. The MTA's station counts, added up, give an observed comparison from February 2017 to February 2020: in every month the counted rides are within 6% of the modelled ones, in every November 3% to 4.5% above them, and over January to May 2019, the window the article compares, within 0.4%.
Seasonal patterns and breaks are partly built in. Before March 2020 every year's rides follow the same imposed monthly pattern, so seasonal variation in rates then partly reflects how the denominator was built, and the change to counted rides coincides with the pandemic. Quarterly fare-evasion estimates are reused for each month of their quarter and are not independent monthly measurements. A rate model should account for uncertainty in rides and entries, complaint counts that vary more than a simple count model assumes (overdispersion), and links between successive months; where station_sum_rides exists, test how the conclusions change with it.
Entries are an estimate on an estimate. entries_est divides paid rides by one minus the MTA's quarterly fare-evasion share. The MTA publishes margins from 2020 (0.8 to 1.6 percentage points; 0.8 to 1.0 in the quarters the article compares; confidence level not stated), none for 2018 and 2019, and no estimate at all for April to June 2020. The scenarios in subway_ridership_monthly.csv, with the unpaid share one percentage point above or below the estimate, show how much it moves a comparison; they are scenarios, not confidence bounds, and do not cover every published margin.
Definitions changed. Each year is counted under that year's law. New York expanded the legal definition of felony assault to more transit workers from 25 September 2022 and 19 July 2024, and to retail workers from 17 October 2024 (felony_assault_widenings_in_force), and redefined rape in a law signed on 30 January 2024 whose effective date the saved bill text does not settle (events.csv). A complaint carries an offence code, not the section charged, so the counts cannot say how many assaults qualified only under a newer law.
Two places, two sources. The complaint counts are for the subway premises. The fiscal series is the Mayor's Management Report's count for the whole transit system, divided by subway rides in the same months: a descriptive ratio, not the subway-premises complaint rate. The two are close (2,093 against 2,176 for the year to June 2026, with June incomplete in the first) but not the same count. Compare within a file, not across them.
The newest months are incomplete. June 2026 has reports only to 30 June 2026, and every recent month gains late reports for a while (about 5% of December 2025's felonies were filed in the new year). Complaints reported in 2026 about months before 2026 (109) are not added back; late_reports_all gives them by month (107 of them; the other two concern months before 2014). complete is false for December 2025 and June 2026, and the yearly files count such months in months_incomplete. The report-delay file shows how long each offence took to come in; its newest years have had less time for the slowest reports.
Times and places are approximate. The start time is the one the complaint records. Many are rounded to the hour, and 00:01 is more than fifteen times as common as 00:02, the mark of a default, so the first hour after midnight is inflated; all_complaints_on_the_hour shows how much rounding there is. A station is matched from the place the NYPD records, and about 8% of complaints are matched less surely (match in the station-matching table). A zero in the station table means no complaint was matched to that complex that year, not that nothing happened there, and a station closed for part of a year has fewer months of entries.
No murders in the subway premises records. The complaint files hold no murder with the subway as its place, so their "six major felonies" are in practice five. That is not evidence that no murder happened in the subway: the transit system's few murders are in the fiscal series.
Not a measure of risk to one rider. A rate per ride is an average over very different trips, stations and hours. Policing announcements in events.csv are announcements, not measured effects, and nothing here says why a rate moved: the files can show what changed alongside it, not what caused it.
Reading the files
- Empty cells mean unavailable or not applicable, never zero. Load counts and rides as nullable integers (pandas
Int64, integer columns that can hold missing values). - The two complaint tables by month are sparse: within a covered month (January 2014 to June 2026), an offence with no row had no complaints. Their keys are
month,law_category,offence,complaint_fileandmonth,key_code,offence,pd_code,complaint_file. The daily, hourly and station files are full grids: every day, hour or complex-year is present. - In the count tables,
(null)inoffence,station_name,victim_age_groupand similar columns is the label the NYPD's file prints for a blank, kept so that its complaints are counted. Insubway_complaint_records.csvthe same blank is an empty cell, ready to be treated as missing. Labels keep the source's spelling (for exampleHARRASSMENT 2). missing_values.csvlists every column with empty cells, how many and why: a figure was not published, does not apply, or is blank in the source.- A month, day or hour is when the offence began (
CMPLNT_FR_DTandCMPLNT_FR_TM), not when it was reported; an arrest's month is the month of the arrest. events.csvkeeps each date at the precision the source gives (YYYY, YYYY-MM or YYYY-MM-DD): read it as text, and do not turn a year or a month into a day.- Rides and entries are added up from unrounded values, then rounded; rates use the unrounded values and are rounded to four decimals. Annual and fiscal totals can therefore differ by a few rides from the sum of the monthly integers shown.
official_annual_totalrepeats on every month of its year insubway_ridership_monthly.csv, andnyc_populationon every month of its year incity_context_monthly.csv: take one value per year, never add them up.- Every finer table counts the same complaints as the monthly table: added up to the month or the year, the daily, hourly, station, victim and report-delay files equal it exactly, and the record file does too once its late reports are left out. The build refuses to write any file unless these checks pass.
Method
The complaint counts are the NYPD's records whose premises is the subway, counted by the month, day and hour the offence began. The monthly counts by offence were retrieved on 26 September 2026, those by offence code on 11 October, and the finer extracts (day, time, report date, codes, station, victim group, and every complaint's descriptive fields) on 19 October. The build checks that each extract, added up by month, equals the earlier files in every cell, so every table counts the same complaints, and that the record file is the NYPD's extract record for record. The 2026 year-to-date file ends with reports to 30 June 2026; its complaints about earlier years (late reports) are kept out of the earlier years' counts and shown in their own columns.
Monthly paid rides before March 2020 are estimates. Through December 2019, each calendar year's official total is spread over its months by an inferred 2019 monthly pattern, rebuilt from the MTA's comparisons of each 2024 day with its 2019 equivalent, with 29 February 2024 left out. January and February 2020 together are 2020's official total less the daily counts for March to December, split between the two months by the same pattern, February's weight multiplied by 29/28 for its leap day. From March 2020 a month's rides are the sum of the MTA's daily figures, which come within 0.2% of the official yearly totals for 2021 to 2024. Entries are each month's paid rides divided by one minus the MTA's unpaid share for its quarter, taken to hold evenly through the quarter. The MTA's station counts, added up by month (station_sum_rides), are a separate series from February 2017: they measure entries a little differently (about 1% above the daily totals since 2024) and are kept beside the paid rides, not mixed into them.
Stations are matched by place. The NYPD records a station name and coordinates for every subway complaint, but its names are older or shared ("125 STREET" is four stations). Each recorded place is matched to the nearest MTA station within 300 metres whose name shares an identifying word; failing that, to the station sharing most words within 800 metres (1,500 for two or more words), and failing that, to the nearest station of all. The station-matching table keeps the distance and the kind of match for every place: 92% of complaints are matched by name within 300 metres and under 1% are left uncertain. A station complex is the MTA's grouping of stations joined by passageways; its name, borough and coordinates are the MTA's current ones.
Every row of the article's own data file is reproduced from these files before they are published, every figure this card quotes is checked against them, and the build is checked to rebuild byte for byte.
Files
| File | Rows | Size | What it holds |
|---|---|---|---|
| subway_crime_monthly.csv | 150 | 29 KB | Start here. One row per month, January 2014 to June 2026, with subway complaint counts, paid rides, estimated entries and rates per million of each. Includes flags for the ridership method and the reporting window. |
| subway_crime_annual.csv | 12 | 3 KB | One row per whole calendar year, 2014 to 2025 (2026 is not included): the monthly table added up, with the year's official ride total beside the rides used and the flags a year inherits from its months. Reproduces the article's year-by-year chart. |
| subway_ridership_monthly.csv | 351 | 29 KB | Monthly paid subway rides from July 1997 (the start of fiscal 1998) to September 2026, with method flags, official yearly totals and fare-evasion estimates. Includes estimated entries and two scenarios with the unpaid share one percentage point higher or lower. Station entries, added up from February 2017, check the modelled months. |
| fare_evasion_quarterly.csv | 34 | 911 B | The MTA's quarterly estimate of the share of subway entries that are unpaid, from traffic checkers' counts at a sample of stations, with its published margin of error, as published on Open NY. |
| transit_major_felonies_fiscal.csv | 29 | 5 KB | The long view: the Mayor's Management Report's major felonies in the whole transit system for each fiscal year (July to June), 1998 to 2026, beside the subway's paid rides in the same months. A ratio across two scopes, not the subway-premises complaint rate. |
| subway_crime_daily.csv | 4,564 | 387 KB | One row per day, 1 January 2014 to 30 June 2026: complaints by the day the offence began, the subway's paid rides that day (from 1 March 2020) and Central Park's temperature, rain and snow. For weekday and weekend, weather and before-and-after questions. |
| subway_crime_by_hour.csv | 7,200 | 279 KB | Complaints by month, weekday or weekend, and the hour the offence began (0 to 23), every hour present. For when in the day crime happens and for the overnight closure of May 2020 to May 2021. Times are as recorded and often rounded. |
| subway_stations_annual.csv | 5,551 | 578 KB | One row per station complex and year, with the complaints matched to it, its entries and rates per million entries. Entries begin in February 2017, and a rate needs entries for every month of the year's complaints. 2026 covers January to June. Every complex is listed in every year. |
| subway_station_crosswalk.csv | 2,849 | 247 KB | Every place the NYPD records for a subway complaint (a station name, a borough and coordinates), with how many complaints it holds and the MTA station complex it is matched to, the distance and the kind of match. Check or redo the matching here. |
| subway_complaints_by_offence_monthly.csv | 4,823 | 343 KB | Complaint counts by month, law category and the NYPD's offence label, as the files print it. This table supplies the monthly table's offence and law-category totals. Sparse: within a covered month, an offence with no row had no complaints. |
| subway_complaints_by_code_monthly.csv | 12,037 | 1.1 MB | Complaint counts by month, the NYPD's key offence code and its internal offence code, which tell kinds of the same offence apart: assaults on police from other assaults, pickpocketing from bag-snatching, theft of services from other theft. Sparse, like the offence table. |
| subway_victims_annual.csv | 3,668 | 174 KB | Complaints by year, law category, offence, and the victim's age group and sex as the NYPD records them. Many complaints have no person as victim: offences against the State, such as fare evasion, and against businesses. 2026 covers January to June. |
| subway_report_delay_annual.csv | 728 | 34 KB | Complaints by year, offence group and the delay between the day the offence began and the day it was reported, every band present. It describes delays among the complaints already in the files: the late reports are not included, the newest years have had less time for the slowest reports, and reports still to come cannot be seen. |
| transit_arrests_monthly.csv | 9,204 | 646 KB | Arrests the NYPD records in its Transit jurisdiction (jurisdiction code 1, the subway), by month of arrest, law category and the offence charged, with its codes. An arrest is not linked to a complaint, and counts when it is made. |
| city_context_monthly.csv | 150 | 14 KB | One row per month: recorded crime across the whole city, the subway included, counted the way the subway's is; the subway's share of it; the city's population; complaints and rides on buses; Transit arrests; and the shelter census. Joins the monthly table one to one on month. |
| events.csv | 23 | 6 KB | Dated events that bear on reading the series: changes to the legal definitions of felony assault and rape, the policing announcements for the subway, the lockdown, the overnight closure, fare increases, congestion pricing, and the points where a source starts or stops. Each names its source. Announcements are what was announced, not measured effects. |
| subway_complaint_records.csv.gz | 187,739 | 6.3 MB | 187,739 complaint records: the 187,630 complaints in the monthly table and 109 late reports (late_report). Each has the fields the NYPD publishes: when the offence began, ended and was reported, the offence and its codes, the place, and the victim's and suspect's age group and sex. Empty cells correspond to blanks or (null) in the NYPD's file; recorded unknown values are kept. Identical rows are separate complaints. No complaint number and no race. Compressed here (gzip); pandas.read_csv reads it as it is. |
| missing_values.csv | 53 | 7 KB | For every column of every CSV here that has empty cells: how many, what share, and why they are empty (not published, not applicable, or blank in the source). |
| QUESTIONS.md | 13 KB | Research questions, each with why it is worth asking, what the files can and cannot show, and the files it needs; the first five are on the card. | |
| data_dictionary.csv | 283 | 41 KB | Column names, types, definitions, value classes and licence layers for every CSV in this dataset. |
| sources.csv | 50 | 32 KB | Every source the files are built from: publisher, title, links, when it was retrieved (in Coordinated Universal Time, UTC), the SHA-256 checksum and name of the saved copy (to verify the file), where in it the figures are, and its terms. |
| LICENSE.md | 3 KB | The three licence layers: government records under their publishers' terms, SparkyData's additions under CC BY 4.0, the code under MIT. | |
| build_dataset.py | 52 KB | The builder (MIT): the tables and the checks run before anything is published. It imports SparkyData's library and the article's own functions, which are in the article's code bundle; it is for reading, not a standalone rebuild. | |
| analysis.py | 61 KB | The script behind the article (MIT): it computes every figure in the article, not these files. It runs inside the article's code bundle, linked from the article. | |
| README.md | 88 KB | Everything on this page in one file, to keep beside the data. |
Columns
Each column is classed by where its values come from: observed (counted from
administrative records or printed by the agency), published estimate (an
estimate the agency publishes), modelled (our estimate, on a stated assumption)
or derived (arithmetic on the others). The same list is in
data_dictionary.csv.
subway_crime_monthly.csv: Subway crime and rides by month, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
month | string | observed | Month in which the recorded offence began (CMPLNT_FR_DT), as YYYY-MM; not the month it was reported. |
year | integer | observed | Calendar year. |
fiscal_year | integer | derived | New York City fiscal year (July to June), named for the year it ends in. |
six_major | integer | observed | Complaints of the six major felonies (murder, rape, robbery, felony assault, burglary, grand larceny; not grand larceny of a motor vehicle) whose premises is the subway. |
murder | integer | observed | Murder and non-negligent manslaughter. Zero in every month: the files hold no murder with the subway as its place, which is not evidence that none happened (the fiscal series counts the transit system's). |
rape | integer | observed | Rape complaints (the definition was widened by a law signed on 30 January 2024; see events.csv). |
robbery | integer | observed | Robbery complaints: theft by force or threat. |
felony_assault | integer | observed | Felony assault complaints (NYPD key code KY_CD 106), the serious grade of assault, widened in 2022 and 2024 (see felony_assault_widenings_in_force). |
burglary | integer | observed | Burglary complaints. |
grand_larceny | integer | observed | Grand larceny complaints, the felony grade of theft (not of a motor vehicle). |
felony_assault_ordinary | integer | observed | Felony assaults with internal offence code PD_CD 109 (ASSAULT 2,1,UNCLASSIFIED). Not a constant-definition or worker-free category: newly covered workers can sit here. |
felony_assault_strangulation | integer | observed | Felony assaults with PD_CD 105 (strangulation). |
felony_assault_police_or_peace_officer | integer | observed | Felony assaults with PD_CD 106 (on a police or peace officer). |
felony_assault_other_public_service_employee | integer | observed | Felony assaults with PD_CD 108 (on another public service employee; from 2017). Newly covered transit workers may sit here or in PD_CD 109. |
theft_of_services | integer | observed | Theft of services complaints, PD_CD 478 under key code 343 (fare evasion falls under it): a record of enforcement, not a crime trend. Counted by code because its offence label changed over the years. |
all_felonies | integer | observed | Every felony complaint whose premises is the subway, including offences the police mostly find themselves (weapons, drugs). |
all_misdemeanors | integer | observed | Every misdemeanour complaint (dominated by enforcement in recent years). |
all_violations | integer | observed | Every violation complaint. |
all_complaints | integer | observed | Felonies, misdemeanours and violations. |
paid_rides | integer | mixed | Paid subway entries (taps and swipes) in the month: the MTA's daily figures added up from March 2020; modelled before (paid_rides_method says how). |
paid_rides_method | string | derived | How paid_rides was made: annual_total_x_2019_pattern (the year's official total spread by an inferred 2019 month pattern; to December 2019), annual_total_less_daily (2020's official total less its daily figures from March, split by that pattern with February weighted 29/28; January and February 2020), daily_counts (the MTA's daily figures added up; from March 2020). |
unpaid_share | number | published estimate | The MTA's estimate of the share of entries that are unpaid, for the month's quarter (a fraction). Empty: Empty before 2018, when the MTA's estimates begin, and for April to June 2020, when none was published. |
unpaid_share_moe | number | published estimate | The MTA's published margin of error on unpaid_share (a fraction; confidence level not stated). Empty: Empty before 2020, when the MTA begins publishing margins, and for April to June 2020. |
entries_est | integer | modelled | Estimated entries, paid or not: paid_rides / (1 - unpaid_share). Empty: Empty where unpaid_share is, as there is no estimate to divide by. |
six_major_per_m_paid | number | derived | Six major felony complaints per million paid rides. |
felony_assault_per_m_paid | number | derived | Felony assault complaints per million paid rides. |
robbery_per_m_paid | number | derived | Robbery complaints per million paid rides. |
grand_larceny_per_m_paid | number | derived | Grand larceny complaints per million paid rides. |
six_major_per_m_entries | number | derived | Six major felony complaints per million estimated entries, paid or not. Empty: Empty where entries_est is. |
felony_assault_per_m_entries | number | derived | Felony assault complaints per million estimated entries. Empty: Empty where entries_est is. |
robbery_per_m_entries | number | derived | Robbery complaints per million estimated entries. Empty: Empty where entries_est is. |
grand_larceny_per_m_entries | number | derived | Grand larceny complaints per million estimated entries. Empty: Empty where entries_est is. |
felony_assault_widenings_in_force | integer | derived | How many of the expansions of felony assault since 2019 were in force for any part of the month: 1 from September 2022, 2 from July 2024, 3 from October 2024 (events.csv). A count of legal changes, not a measure of their size; a transition month holds both regimes. |
complaint_file | string | derived | The NYPD file the month's counts come from: historic (to December 2025) or year_to_date (2026). |
report_cutoff | string | observed | The last report date in that file (YYYY-MM-DD): complaints reported after it are not in the count. |
late_reports_all | integer | observed | Complaints about this month (before 2026) found in the 2026 year-to-date file and left out of the historic counts (107 from 2014 on; the article's 109 include two about earlier months). Empty: Empty for 2026's months, whose late reports are already in their counts: not applicable, not zero. |
late_reports_six_major | integer | observed | The six major felonies among late_reports_all. Empty: Empty for 2026's months: not applicable, not zero. |
complete | boolean | derived | A reporting-window flag, not a guarantee of final counts: true when the file's report cutoff is at least the end of the following calendar month. False for December 2025 and June 2026. |
subway_crime_annual.csv: Subway crime and rides by calendar year, 2014–2025
| Column | Type | Class | What it is |
|---|---|---|---|
year | integer | observed | Calendar year. |
six_major | integer | observed | Complaints of the six major felonies on the subway premises in the year (grand larceny of a motor vehicle excluded). |
murder | integer | observed | Murder complaints on the subway premises in the year: zero, which is not evidence that none happened (the fiscal series counts the transit system's). |
rape | integer | observed | Rape complaints in the year (the definition was widened by a law signed on 30 January 2024). |
robbery | integer | observed | Robbery complaints in the year. |
felony_assault | integer | observed | Felony assault complaints (KY_CD 106) in the year. |
burglary | integer | observed | Burglary complaints in the year. |
grand_larceny | integer | observed | Grand larceny complaints in the year (not of a motor vehicle). |
felony_assault_ordinary | integer | observed | Felony assaults with PD_CD 109 in the year. Not a constant-definition category: newly covered workers can sit here. |
felony_assault_strangulation | integer | observed | Felony assaults with PD_CD 105 (strangulation) in the year. |
felony_assault_police_or_peace_officer | integer | observed | Felony assaults with PD_CD 106 (on a police or peace officer) in the year. |
felony_assault_other_public_service_employee | integer | observed | Felony assaults with PD_CD 108 (on another public service employee) in the year. |
theft_of_services | integer | observed | Theft of services complaints (PD_CD 478 under key code 343) in the year: a record of enforcement, not a crime trend. |
all_felonies | integer | observed | Felony complaints in the year. |
all_misdemeanors | integer | observed | Misdemeanour complaints in the year. |
all_violations | integer | observed | Violation complaints in the year. |
all_complaints | integer | observed | Every complaint in the year. |
paid_rides | integer | observed | The year's paid rides: the official total to 2020, the MTA's daily figures added up from 2021 (within 0.2% of the official totals in 2021-2024). |
paid_rides_method | string | derived | official_total (to 2020) or daily_counts (from 2021). |
official_annual_total | integer | observed | The MTA's official yearly subway ridership. Empty: Empty for 2025: the MTA's latest yearly page is for 2024. |
unpaid_share | number | modelled | 1 - paid_rides / entries_est for the year: the unpaid share implied by its quarters. Empty: Empty before 2018 (no estimate) and for 2020 (none for April to June). |
entries_est | integer | modelled | The year's estimated entries, added up from unrounded monthly values. Empty: Empty where any month of the year has no estimate (before 2018, and 2020). |
six_major_per_m_paid | number | derived | Six major felony complaints per million paid rides in the year. |
felony_assault_per_m_paid | number | derived | Felony assault complaints per million paid rides in the year. |
robbery_per_m_paid | number | derived | Robbery complaints per million paid rides in the year. |
grand_larceny_per_m_paid | number | derived | Grand larceny complaints per million paid rides in the year. |
six_major_per_m_entries | number | derived | Six major felony complaints per million estimated entries in the year. Empty: Empty where entries_est is. |
felony_assault_per_m_entries | number | derived | Felony assault complaints per million estimated entries in the year. Empty: Empty where entries_est is. |
robbery_per_m_entries | number | derived | Robbery complaints per million estimated entries in the year. Empty: Empty where entries_est is. |
grand_larceny_per_m_entries | number | derived | Grand larceny complaints per million estimated entries in the year. Empty: Empty where entries_est is. |
felony_assault_widenings_in_force | integer | derived | The most expansions of felony assault in force in any month of the year (0 to 3). A year with a change holds more than one regime. |
months_incomplete | integer | derived | How many of the year's months are flagged as not yet complete (2025: one, December). |
subway_ridership_monthly.csv: Subway rides by month, 1997–2026
| Column | Type | Class | What it is |
|---|---|---|---|
month | string | observed | Month (YYYY-MM). |
year | integer | observed | Calendar year. |
quarter | integer | observed | Calendar quarter (1-4), the period of the fare-evasion estimate. |
fiscal_year | integer | derived | New York City fiscal year (July to June). |
paid_rides | integer | mixed | Paid subway entries in the month: the MTA's daily figures added up from March 2020, modelled before (paid_rides_method). |
paid_rides_method | string | derived | annual_total_x_2019_pattern (to December 2019), annual_total_less_daily (January and February 2020) or daily_counts (from March 2020). |
official_annual_total | integer | observed | The year's official subway ridership (NYU Rudin's table of New York City Transit's counts to 2013, the MTA's yearly pages from 2014). Repeated on every month of its year: take one value per year, never add it up. Empty: Empty for 2025 and 2026: no official yearly figure has been published yet. |
unpaid_share | number | published estimate | The MTA's unpaid share for the month's quarter (a fraction). Empty: Empty before 2018, when the MTA's estimates begin, for April to June 2020, when none was published, and for July to September 2026, not yet published. |
unpaid_share_moe | number | published estimate | Its published margin of error (a fraction). Empty: Empty before 2020, when the MTA begins publishing margins, and wherever unpaid_share is empty. |
entries_est | integer | modelled | Estimated entries, paid or not: paid_rides / (1 - unpaid_share). Empty: Empty where unpaid_share is. |
entries_est_unpaid_minus_1pt | integer | modelled | Entries with the unpaid share one percentage point (0.01) lower: a scenario, not a confidence bound, and not guaranteed to cover every published margin. Empty: Empty where unpaid_share is. |
entries_est_unpaid_plus_1pt | integer | modelled | Entries with the unpaid share one percentage point (0.01) higher: a scenario, not a confidence bound. Empty: Empty where unpaid_share is. |
station_sum_rides | integer | observed | The MTA's entries at every station complex in the month, added up (MTA Subway Station Monthly Ridership). Counted, not modelled, but not the same measure as paid_rides: about 1% above the daily totals since 2024. Use it to check the modelled months or as another monthly denominator; never mix it into paid_rides. Empty: Empty before February 2017, when the MTA's station file starts, and for September 2026, after its latest month. |
fare_evasion_quarterly.csv: Subway fare evasion by quarter, 2018–2026
| Column | Type | Class | What it is |
|---|---|---|---|
period | string | observed | Quarter (YYYY-Qn). |
year | integer | observed | Calendar year. |
quarter | integer | observed | Calendar quarter (1-4). |
unpaid_share | number | published estimate | Estimated share of entries that are unpaid (a fraction). Empty: Empty for 2020 Q2: no estimate was published. |
margin_of_error | number | published estimate | Published margin of error (a fraction; confidence level not stated). Empty: Empty before 2020 Q1, when the MTA begins publishing margins, and for 2020 Q2. |
transit_major_felonies_fiscal.csv: Transit-system major felonies by fiscal year, 1998–2026
| Column | Type | Class | What it is |
|---|---|---|---|
fiscal_year | integer | observed | New York City fiscal year (July to June), named for the year it ends in. |
months | string | derived | The months the fiscal year covers (YYYY-MM to YYYY-MM). |
major_felonies | integer | observed | Major felony crime in the transit system as the Mayor's Management Report prints it: murder, rape, robbery, felony assault, burglary and grand larceny, under each year's law. |
crime_scope | string | derived | What major_felonies counts: the whole transit system under the NYPD's Transit Bureau. |
rides_scope | string | derived | What paid_rides counts: subway paid entries. |
mmr_source_id | string | derived | The source the figure was read from (sources.csv). Where editions overlap they agree to the felony; the latest is kept. |
note | string | observed | A remark the source makes about the year (fiscal 1998: based on preliminary data). Empty: Empty where the source makes no remark about the year. |
paid_rides | integer | mixed | Paid subway rides in the fiscal year's twelve months, added up from the unrounded monthly values: modelled months to February 2020, the MTA's daily figures after (paid_rides_method). |
paid_rides_method | string | derived | How the year's months were built (see subway_ridership_monthly.csv); fiscal 2020 mixes all three. |
major_felonies_per_m_paid | number | derived | Transit-system major felonies per million paid subway rides: a ratio across two scopes. |
unpaid_share | number | modelled | The fiscal year's implied unpaid share (1 - paid / entries). Empty: Empty before fiscal 2019 (no estimate for every month) and for fiscal 2020 (none for April to June 2020). |
entries_est | integer | modelled | Estimated subway entries, paid or not, in the fiscal year. Empty: Empty where unpaid_share is. |
major_felonies_per_m_entries | number | derived | Transit-system major felonies per million estimated subway entries. Empty: Empty where entries_est is. |
subway_crime_daily.csv: Subway crime, rides and weather by day, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
date | string | observed | The day the recorded offence began (CMPLNT_FR_DT), YYYY-MM-DD. |
year | integer | observed | Calendar year. |
month | string | observed | YYYY-MM, the key to the monthly files. |
day_of_week | string | derived | Monday to Sunday. |
weekend | boolean | derived | True on Saturday and Sunday. Public holidays are not flagged. |
six_major | integer | observed | Complaints of the six major felonies that began that day. |
felony_assault | integer | observed | Felony assault complaints that began that day. |
robbery | integer | observed | Robbery complaints that began that day. |
grand_larceny | integer | observed | Grand larceny complaints that began that day. |
all_felonies | integer | observed | Felony complaints that began that day. |
all_misdemeanors | integer | observed | Misdemeanour complaints that began that day. |
all_violations | integer | observed | Violation complaints that began that day. |
all_complaints | integer | observed | Every subway complaint that began that day. |
theft_of_services | integer | observed | Theft of services complaints (PD_CD 478 under key code 343): a record of enforcement. |
paid_rides | integer | observed | The MTA's subway ridership figure for the day, which it labels 'Total Estimated Ridership' and builds from its fare-system counts. Empty: Empty before 1 March 2020, when the MTA's daily figures begin. |
tmax_f | integer | observed | Central Park's maximum temperature, whole degrees Fahrenheit (NOAA's Global Historical Climatology Network - Daily). |
tmin_f | integer | observed | Central Park's minimum temperature, whole degrees Fahrenheit. |
precip_in | number | observed | Central Park's precipitation (rain and melted snow), inches. |
snow_in | number | observed | Central Park's snowfall, inches. |
felony_assault_widenings_in_force | integer | derived | How many expansions of felony assault were in force that day (0 to 3; events.csv). |
complete | boolean | derived | The day's month's reporting-window flag: true when the file's report cutoff reaches at least the end of the following calendar month. Not a guarantee of final counts. |
subway_crime_by_hour.csv: Subway crime by hour of the day, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
month | string | observed | YYYY-MM of the day the offence began. |
day_type | string | derived | weekday (Monday to Friday) or weekend (Saturday and Sunday). |
hour | integer | observed | The hour of the recorded start time (CMPLNT_FR_TM), 0 to 23: 0 is midnight to 00:59. 00:01 is a common default, so hour 0 is inflated. |
six_major | integer | observed | Complaints of the six major felonies that began in the hour. |
felony_assault | integer | observed | Felony assault complaints that began in the hour. |
robbery | integer | observed | Robbery complaints that began in the hour. |
grand_larceny | integer | observed | Grand larceny complaints that began in the hour. |
all_felonies | integer | observed | Felony complaints that began in the hour. |
all_complaints | integer | observed | Every subway complaint that began in the hour. |
all_complaints_on_the_hour | integer | observed | Complaints whose recorded start time is exactly on the hour (HH:00:00): a measure of rounding in the times. |
complete | boolean | derived | The month's reporting-window flag: true when the file's report cutoff reaches at least the end of the following calendar month. |
subway_stations_annual.csv: Subway crime and entries by station complex and year, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
complex_id | integer | observed | The MTA's station complex id (Complex ID in its station list, station_complex_id in its ridership). |
station_complex | string | observed | The complex's current name, with the routes that stop there, as the MTA's ridership names it. |
borough | string | observed | The complex's borough, as the MTA gives it. |
latitude | number | observed | The complex's latitude (MTA, current). |
longitude | number | observed | The complex's longitude (MTA, current). |
year | integer | observed | Calendar year of the complaints. |
months | integer | derived | Months of complaints the year covers: 12, or 6 for 2026 (January to June). |
months_incomplete | integer | derived | How many of the year's months are flagged as not yet complete in the monthly table (2025: December; 2026: June). |
six_major | integer | observed | Complaints of the six major felonies at places matched to the complex. A zero means no complaint was matched there that year, not that nothing happened. |
felony_assault | integer | observed | Felony assault complaints matched to the complex. |
robbery | integer | observed | Robbery complaints matched to the complex. |
grand_larceny | integer | observed | Grand larceny complaints matched to the complex. |
all_felonies | integer | observed | Felony complaints matched to the complex. |
all_complaints | integer | observed | Every complaint matched to the complex. |
all_complaints_matched_by_name | integer | derived | Of all_complaints, those whose place was matched by name within 300 metres (match 'name' in the station-matching table); the rest were matched less surely. |
rides | integer | observed | The MTA's entries at the complex over the same months (MTA Subway Station Monthly Ridership). Empty: Empty before 2017, when the MTA's station file starts, and in years the station file has no month for the complex (three Staten Island Railway stations). |
ride_months | integer | derived | Months of entries in rides: 11 in 2017 (the file starts in February), fewer where a station has months missing, 0 before 2017. |
six_major_per_m_rides | number | derived | Six major felony complaints per million entries at the complex. Empty: Empty where the entries do not cover every month of the year's complaints: every year before 2018, and years in which the station file lacks some months for the complex. |
felony_assault_per_m_rides | number | derived | Felony assault complaints per million entries at the complex. Empty: Empty where the entries do not cover every month of the year's complaints. |
robbery_per_m_rides | number | derived | Robbery complaints per million entries at the complex. Empty: Empty where the entries do not cover every month of the year's complaints. |
all_complaints_per_m_rides | number | derived | Every complaint per million entries at the complex. Empty: Empty where the entries do not cover every month of the year's complaints. |
subway_station_crosswalk.csv: Station matching: the NYPD's station names to the MTA's station complexes
| Column | Type | Class | What it is |
|---|---|---|---|
station_name | string | observed | The station name the NYPD records (STATION_NAME), as printed; '(null)' where blank. |
borough | string | observed | The borough the NYPD records (BORO_NM). |
latitude | number | observed | The latitude the NYPD records. |
longitude | number | observed | The longitude the NYPD records. |
complaints | integer | observed | Complaints at this place across the whole record file: the monthly table's complaints plus the 109 late reports (two of them about 2005 and 2006). |
complex_id | integer | derived | The MTA station complex the place is matched to. |
matched_station | string | observed | The MTA station (stop name) the match was made to. |
distance_m | number | derived | Metres from the recorded place to that station. |
match | string | derived | name: a station sharing an identifying word within 300 m; name_far: the station sharing the most words, further away (up to 800 m, or 1,500 m for two or more words); distance: no name in common, the nearest within 300 m (often an older name, such as PACIFIC STREET for Atlantic Av-Barclays Ctr); uncertain: no name in common and further than 300 m. |
subway_complaints_by_offence_monthly.csv: Every subway complaint offence by month, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
month | string | observed | Month in which the recorded offence began (CMPLNT_FR_DT), as YYYY-MM. |
law_category | string | observed | FELONY, MISDEMEANOR or VIOLATION (LAW_CAT_CD). |
offence | string | observed | The NYPD's offence description (OFNS_DESC) as the files print it, spelling included; '(null)' is the source's own label for complaints with no description. Labels can change over the years while the offence does not. |
is_major_six | boolean | derived | One of the six major felonies (grand larceny of a motor vehicle excluded). |
complaints | integer | observed | Number of complaints in this month, law category and offence. |
complaint_file | string | derived | historic or year_to_date: the NYPD file the counts come from. |
report_cutoff | string | observed | The last report date in that file (YYYY-MM-DD). |
complete | boolean | derived | The month's reporting-window flag: true when the file's report cutoff reaches at least the end of the following calendar month. Not a guarantee of final counts. |
subway_complaints_by_code_monthly.csv: Every subway complaint by internal offence code, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
month | string | observed | Month in which the recorded offence began (CMPLNT_FR_DT), as YYYY-MM. |
key_code | integer | observed | The NYPD's key offence code (KY_CD), e.g. 105 robbery, 106 felony assault, 109 grand larceny, 343 other offences related to theft. |
offence | string | observed | The offence description (OFNS_DESC) as printed; a label can change over the years while the codes do not. |
pd_code | integer | observed | The NYPD's internal offence code (PD_CD), e.g. 109 ordinary felony assault, 478 theft of services, 475 unauthorised sale of transit service. |
pd_description | string | observed | The internal code's description (PD_DESC) as printed. |
complaints | integer | observed | Number of complaints in this month and offence-code group. |
complaint_file | string | derived | historic or year_to_date: the NYPD file the counts come from. |
report_cutoff | string | observed | The last report date in that file (YYYY-MM-DD). |
complete | boolean | derived | The month's reporting-window flag: true when the file's report cutoff reaches at least the end of the following calendar month. Not a guarantee of final counts. |
subway_victims_annual.csv: Subway complaints by victim age group and sex, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
year | integer | observed | Calendar year the offence began. |
law_category | string | observed | FELONY, MISDEMEANOR or VIOLATION. |
offence | string | observed | The offence description (OFNS_DESC) as printed. |
victim_age_group | string | observed | VIC_AGE_GROUP as printed: <18, 18-24, 25-44, 45-64, 65+, UNKNOWN, '(null)' (blank in the source), and a few values that are not ages (such as -59 or 951), kept as the source has them. |
victim_sex | string | observed | VIC_SEX as printed: F female, M male, D a business or organisation, E the People of the State of New York (offences against the public), L not defined in the NYPD's notes. |
complaints | integer | observed | Number of complaints in this year, law category, offence and victim group. |
months_incomplete | integer | derived | How many of the year's months are flagged as not yet complete in the monthly table. |
subway_report_delay_annual.csv: How long subway crimes took to be reported, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
year | integer | observed | Calendar year the offence began. |
offence_group | string | derived | rape, robbery, felony_assault, burglary, grand_larceny (the five major felonies the records hold), or other_felonies, misdemeanors, violations. |
lag_band | string | derived | same day, 1 day, 2-7 days, 8-30 days, 31-90 days, 91-365 days, over a year. |
lag_days_min | integer | derived | The band's shortest delay in days. |
lag_days_max | integer | derived | The band's longest delay in days. Empty: Empty for 'over a year', which has no upper limit. |
complaints | integer | observed | Complaints reported with that delay (RPT_DT minus CMPLNT_FR_DT), among those in the monthly table. |
report_cutoff | string | observed | The last report date the year's file holds: a longer delay than this allows cannot appear yet. |
months_incomplete | integer | derived | How many of the year's months are flagged as not yet complete in the monthly table. |
transit_arrests_monthly.csv: Arrests in the Transit jurisdiction by month and charge, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
month | string | observed | Month of the arrest (ARREST_DATE), YYYY-MM. |
law_category | string | observed | LAW_CAT_CD as printed: F felony, M misdemeanour, V violation, I infraction, and a few other codes the file holds. Empty: Empty where the NYPD's arrest file is blank. |
key_code | integer | observed | Key offence code (KY_CD) of the charge. Empty: Empty where the NYPD's arrest file is blank. |
offence | string | observed | Offence description (OFNS_DESC) as printed. Empty: Empty where the NYPD's arrest file is blank. |
pd_code | integer | observed | Internal offence code (PD_CD); 478 under key code 343 is theft of services. Empty: Empty where the NYPD's arrest file is blank. |
pd_description | string | observed | Internal code description (PD_DESC) as printed. Empty: Empty where the NYPD's arrest file is blank. |
arrests | integer | observed | Number of arrests in this month, law category and charge. |
city_context_monthly.csv: The city around the subway by month, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
month | string | observed | YYYY-MM (the month an offence began for complaints, the month of arrest for arrests). |
city_six_major | integer | observed | Complaints of the six major felonies anywhere in the city, the subway included (grand larceny of a motor vehicle excluded, as for the subway). |
city_felony_assault | integer | observed | Felony assault complaints anywhere in the city. |
city_robbery | integer | observed | Robbery complaints anywhere in the city. |
city_grand_larceny | integer | observed | Grand larceny complaints anywhere in the city (not of a motor vehicle). |
city_all_complaints | integer | observed | Every complaint anywhere in the city. |
subway_share_of_city_six_major | number | derived | The monthly table's six_major divided by city_six_major. |
nyc_population | integer | published estimate | The five boroughs' population on 1 July of the month's year (Census Bureau estimates). Repeated on every month of its year. Empty: Empty for 2026: the Census Bureau's estimate for 1 July 2026 comes out in 2027. |
bus_six_major | integer | observed | Six major felony complaints whose premises is a New York City Transit bus. |
bus_felony_assault | integer | observed | Felony assault complaints on New York City Transit buses. |
bus_all_complaints | integer | observed | Every complaint on New York City Transit buses. |
bus_stop_and_terminal_complaints | integer | observed | Every complaint at bus stops and bus terminals. |
bus_rides | integer | observed | The MTA's bus ridership figures for the month, the daily figures added up; they may cover more buses than the NYPD's 'BUS (NYC TRANSIT)' premises. Empty: Empty before March 2020 (no daily bus figures) and for April to August 2020, when buses were fare-free with rear-door boarding and there is no usable count. |
transit_arrests | integer | observed | Transit-jurisdiction arrests in the month (transit_arrests_monthly.csv added up). |
transit_arrests_felony | integer | observed | Transit-jurisdiction arrests on a felony charge in the month. |
transit_arrests_theft_of_services | integer | observed | Transit-jurisdiction arrests for theft of services (PD_CD 478 under key code 343) in the month. |
shelter_individuals | integer | observed | People in the Department of Homeless Services' shelters, the average of the month's nightly census (Total Individuals in Shelter). Not other shelter systems, and not people sleeping outside. |
shelter_census_days | integer | derived | Days in the month with a census (some days are missing in 2013-2021). |
complete | boolean | derived | The month's reporting-window flag for the subway complaints: true when the file's report cutoff reaches at least the end of the following calendar month. The city and bus counts come from the same files and share it. |
events.csv: Law changes, policing announcements and service changes, 1995–2026
| Column | Type | Class | What it is |
|---|---|---|---|
date | string | observed | The event's date at the precision the source gives: YYYY, YYYY-MM or YYYY-MM-DD. Read it as text. |
date_basis | string | derived | What the date is: signed, in_force (from the act's effective-date clause, or stated by the source), announced, published, or data (a series starts, stops or has a gap). |
kind | string | derived | law, policing_announcement, service (a change to service or fares) or data. |
event | string | observed | What happened. |
bearing | string | derived | What it means for reading the series. |
source_id | string | observed | The source's id in sources.csv. |
subway_complaint_records.csv.gz: Every subway complaint, one row each, 2014–2026
| Column | Type | Class | What it is |
|---|---|---|---|
complaint_date | string | observed | The day the offence began (CMPLNT_FR_DT), YYYY-MM-DD. |
complaint_time | string | observed | The time it began (CMPLNT_FR_TM), HH:MM:SS, as recorded: often rounded to the hour, and 00:01 is a common default. |
end_date | string | observed | The day it ended, where the complaint records an end (CMPLNT_TO_DT), YYYY-MM-DD. Empty: Empty where the NYPD's file is blank: no end recorded. |
end_time | string | observed | The time it ended (CMPLNT_TO_TM), HH:MM:SS. Empty: Empty where the NYPD's file prints (null): no end time recorded. |
report_date | string | observed | The day it was reported (RPT_DT), YYYY-MM-DD. |
year | integer | derived | Calendar year of complaint_date. |
month | string | derived | YYYY-MM of complaint_date, the key to the monthly files. |
day_of_week | string | derived | Monday to Sunday, of complaint_date. |
hour | integer | derived | The hour of complaint_time, 0 to 23. |
report_delay_days | integer | derived | Days from complaint_date to report_date. |
law_category | string | observed | FELONY, MISDEMEANOR or VIOLATION (LAW_CAT_CD). |
offence | string | observed | The offence description (OFNS_DESC) as printed, spelling included. Empty: Empty where the NYPD's file prints (null): no description, though the codes are there. |
key_code | integer | observed | The key offence code (KY_CD). |
pd_code | integer | observed | The internal offence code (PD_CD). |
pd_description | string | observed | The internal code's description (PD_DESC) as printed. |
is_major_six | boolean | derived | One of the six major felonies (grand larceny of a motor vehicle excluded), as in the monthly table. |
attempted_or_completed | string | observed | ATTEMPTED or COMPLETED (CRM_ATPT_CPTD_CD). |
jurisdiction | string | observed | The jurisdiction responsible (JURIS_DESC): N.Y. TRANSIT POLICE for almost every subway complaint. |
precinct | integer | observed | The precinct of the place (ADDR_PCT_CD). |
borough | string | observed | The borough (BORO_NM). Empty: Empty where the NYPD's file prints (null). |
patrol_borough | string | observed | The NYPD patrol borough (PATROL_BORO). |
transit_district | integer | observed | The NYPD transit district (TRANSIT_DISTRICT). Empty: Empty where the NYPD's file is blank. |
station_name | string | observed | The station name the NYPD records (STATION_NAME), as printed. Empty: Empty where the NYPD's file prints (null). |
latitude | number | observed | The latitude the NYPD records. |
longitude | number | observed | The longitude the NYPD records. |
complex_id | integer | derived | The MTA station complex the place is matched to (subway_station_crosswalk.csv). |
station_match | string | derived | How surely the place was matched: name, name_far, distance or uncertain, as in the station-matching table. |
victim_age_group | string | observed | The victim's age group as recorded (VIC_AGE_GROUP): <18, 18-24, 25-44, 45-64, 65+, UNKNOWN, and a few values that are not ages (such as -59 or 951), kept as the NYPD has them. Empty: Empty where the NYPD's file prints (null); not the same as UNKNOWN, which the NYPD recorded. |
victim_sex | string | observed | The victim's sex as recorded (VIC_SEX): F female, M male, D a business or organisation, E the People of the State of New York (offences against the public), L not defined in the NYPD's notes. |
suspect_age_group | string | observed | The suspect's age group as recorded (SUSP_AGE_GROUP): <18, 18-24, 25-44, 45-64, 65+, UNKNOWN, and a few values that are not ages (such as 2024), kept as the NYPD has them. Empty: Empty where the NYPD's file prints (null); not the same as UNKNOWN, which the NYPD recorded. |
suspect_sex | string | observed | The suspect's sex as recorded (SUSP_SEX): F female, M male, U unknown. Empty: Empty where the NYPD's file prints (null); U is a recorded value, not an empty cell. |
complaint_file | string | derived | historic or year_to_date: the NYPD file the complaint is in. |
report_cutoff | string | observed | The last report date in that file (YYYY-MM-DD): complaints reported after it are not here. |
late_report | boolean | derived | True for the 109 complaints reported in 2026 about earlier years (two of them about 2005 and 2006), which the monthly table leaves out of those years. Leave them out to reproduce the monthly table. |
missing_values.csv: Every empty cell, counted and explained
| Column | Type | Class | What it is |
|---|---|---|---|
file | string | derived | CSV file name. |
column | string | derived | Column name. |
rows | integer | derived | Rows in the file. |
empty | integer | derived | Empty cells in the column. |
share_empty | number | derived | empty / rows. |
why_empty | string | derived | Why the cells are empty. |
data_dictionary.csv: Data dictionary
| Column | Type | Class | What it is |
|---|---|---|---|
file | string | derived | The file the column is in. |
column | string | derived | The column's name. |
type | string | derived | string, integer, number or boolean. |
class | string | derived | How the values were obtained or calculated: observed, published_estimate, modelled, derived, or mixed (varies by row; the row's method column says which). Separate from layer: derived here means a calculation. |
layer | string | derived | The licence layer that applies: government (the publisher's terms), derived (SparkyData's, CC BY 4.0) or mixed (by row). |
description | string | derived | What the column holds, and why it can be empty. |
sources.csv: Sources and provenance
| Column | Type | Class | What it is |
|---|---|---|---|
source_id | string | derived | The source's id, as events.csv and transit_major_felonies_fiscal.csv cite it. |
publisher | string | observed | Who publishes it. |
title | string | observed | Its title. |
landing_page | string | observed | The page that describes it. |
url | string | observed | The address it was fetched from (for open-data tables, the query that counted the records). |
retrieved_utc | string | observed | When it was fetched, in Coordinated Universal Time (a date can differ by one from a local date). |
sha256 | string | observed | The SHA-256 checksum of the saved copy, to verify the file. |
saved_as | string | derived | The saved copy's path in SparkyData's repository (data/raw is a cache; data/reference is kept). |
locator | string | derived | Where in the source the figures used are (an indicator, a chart, a clause). Empty: Empty where no locator is needed: the figures come from the whole table, or the whole document. |
terms | string | observed | The terms the source is published under, as recorded at retrieval. |
More questions
Each is set out in QUESTIONS.md with why it is worth asking.
- How have transit-system felonies per paid subway ride changed since the 1990s? (
transit_major_felonies_fiscal.csv,subway_ridership_monthly.csv) - How has the subway's share of the city's recorded major felonies changed? (
city_context_monthly.csv,subway_crime_monthly.csv) - Did borough differences in major felony complaint rates widen or narrow after 2020? (
subway_stations_annual.csv,subway_station_crosswalk.csv) - Are recorded assault rates per ride higher on hot days? (
subway_crime_daily.csv) - How do rain and snow relate to ridership and recorded complaints per ride? (
subway_crime_daily.csv) - How has the recorded victim profile changed by age group and sex? (
subway_victims_annual.csv) - How did complaint counts by offence code change around changes in the law? (
subway_crime_monthly.csv,subway_complaints_by_code_monthly.csv,events.csv) - Is pickpocketing disappearing from the records? (
subway_complaints_by_code_monthly.csv) - How has the ratio of Transit arrests to recorded complaints changed? (
transit_arrests_monthly.csv,subway_crime_monthly.csv) - What changed in recorded complaints and arrests around the policing announcements of 2022, 2024 and 2025? (
events.csv,subway_crime_monthly.csv,subway_crime_daily.csv,transit_arrests_monthly.csv) - How do the shelter census and subway complaints move together? (
city_context_monthly.csv,subway_crime_monthly.csv) - How did ridership and complaint rates change around the start of congestion pricing? (
subway_ridership_monthly.csv,subway_crime_daily.csv,subway_crime_monthly.csv,events.csv) - Did the unpaid share move the same way around each fare increase? (
fare_evasion_quarterly.csv,events.csv) - How do reporting delays vary by offence and year? (
subway_report_delay_annual.csv,subway_crime_monthly.csv) - How much of the seasonal pattern before 2020 comes from the model? (
subway_ridership_monthly.csv,subway_crime_monthly.csv) - How do recorded complaints per ride compare on buses and on the subway? (
city_context_monthly.csv,subway_crime_monthly.csv) - What happened to recorded overnight complaints when the subway closed at night? (
subway_crime_by_hour.csv,subway_complaint_records.csv,events.csv) - Can you tell a felony from a misdemeanour by when and where it happened? (
subway_complaint_records.csv) - When are suspect descriptions blank, and when recorded as unknown? (
subway_complaint_records.csv,missing_values.csv) - How wide are the recorded windows in which offences took place? (
subway_complaint_records.csv,missing_values.csv)
Sources
The SHA-256 of each saved copy is in sources.csv.
- NYPD (via NYC Open Data): NYPD Complaint Data Historic, complaints on the subway summed by month, law category and offense, retrieved 2026-09-26
- NYPD (via NYC Open Data): NYPD Complaint Data Current (Year To Date), complaints on the subway summed by month, law category and offense, retrieved 2026-09-26
- NYPD (via NYC Open Data): NYPD Complaint Data Historic, felony assaults and other offenses related to theft on the subway, by month and offence code, retrieved 2026-10-11
- NYPD (via NYC Open Data): NYPD Complaint Data Current (Year To Date), felony assaults and other offenses related to theft on the subway, by month and offence code, retrieved 2026-10-11
- NYPD (via NYC Open Data): NYPD Complaint Data Historic: first and last report dates and last occurrence date in the file, retrieved 2026-10-11
- NYPD (via NYC Open Data): NYPD Complaint Data Current (Year To Date): first and last report dates and last occurrence date in the file, retrieved 2026-10-11
- NYPD (via NYC Open Data): NYPD Complaint Data Historic, complaints on the subway summed by day, time, report date, offence, code, station, place and victim group, retrieved 2026-10-19
- NYPD (via NYC Open Data): NYPD Complaint Data Current (Year To Date), complaints on the subway summed by day, time, report date, offence, code, station, place and victim group, retrieved 2026-10-19
- NYPD (via NYC Open Data): NYPD Complaint Data Historic, the subway's complaints with their descriptive fields (no complaint number, no race), retrieved 2026-10-19
- NYPD (via NYC Open Data): NYPD Complaint Data Current (Year To Date), the subway's complaints with their descriptive fields (no complaint number, no race), retrieved 2026-10-19
- NYPD (via NYC Open Data): NYPD Complaint Data Historic, every complaint in the city summed by month, law category and offence, retrieved 2026-10-19
- NYPD (via NYC Open Data): NYPD Complaint Data Current (Year To Date), every complaint in the city summed by month, law category and offence, retrieved 2026-10-19
- NYPD (via NYC Open Data): NYPD Complaint Data Historic, complaints on New York City Transit buses, at bus stops and at bus terminals, by month, premises, law category and offence, retrieved 2026-10-19
- NYPD (via NYC Open Data): NYPD Complaint Data Current (Year To Date), complaints on New York City Transit buses, at bus stops and at bus terminals, by month, premises, law category and offence, retrieved 2026-10-19
- NYPD (via NYC Open Data): NYPD Arrests Data (Historic), arrests in the Transit jurisdiction by month, law category and offence code, retrieved 2026-10-19
- NYPD (via NYC Open Data): NYPD Arrest Data (Year to Date), arrests in the Transit jurisdiction by month, law category and offence code, retrieved 2026-10-19
- Metropolitan Transportation Authority (via data.ny.gov): MTA Daily Ridership and Traffic: Beginning 2020, retrieved 2026-10-05
- Metropolitan Transportation Authority (via data.ny.gov): MTA Daily Ridership Data: 2020 - 2025, retrieved 2026-09-06
- Metropolitan Transportation Authority (via data.ny.gov): MTA Subway Station Monthly Ridership: Beginning February 2017, retrieved 2026-10-19
- Metropolitan Transportation Authority (via data.ny.gov): MTA Subway Stations, retrieved 2026-10-19
- Metropolitan Transportation Authority (via data.ny.gov): MTA NYCT Subway Fare Evasion: Beginning 2018, retrieved 2026-10-08
- NYU Rudin Center for Transportation: Subway Ridership 1975-2015 (NYU Rudin Center for Transportation, March 2017), retrieved 2026-10-08
- Metropolitan Transportation Authority: MTA: Subway and bus ridership for 2019 (annual totals 2014-2019), retrieved 2026-10-08
- Metropolitan Transportation Authority: MTA: Subway and bus ridership for 2023 (annual totals 2018-2023), retrieved 2026-10-08
- Metropolitan Transportation Authority: MTA: Subway and bus ridership for 2024, retrieved 2026-10-08
- NYC Department of Homeless Services (NYC Open Data): DHS Daily Report (Historical) — the shelter census, 21 August 2013 to 28 February 2021, retrieved 2026-10-16
- NYC Department of Homeless Services (NYC Open Data): DHS Daily Report — individuals in the NYC Department of Homeless Services shelter system, retrieved 2026-10-05
- NOAA National Centers for Environmental Information: NOAA NCEI Global Historical Climatology Network - Daily, New York Central Park (USW00094728), by-station file, retrieved 2026-10-02
- U.S. Census Bureau, Population Division: Annual Intercensal County Resident Population Estimates by Selected Age Groups and Sex, New York: April 1, 2010 to April 1, 2020, retrieved 2026-09-26
- U.S. Census Bureau, Population Division: County Population Estimates by Selected Age Groups and Sex, New York: April 1, 2020 to July 1, 2025 (Vintage 2025), retrieved 2026-09-26
- NYC Mayor's Office of Operations: Mayor's Management Report, Fiscal 2001: Volume I (Fire Department), retrieved 2026-10-02
- NYC Mayor's Office of Operations: Mayor's Management Report, Fiscal 2004 (Fire Department section), retrieved 2026-10-03
- NYC Mayor's Office of Operations: Mayor's Management Report, Fiscal 2006 (Fire Department section), retrieved 2026-10-02
- NYC Mayor's Office of Operations (via NYC Open Data): FY03 - FY12 MMR Agency Performance Indicators (NYPD rows), retrieved 2026-10-08
- NYC Mayor's Office of Operations: Mayor's Management Report, Fiscal 2016: New York City Police Department chapter, retrieved 2026-10-08
- NYC Mayor's Office of Operations: Mayor's Management Report, Fiscal 2021: New York City Police Department chapter, retrieved 2026-10-08
- NYC Mayor's Office of Operations: Mayor's Management Report, Fiscal 2026: New York City Police Department chapter, retrieved 2026-10-08
- New York State Legislature (Senate legislation API): New York State Assembly bill A.10491 (2022): assaults upon certain employees of a transit agency or authority, retrieved 2026-10-11
- New York State Legislature (Senate legislation API): New York State budget bill S.8305-C / A.8805-C (2024), public protection and general government: Part A, assault on a retail worker, retrieved 2026-10-07
- New York State Legislature (Senate legislation API): New York State Assembly bill A.3340 (2023): sex offenses, the definition of rape, retrieved 2026-10-11
- New York City Police Department: NYPD Transit Bureau (nyc.gov page), retrieved 2026-10-15
- Office of the Governor of New York (press release, 20 March 2020; Internet Archive copy of 1 October 2026): Governor Cuomo Signs the 'New York State on PAUSE' Executive Order, retrieved 2026-10-19
- Metropolitan Transportation Authority (press release, May 2021; Internet Archive copy of 18 May 2026): MTA to Restore 24-Hour Subway Service on Monday, May 17, retrieved 2026-10-19
- NYC Office of the Mayor: Mayor Adams Releases Subway Safety Plan, Says Safe Subway is Prerequisite for New York City's Recovery (press release), retrieved 2026-10-15
- NYC Office of the Mayor: Mayor Adams and Governor Hochul Announce Major Actions to Keep Subways Safe and Address Transit Crime (press release), retrieved 2026-10-15
- Metropolitan Transportation Authority (press release, 18 August 2023; Internet Archive copy of 18 May 2026): REMINDER: New Fares on Subway, Buses and Commuter Railroads to Begin Aug. 20, retrieved 2026-10-19
- ABC (WTVD), reporting Governor Hochul's announcement: New York governor to deploy National Guard, state police to combat NYC subway crime (ABC, 7 March 2024), retrieved 2026-10-15
- Metropolitan Transportation Authority (press release, 18 November 2024; Internet Archive copy of 12 June 2026): MTA Board Approves Phasing In the Congestion Relief Zone Toll, retrieved 2026-09-29
- Spectrum News NY1: NYPD to deploy 1,050 more officers into subway stations, Hochul says (NY1, 16 January 2025), retrieved 2026-10-15
- Metropolitan Transportation Authority (press release, 30 September 2025; Internet Archive copy of 21 May 2026): MTA Board Adopts Fare and Toll Increases to Take Effect January 2026, retrieved 2026-10-19
Licence and credit
Mixed licensing: government-source values remain under their publishers' terms; SparkyData's additions are Creative Commons Attribution 4.0 (CC BY 4.0); the code is MIT. The layer column of data_dictionary.csv gives the layer of every column.
Government records. Government records are reproduced or counted under their publishers' terms, which continue to apply; SparkyData does not relicense them. City sources (NYPD complaint records and complaint and arrest counts, the Department of Homeless Services' shelter census, both on NYC Open Data, and the Mayor's Management Report): the City of New York's terms, https://www.nyc.gov/main/terms-of-use. MTA sources on Open NY (ridership, station and fare-evasion figures): Open NY's terms, https://data.ny.gov/dataset/OPEN-NY-Terms-Of-Use/77gx-ii52. Central Park's daily weather comes from NOAA's National Centers for Environmental Information, and the population estimates from the US Census Bureau, under their terms. Yearly ridership for 1997 to 2013 is transcribed from the NYU Rudin Center's table of New York City Transit's counts. events.csv links to laws, press releases and news reports; none of those documents is redistributed here.
What we added. SparkyData's own additions are CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/): the monthly rides before March 2020, the estimated entries, the rates, the fiscal-year rides, the station matches, the flags, events.csv, QUESTIONS.md, missing_values.csv and the documentation.
Code. build_dataset.py and analysis.py are MIT.
Credit it as:
SparkyData (2026). NYC Subway Crime Rates and Ridership, 1998–2026 (version 2.0). SparkyData additions CC BY 4.0; government-source data under publisher terms; code MIT.
https://sparkydata.dev/data/nyc-subway-crime-and-ridership
The article gives the charts, the uncertainty of each comparison and a changelog. Corrections and questions: sparkytech.dev@gmail.com, or see corrections.
Versions
- 1.0 (): First release.
- 1.1 (): After an outside review: the licence marked as mixed, with LICENSE.md and the publishers' terms; a Start here section with a tested example; the by-code complaint table; flags for the ride method, the legal changes and incomplete months in the annual and long tables; source file names and locators in sources.csv. Corrected: paid rides are classed as mixed (counted from March 2020); late-report cells for 2026 are empty rather than zero; the rape row of events.csv records signing only. No count, ride or rate changed.
- 2.0 (): A wider dataset, built around twenty-five research questions (QUESTIONS.md), with a card written as a story. Added: complaints by day (with that day's rides and weather), by hour, by station complex (with station entries and the station-matching table), by victim group and by reporting delay; every complaint as its own row, for learning and training; Transit arrests; recorded crime across the whole city, on buses, bus rides, population and the shelter census; the MTA's station counts summed by month, an observed check on the modelled months before March 2020; missing_values.csv; and the lockdown, the overnight closure, two fare increases and congestion pricing in events.csv. The code table now holds every offence code. Corrected: theft of services is code 478 under key code 343 everywhere; the card no longer says its complaints rose "while enforcement rose" without the arrests that show the recording changed. No count, ride or rate in the files of version 1.1 changed.