Road Injury Severity Scales Explained
On this page
Problem statement
Every crash dataset grades injuries, and no two grade them the same way. US police reports use the KABCO scale: K killed, A suspected serious injury, B suspected minor injury, C possible injury, O no apparent injury. Great Britain's STATS19 uses three classes, fatal, serious and slight, with serious defined by a list of injuries. "Fatal" itself has a time limit: a death counts if it happens within 30 days of the crash. Comparing numbers across datasets, or across years within one, needs to know which scale produced them and what each grade means.
This page reads injury severity from three sources: FARS 2023, where every person in a fatal crash has a KABCO grade and the deaths have a recorded time from crash to death; Chicago's 2024 crash records, graded by the most severe injury in each crash; and STATS19 2023 casualties, with their adjusted serious grade.
Quick answer
Look at the distribution of grades in each source before comparing anything:
print(P.INJ_SEVNAME.value_counts().to_string())
print()
print(CHI.set_index("most_severe_injury").n.to_string())
print()
print(CAS.casualty_severity.map({1: "fatal", 2: "serious", 3: "slight"}).value_counts().to_string())
INJ_SEVNAME
Fatal Injury (K) 41025
No Apparent Injury (O) 24285
Suspected Minor Injury (B) 9649
Suspected Serious Injury (A) 9563
Possible Injury (C) 6585
Unknown/Not Reported 1458
Injured, Severity Unknown 200
Died Prior to Crash* 3
most_severe_injury
FATAL 111
INCAPACITATING INJURY 1628
NO INDICATION OF INJURY 93363
NONINCAPACITATING INJURY 9968
REPORTED, NOT EVIDENT 6736
NaN 251
casualty_severity
slight 105323
serious 26030
fatal 1624
Three sources, three shapes. FARS grades every person in a fatal crash on KABCO, so killed people dominate; Chicago's records are mostly crashes with no injury at all; STATS19 has only injured casualties, most of them slight.
How soon fatal happens, KABCO, STATS19 grades
1. How soon "fatal" happens
FARS records the hours and minutes from the crash to each death. The 30-day rule cuts the series off at 720 hours:
k = P[P.INJ_SEV == 4]
lag = k.LAG_HRS[k.LAG_HRS < 999] + k.LAG_MINS[k.LAG_HRS < 999].clip(upper=59) / 60
print(f"deaths with a known time: {len(lag):,} of {len(k):,}")
for h, label in ((1, "within an hour"), (24, "within a day"), (168, "within a week"), (720, "within 30 days")):
print(f"{label:16s} {(lag < h).mean():.1%}")
print(f"died at the scene: {(k.DOANAME == 'Died at Scene').mean():.1%}")
deaths with a known time: 38,946 of 41,025
within an hour 70.2%
within a day 86.4%
within a week 94.3%
within 30 days 100.0%
died at the scene: 56.7%
Of the deaths with a recorded time, 70.2% happened within an hour of the crash and 86.4% within a day; 94.3% within a week. 56.7% of people killed died at the scene. The 30-day rule decides only a few percent of cases, but those are the ones that make a year's total provisional.
2. KABCO in a city's crash records
Chicago's records grade each crash by its most severe injury, on the same scale with different words:
order = ["FATAL", "INCAPACITATING INJURY", "NONINCAPACITATING INJURY", "REPORTED, NOT EVIDENT", "NO INDICATION OF INJURY"]
c = CHI.set_index("most_severe_injury").n.reindex(order)
kabco = dict(zip(order, "KABCO"))
print(pd.DataFrame({"KABCO": [kabco[o] for o in order], "crashes": c, "share": (c / c.sum()).map("{:.2%}".format)}).to_string())
print(f"crashes with any injury (K, A, B or C): {c.iloc[:4].sum() / c.sum():.1%}; K or A: {c.iloc[:2].sum() / c.sum():.2%}")
KABCO crashes share
most_severe_injury
FATAL K 111 0.10%
INCAPACITATING INJURY A 1628 1.46%
NONINCAPACITATING INJURY B 9968 8.92%
REPORTED, NOT EVIDENT C 6736 6.02%
NO INDICATION OF INJURY O 93363 83.50%
crashes with any injury (K, A, B or C): 16.5%; K or A: 1.56%
Five in six of Chicago's 2024 crashes injured nobody. 16.5% injured someone, and 1.56% killed or incapacitated someone: 1,628 crashes with an incapacitating injury for 111 fatal crashes.
3. Three grades and an adjustment in STATS19
STATS19 has no "possible injury" or "no injury" grade: a collision is in the data because someone was injured. Its serious grade needs the adjustment for recording method:
CAS["ksi_adjusted"] = (CAS.casualty_severity == 1) + CAS.casualty_adjusted_severity_serious
print(f"casualties: {len(CAS):,}; killed {(CAS.casualty_severity == 1).sum():,}; serious as recorded {(CAS.casualty_severity == 2).sum():,}, "
f"adjusted {CAS.casualty_adjusted_severity_serious.sum():,.0f}")
print(f"KSI share of casualties: recorded {(CAS.casualty_severity <= 2).mean():.1%}, adjusted {CAS.ksi_adjusted.mean():.1%}")
casualties: 132,977; killed 1,624; serious as recorded 26,030, adjusted 27,349
KSI share of casualties: recorded 20.8%, adjusted 21.8%
Britain recorded 1,624 deaths and 26,030 serious injuries in 2023; adjusted for recording method, serious injuries were 27,349, and a fifth of all casualties were killed or seriously injured.
Injured survivors of fatal crashes
The data used on this page
NHTSA's FARS 2023 person file; the City of Chicago's Traffic Crashes - Crashes (85ca-t3if) for 2024, counted by most severe injury on the server; and the DfT's STATS19 2023 casualty file.
import zipfile
from pathlib import Path
import pandas as pd
import requests
Path("data").mkdir(exist_ok=True)
SRC = {"FARS2023NationalCSV.zip": "https://static.nhtsa.gov/nhtsa/downloads/FARS/2023/National/FARS2023NationalCSV.zip",
"dft-road-casualty-statistics-casualty-2023.csv": "https://data.dft.gov.uk/road-accidents-safety-data/dft-road-casualty-statistics-casualty-2023.csv"}
for name, url in SRC.items():
if not Path("data", name).exists():
Path("data", name).write_bytes(requests.get(url, timeout=600).content)
P = pd.read_csv(zipfile.ZipFile("data/FARS2023NationalCSV.zip").open("FARS2023NationalCSV/person.csv"), encoding="latin1", low_memory=False,
usecols=["INJ_SEV", "INJ_SEVNAME", "LAG_HRS", "LAG_MINS", "DOANAME"])
f = Path("data/chicago_crashes_2024_by_injury.json")
if not f.exists():
f.write_bytes(requests.get("https://data.cityofchicago.org/resource/85ca-t3if.json", timeout=300, params={
"$select": "most_severe_injury, count(*) AS n", "$where": "crash_date >= '2024-01-01' AND crash_date < '2025-01-01'",
"$group": "most_severe_injury"}).content)
CHI = pd.read_json(f).astype({"n": int})
CAS = pd.read_csv("data/dft-road-casualty-statistics-casualty-2023.csv", low_memory=False)
print(f"FARS people: {len(P):,}; Chicago crashes 2024: {CHI.n.sum():,}; STATS19 casualties: {len(CAS):,}")
FARS people: 92,768; Chicago crashes 2024: 112,057; STATS19 casualties: 132,977
Example 1: the injured survivors of fatal crashes
A fatal crash is graded by its worst outcome, but most people in fatal crashes are not killed. Grade the survivors:
surv = P[P.INJ_SEV.isin([0, 1, 2, 3])]
print(f"people in fatal crashes: {len(P):,}; killed {(P.INJ_SEV == 4).sum():,}; survivors with a KABCO grade {len(surv):,}")
print((surv.INJ_SEVNAME.value_counts(normalize=True)).map("{:.1%}".format).to_string())
people in fatal crashes: 92,768; killed 41,025; survivors with a KABCO grade 50,082
INJ_SEVNAME
No Apparent Injury (O) 48.5%
Suspected Minor Injury (B) 19.3%
Suspected Serious Injury (A) 19.1%
Possible Injury (C) 13.1%
For the 41,025 people killed in fatal crashes, 50,082 survivors have a KABCO grade; half had no apparent injury and 19.1% a suspected serious one.
Why police need a quick severity scale
Severity scales exist because police officers at a crash scene need a quick, consistent way to record how badly people were hurt, without a medical diagnosis. KABCO, used across the US and adopted in the Model Minimum Uniform Crash Criteria, grades what the officer can see or is told: killed, serious (incapacitating), minor (evident but not incapacitating), possible (complaint of pain), none. STATS19's three classes cover only injury collisions and define serious by type of injury, such as fractures, or admission to hospital, which is why the move to injury-based recording raised its serious counts.
Two consequences follow for analysis. The grades are judgements made early, often before anyone knows how the injury will develop, and they differ in reliability: fatal is the firmest, A and serious are reasonably firm, and B, C and slight are loose, with C depending largely on what the person reports. And the grades are not interchangeable between systems: KSI in Britain is close to, but not the same as, K plus A in the US, and under a 30-day death rule a year's count is not complete until 30 days after it ends.
Medical scales, unknown severity and the 30-day rule
- Medical scales: hospital data use clinical scales such as the Abbreviated Injury Scale; linking police and hospital records shows how far police grades differ.
- Unknown severity: FARS has codes for injured with severity unknown and unknown; Chicago has records with no grade; count them.
- Crash or person: Chicago grades crashes by their worst injury; FARS and STATS19 grade people; compare like with like.
- Died prior to crash: FARS has a code for a driver who died before the crash, from a medical event, who is not a road death.
- The 30-day rule: deaths after 30 days are not road deaths in FARS or STATS19, even if caused by the crash.
Internal links
- Why did serious injuries jump in my STATS19 time series? β a change of recording method
- How to build a high-injury network from crash data in Python β KSI from Chicago's grades
- How to map fatal road crashes in the US with FARS in Python β the FARS person file
FAQ
What is the KABCO injury scale?
The US police crash report scale: K killed, A suspected serious injury, B suspected minor injury, C possible injury, O no apparent injury.
What counts as a road death?
A death within 30 days of the crash, as a result of it, in both FARS and STATS19; in FARS 2023, 70% of deaths happened within an hour.
What is the difference between KSI and K plus A?
KSI is Britain's killed or seriously injured, with serious defined by injury type; K plus A is the US equivalent from police judgement; they are close but not identical.
How common are serious injuries compared with deaths?
In Chicago's 2024 crash records there were 1,628 crashes whose worst injury was incapacitating for 111 fatal crashes, about 15 to 1.