Injuries are the great equalizer in the NFL. A team built to dominate can be brought low by key absences, while an underdog can find opportunity when opponents lose crucial players. For analysts, injuries represent both a challenge and an...
In This Chapter
- Part 5: Advanced Topics
- Learning Objectives
- Introduction: The Injury Factor
- 23.1 The Challenge of Injury Analysis
- 23.2 Position Value Framework
- 23.3 Quantifying Player Value
- 23.4 Building an Injury Adjustment Model
- 23.5 Quarterback Injury Deep Dive
- 23.6 Multiple Injury Scenarios
- 23.7 Game-Time Decision Analysis
- 23.8 In-Game Injury Adjustments
- 23.9 Injury Recovery and Return Analysis
- 23.10 Market Response to Injuries
- 23.11 Building a Complete Injury Model
- 23.12 Case Study: High-Profile Injury Impact
- Summary
- Key Formulas
- Practice Problems
- Chapter 23 Summary
- Looking Ahead
Chapter 23: Injuries and Their Impact
Part 5: Advanced Topics
Learning Objectives
By the end of this chapter, you will be able to:
- Quantify the impact of player injuries on team performance
- Build injury adjustment models for prediction systems
- Understand position-specific injury importance
- Analyze injury report information and practice participation
- Incorporate uncertainty around injury status into predictions
Introduction: The Injury Factor
Injuries are the great equalizer in the NFL. A team built to dominate can be brought low by key absences, while an underdog can find opportunity when opponents lose crucial players. For analysts, injuries represent both a challenge and an opportunity: they introduce uncertainty that must be modeled, but they also create inefficiencies in prediction markets when injury impacts are mispriced.
This chapter develops a systematic framework for quantifying injury impacts. We move beyond simple "star player out = bad" intuition to precise estimates of how specific player absences affect team performance.
23.1 The Challenge of Injury Analysis
Why Injuries Are Difficult to Model
Injuries present unique analytical challenges:
Information Uncertainty - Injury reports are often vague ("questionable") - Game-time decisions create last-minute uncertainty - Severity is rarely disclosed accurately - Recovery timelines are unpredictable
Contextual Complexity - Impact depends on the opponent - Backup quality varies dramatically - Scheme may adjust around absences - Other injuries may compound effects
Sample Size Issues - Star players rarely miss games - Each injury situation is unique - Limited historical comparable situations
The Injury Report System
The NFL requires teams to submit injury reports following specific guidelines:
Designation Meanings:
| Designation | Historical Game Play Rate | Interpretation |
|---|---|---|
| Out | 0% | Definitely not playing |
| Doubtful | ~25% | Unlikely to play |
| Questionable | ~50-60% | Uncertain status |
| Probable* | ~90% | Likely to play |
| No designation | ~95%+ | Expected to play |
Note: "Probable" was removed from NFL reports in 2016, but the concept remains useful.
Practice Participation: - Full: Full participation in practice - Limited: Partial participation - DNP: Did not practice
Practice patterns provide signal: - Full → Full → Full: Very likely to play - DNP → DNP → Limited: Concerning - DNP → DNP → DNP → Questionable: Often game-time decision
23.2 Position Value Framework
Not All Positions Are Equal
The first step in injury analysis is understanding that positions have vastly different impacts on team performance. A starting quarterback's absence affects a team differently than a starting guard's absence.
Quarterback Value
Quarterbacks have outsized importance:
Approximate point spread impact of QB change:
- Elite QB to average backup: 4-7 points
- Good starter to backup: 3-5 points
- Average starter to backup: 2-4 points
Historical Examples:
| Starter | Backup | Spread Impact |
|---|---|---|
| Patrick Mahomes | Chad Henne | ~6 points |
| Aaron Rodgers | Jordan Love (early) | ~5 points |
| Tua Tagovailoa | Skylar Thompson | ~4 points |
| Brock Purdy | Josh Johnson | ~3.5 points |
QB backup quality varies enormously, making quarterback injuries particularly difficult to assess.
Position Importance Hierarchy
Based on historical analysis of injury impacts:
Tier 1 - Highest Impact (3+ points): - Quarterback - Left Tackle (protecting QB blind side)
Tier 2 - High Impact (1-2 points): - Edge Rusher (premier pass rushers) - Cornerback #1 - Wide Receiver #1 - Running Back (elite three-down backs)
Tier 3 - Moderate Impact (0.5-1 point): - Interior Defensive Line - Linebacker (coverage specialists) - Safety - Interior Offensive Line
Tier 4 - Lower Impact (<0.5 points): - Wide Receiver #2-3 - Tight End (depending on scheme) - Depth positions - Special teams (except kicker/punter)
Calculating Position Value
A useful framework for position value:
Position Impact = Player Value - Replacement Value
Where:
- Player Value: Contribution when playing (EPA, WAR, etc.)
- Replacement Value: Expected contribution from backup
Example Calculation:
Starter EPA per game: +5.2 Expected backup EPA per game: +1.8 Position Impact = 5.2 - 1.8 = 3.4 EPA
Converting to points: 3.4 EPA ≈ 2.0 point spread impact
23.3 Quantifying Player Value
Wins Above Replacement (WAR)
WAR provides a comprehensive player value metric:
WAR = (Player EPA - Replacement EPA) / EPA_per_Win
Typical EPA per Win ≈ 25-30 EPA
2023 Positional WAR Leaders (examples):
| Position | Player | Approx WAR |
|---|---|---|
| QB | Lamar Jackson | 8.2 |
| WR | CeeDee Lamb | 2.8 |
| Edge | Myles Garrett | 2.5 |
| CB | Sauce Gardner | 2.2 |
| RB | Christian McCaffrey | 2.1 |
Converting WAR to Game Impact
For single-game analysis:
Per Game Impact = Season WAR / 17
Elite QB (~8 WAR): 0.47 wins per game
Elite WR (~3 WAR): 0.18 wins per game
Elite CB (~2 WAR): 0.12 wins per game
Converting to spread impact (1 point ≈ 0.03 wins):
Elite QB: 0.47 / 0.03 ≈ 15.7 points over replacement
But we compare to backup, not replacement level:
Adjusted Impact = WAR_per_game × Quality_Differential
Expected Points Added (EPA) Framework
EPA provides game-level precision:
def calculate_injury_impact_epa(player_epa_per_play, plays_per_game,
backup_epa_per_play):
"""
Calculate expected impact from player absence.
Args:
player_epa_per_play: Starter's EPA contribution
plays_per_game: Expected plays for position
backup_epa_per_play: Backup's expected EPA
Returns:
Expected point swing from injury
"""
starter_contribution = player_epa_per_play * plays_per_game
backup_contribution = backup_epa_per_play * plays_per_game
epa_impact = starter_contribution - backup_contribution
# Convert EPA to points (rough 1:1 for offense)
return epa_impact
Example: Elite Wide Receiver Absence
- Starter EPA/play: +0.15 (elite)
- Expected targets per game: 10
- Backup EPA/play: +0.02 (average)
Impact = (0.15 - 0.02) × 10 = 1.3 expected points
23.4 Building an Injury Adjustment Model
The Comprehensive Model
A complete injury adjustment considers multiple factors:
Total Adjustment = Σ (Position_Weight × Player_Value × Play_Probability)
Where:
- Position_Weight: Importance of position (0-1 scale)
- Player_Value: Individual's value above backup
- Play_Probability: Likelihood of not playing (0-1)
Step 1: Establish Position Weights
Based on historical variance explained:
| Position | Weight | Rationale |
|---|---|---|
| QB | 1.00 | Maximum impact |
| LT | 0.35 | Protects QB |
| Edge | 0.30 | Pass rush crucial |
| CB1 | 0.25 | Coverage importance |
| WR1 | 0.25 | Receiving threat |
| RB | 0.20 | Variable by scheme |
| Interior OL | 0.15 | Important but fungible |
| TE | 0.15 | Scheme dependent |
| Other | 0.10 | Lower impact |
Step 2: Calculate Player Value Over Backup
For each player, estimate value differential:
def player_value_differential(player_stats, backup_stats, league_average):
"""
Calculate how much better the starter is than backup.
Returns value on -5 to +5 point scale
"""
# Normalize to z-scores
player_z = (player_stats - league_average) / league_std
backup_z = (backup_stats - league_average) / league_std
differential_z = player_z - backup_z
# Convert to point scale (each z ≈ 1.5 points for QB, less for others)
return differential_z * position_conversion_factor
Step 3: Apply Probability Adjustments
Convert injury status to probability:
def injury_probability(designation, practice_pattern):
"""
Estimate probability player misses game.
Args:
designation: 'out', 'doubtful', 'questionable', etc.
practice_pattern: List of ['full', 'limited', 'dnp']
Returns:
Probability of not playing (0-1)
"""
base_probabilities = {
'out': 1.00,
'doubtful': 0.75,
'questionable': 0.40,
'probable': 0.10,
'none': 0.05
}
base_prob = base_probabilities.get(designation, 0.5)
# Adjust for practice pattern
practice_adjustment = calculate_practice_adjustment(practice_pattern)
return min(1.0, base_prob + practice_adjustment)
Step 4: Aggregate Team Impact
Sum individual impacts:
def total_injury_adjustment(injuries, team_side):
"""
Calculate total spread adjustment for all injuries.
Args:
injuries: List of (position, player_value, probability)
team_side: 'home' or 'away'
Returns:
Spread adjustment in points
"""
total_adjustment = 0
for position, player_value, miss_probability in injuries:
position_weight = POSITION_WEIGHTS[position]
impact = position_weight * player_value * miss_probability
total_adjustment += impact
# Positive adjustment = team gets worse
if team_side == 'home':
return total_adjustment # Add to spread
else:
return -total_adjustment # Subtract from spread
23.5 Quarterback Injury Deep Dive
The Special Case of Quarterbacks
Quarterback injuries deserve special treatment due to their outsized impact:
QB Injury Impact = f(Starter_Quality, Backup_Quality, Scheme_Dependence)
Starter Quality Tiers
| Tier | Examples | Approximate Value |
|---|---|---|
| Elite | Mahomes, Allen | +4 to +6 points |
| Good | Burrow, Herbert | +3 to +4 points |
| Average | Cousins, Goff | +1 to +2 points |
| Below Average | Various | 0 to +1 points |
Backup Quality Assessment
Backup quarterbacks fall into categories:
Quality Backup (+1 to +2 points over replacement) - Experienced NFL starter - Former high draft pick with starts - Veteran with system knowledge
Average Backup (replacement level) - Career backup - Limited starting experience - Adequate but not impactful
Below Replacement (-1 to -2 points) - Undrafted emergency option - Practice squad elevation - Very limited experience
The Uncertainty Factor
Backup performance is highly variable:
Backup QB Performance Distribution:
- Mean: Approximately 0 (replacement level)
- Standard Deviation: 0.5 EPA/dropback
This means outcome range is wide:
- 10th percentile: Disaster (-0.64 EPA/db)
- 50th percentile: Mediocre (0.00 EPA/db)
- 90th percentile: Surprisingly good (+0.64 EPA/db)
This variance should widen confidence intervals for games with backup QBs.
23.6 Multiple Injury Scenarios
Compounding Effects
When multiple players are injured, effects may compound:
Offensive Line Example: - One lineman out: ~0.5 point impact - Two linemen out: ~1.5 point impact (not 1.0) - Three linemen out: ~3.0+ point impact
The non-linear relationship reflects that: - Communication becomes harder - Protection schemes break down - Backup quality drops with depth
Modeling Compound Effects
def compound_injury_adjustment(injuries_by_position):
"""
Calculate adjustment accounting for compound effects.
Args:
injuries_by_position: Dict mapping position to injury count
Returns:
Adjusted impact including compound effects
"""
base_impact = 0
compound_multiplier = 1.0
for position, count in injuries_by_position.items():
# Base impact
base = POSITION_WEIGHTS[position] * count
base_impact += base
# Compound effect for multiple at same position group
if count > 1:
compound_multiplier *= (1 + 0.2 * (count - 1))
# Position group interactions
if 'OL' in injuries_by_position and 'QB' not in injuries_by_position:
# QB faces more pressure, implicit impact
compound_multiplier *= 1.1
return base_impact * compound_multiplier
Injury Correlation
Some injuries are correlated:
Within-Game Correlation: - Physical games lead to more injuries - Defensive injuries may cluster - Offensive line injuries cascade
Historical Correlation: - Teams with poor medical staff have more injuries - Artificial turf associated with specific injuries - Age correlates with injury risk
23.7 Game-Time Decision Analysis
The "Questionable" Problem
"Questionable" designations create analytical challenges:
- 40-60% play rate historically
- Wide range of conditions
- Game-time announcements
- May play but limited
Modeling Uncertainty
For game-time decisions, model two scenarios:
def gameday_injury_analysis(questionable_players, model):
"""
Analyze game accounting for questionable players.
Returns projections for different scenarios.
"""
scenarios = {}
# Generate all combinations
for combo in itertools.product([True, False], repeat=len(questionable_players)):
scenario_injuries = [p for p, plays in zip(questionable_players, combo) if not plays]
adjustment = calculate_adjustment(scenario_injuries)
probability = calculate_scenario_probability(combo, questionable_players)
scenarios[combo] = {
'adjustment': adjustment,
'probability': probability
}
# Expected adjustment
expected = sum(s['adjustment'] * s['probability'] for s in scenarios.values())
# Variance in outcomes
variance = sum(s['probability'] * (s['adjustment'] - expected)**2
for s in scenarios.values())
return {
'expected_adjustment': expected,
'std_adjustment': np.sqrt(variance),
'scenarios': scenarios
}
Practice Report Signals
Practice participation provides signal:
| Pattern | Play Rate | Interpretation |
|---|---|---|
| F-F-F | 95%+ | Almost certain to play |
| L-L-F | 85% | Likely to play |
| L-L-L | 60% | Uncertain |
| D-D-L | 40% | Concerning |
| D-D-D | 20% | Unlikely |
23.8 In-Game Injury Adjustments
When Injuries Occur During Games
Mid-game injuries require live adjustment:
def ingame_injury_adjustment(player, time_remaining, current_score_differential):
"""
Adjust win probability for in-game injury.
Args:
player: Injured player information
time_remaining: Seconds remaining in game
current_score_differential: Current score difference
Returns:
Win probability adjustment
"""
# Base impact
player_value = calculate_player_value(player)
# Time-weighted impact (less time = less impact)
time_factor = time_remaining / 3600 # Proportion of game remaining
# Score context (injuries matter more in close games)
score_factor = 1.0 / (1 + abs(current_score_differential) / 14)
impact = player_value * time_factor * score_factor
return impact
Historical In-Game Impact
Analysis of in-game quarterback injuries:
| Time of Injury | WP Impact | Notes |
|---|---|---|
| 1st Quarter | -8% to -15% | Full impact |
| 2nd Quarter | -6% to -12% | Significant |
| 3rd Quarter | -4% to -10% | Still meaningful |
| 4th Quarter | -2% to -8% | Context dependent |
23.9 Injury Recovery and Return Analysis
Return Timeline Expectations
Different injuries have different recovery patterns:
| Injury Type | Typical Recovery | Variance |
|---|---|---|
| Concussion | 1-2 weeks | High (protocol) |
| Hamstring | 2-4 weeks | Moderate |
| High ankle sprain | 4-6 weeks | High |
| MCL sprain | 4-8 weeks | Moderate |
| ACL tear | 9-12 months | Low |
Performance After Return
Players returning from injury often underperform initially:
First Game Back Performance (relative to baseline):
- Soft tissue: -15% to -25%
- Concussion: -5% to -15%
- ACL (first year back): -10% to -20%
Modeling Return Impact
def returned_player_adjustment(player, injury_type, games_since_return):
"""
Adjust player value for recent return from injury.
Args:
player: Player information
injury_type: Type of injury returned from
games_since_return: Games played since return
Returns:
Adjusted player value
"""
base_value = player['normal_value']
# Recovery factors by injury type
recovery_rates = {
'soft_tissue': 0.85, # Initial performance
'concussion': 0.90,
'structural': 0.75
}
initial_rate = recovery_rates.get(injury_type, 0.85)
# Gradual recovery over games
games_to_full = {'soft_tissue': 3, 'concussion': 2, 'structural': 8}
recovery_games = games_to_full.get(injury_type, 4)
recovery_factor = min(1.0, initial_rate + (1 - initial_rate) *
games_since_return / recovery_games)
return base_value * recovery_factor
23.10 Market Response to Injuries
How Markets Price Injuries
Betting markets incorporate injury information:
Immediate Response: - Major QB injury: 3-5 point line movement - Star player: 1-2 point movement - Role player: 0.5 or less
Information Flow: - Official report: Full market adjustment - Social media rumors: Partial adjustment - Game-time announcement: Final adjustment
Finding Value in Injury Markets
Markets may misprice injuries when:
-
Overreaction to star names - Backup quality underestimated - Scheme adjustment capability ignored
-
Underreaction to depth - Multiple injuries not fully compounded - Practice squad usage not anticipated
-
Timing differences - Early week information not fully priced - Game-time status creates opportunities
Tracking Market Efficiency
def analyze_injury_market_efficiency(games_df):
"""
Analyze how well markets price injuries.
Args:
games_df: DataFrame with injury info, lines, results
Returns:
Analysis of market efficiency
"""
results = {
'qb_injuries': {'ats_record': [], 'clv': []},
'multiple_injuries': {'ats_record': [], 'clv': []},
'game_time_decisions': {'ats_record': [], 'clv': []}
}
for _, game in games_df.iterrows():
# Categorize game
if game['qb_out']:
category = 'qb_injuries'
elif game['total_injuries'] >= 3:
category = 'multiple_injuries'
elif game['game_time_decision']:
category = 'game_time_decisions'
else:
continue
# Track results
results[category]['ats_record'].append(game['covered'])
results[category]['clv'].append(game['clv'])
return results
23.11 Building a Complete Injury Model
Putting It All Together
A comprehensive injury adjustment system:
class NFLInjuryModel:
"""Complete injury impact model."""
def __init__(self, player_values, backup_values, position_weights):
self.player_values = player_values
self.backup_values = backup_values
self.position_weights = position_weights
def calculate_team_adjustment(self, team, injuries):
"""
Calculate total injury adjustment for a team.
Args:
team: Team identifier
injuries: List of injury information
Returns:
Spread adjustment in points
"""
total_adjustment = 0
position_counts = {}
for injury in injuries:
player = injury['player']
status = injury['status']
position = injury['position']
# Get miss probability
miss_prob = self._get_miss_probability(status, injury.get('practice', []))
# Get player value differential
starter_value = self.player_values.get(player, 0)
backup_value = self.backup_values.get(f"{team}_{position}_backup", 0)
differential = starter_value - backup_value
# Apply position weight
weight = self.position_weights.get(position, 0.1)
# Calculate impact
impact = weight * differential * miss_prob
total_adjustment += impact
# Track for compound effects
pos_group = self._get_position_group(position)
position_counts[pos_group] = position_counts.get(pos_group, 0) + miss_prob
# Apply compound multiplier
compound = self._calculate_compound_effect(position_counts)
return total_adjustment * compound
def _get_miss_probability(self, status, practice_pattern):
"""Convert status and practice to miss probability."""
base = {'out': 1.0, 'doubtful': 0.75, 'questionable': 0.45}
prob = base.get(status.lower(), 0.05)
# Adjust for practice
if practice_pattern:
if practice_pattern[-1] == 'full':
prob *= 0.6
elif practice_pattern[-1] == 'dnp':
prob *= 1.3
return min(1.0, prob)
def _get_position_group(self, position):
"""Map position to group for compound effects."""
groups = {
'LT': 'OL', 'LG': 'OL', 'C': 'OL', 'RG': 'OL', 'RT': 'OL',
'DE': 'DL', 'DT': 'DL',
'CB': 'secondary', 'S': 'secondary', 'FS': 'secondary', 'SS': 'secondary'
}
return groups.get(position, position)
def _calculate_compound_effect(self, position_counts):
"""Calculate multiplier for compound injuries."""
multiplier = 1.0
for group, count in position_counts.items():
if count > 1:
multiplier *= (1 + 0.15 * (count - 1))
return min(2.0, multiplier) # Cap at 2x
Validation Approach
Test injury model against historical data:
Validation Metrics:
1. Does adjustment correlate with actual margin impact?
2. Does adjustment improve model accuracy?
3. How does adjustment compare to market response?
23.12 Case Study: High-Profile Injury Impact
Example: Elite Quarterback Injury
Scenario: Team's franchise QB suffers season-ending injury in Week 8
Pre-Injury Status: - Team record: 6-1 - Point differential: +78 - Playoff probability: 95% - Super Bowl odds: 12%
Immediate Analysis:
-
Backup assessment: - Career stats: 4 starts, 1-3 record - EPA/play: -0.08 (below average) - Experience in system: 3 years
-
Model adjustment: - Starter value: +6.5 points above replacement - Backup value: -1.5 points vs replacement - Differential: 8.0 points - Position weight: 1.0 - Spread adjustment: +8.0 points
-
Season projection update: - Expected wins rest of season: from 7.5 to 4.2 - Playoff probability: from 95% to 45% - Super Bowl odds: from 12% to 0.5%
Actual Results: - Team went 3-6 remainder - Average margin: -4.2 points - Model predicted margin shift: -8.0 points - Actual shift: -7.5 points
The model slightly overstated the impact, but was within reasonable error bounds.
Summary
Injury analysis requires:
- Position Value Framework - Understanding which positions matter most
- Player Valuation - Quantifying individual value over backups
- Probability Assessment - Converting injury status to miss probability
- Compound Effects - Accounting for multiple injury interactions
- Uncertainty Modeling - Widening confidence intervals for uncertain situations
Key principles: - Quarterbacks have outsized impact - Backup quality matters as much as starter quality - Multiple injuries compound non-linearly - Markets generally price injuries efficiently but not perfectly - Game-time decisions require scenario analysis
Key Formulas
Position Impact:
Impact = Position_Weight × (Starter_Value - Backup_Value) × Miss_Probability
QB Adjustment (simplified):
Adjustment = Starter_Tier - Backup_Tier
Where tiers range from +6 (elite) to -2 (emergency)
Compound Effect:
Compound_Multiplier = Π(1 + 0.15 × (n_injuries_in_group - 1))
Practice Problems
-
A team's starting quarterback (elite tier) is listed as doubtful. The backup is a career backup with limited experience. Calculate the expected spread adjustment.
-
Three offensive linemen are listed as questionable for the same team. How should you model the compound effect?
-
A star wide receiver is returning from a hamstring injury after missing two weeks. How should you adjust his expected value for his first game back?
Chapter 23 Summary
Injuries represent one of the most important factors in NFL prediction. A systematic approach to injury analysis involves quantifying position importance, measuring player value differentials, assessing miss probabilities, and accounting for compound effects. While betting markets are generally efficient at pricing injuries, opportunities exist when injury impacts are over- or under-estimated.
Looking Ahead
Chapter 24 explores Weather Effects on NFL games. We'll examine how temperature, wind, precipitation, and altitude affect game outcomes, and develop models to incorporate weather into predictions.
Related Reading
Explore this topic in other books
Basketball Analytics Injury Risk Prediction Soccer Analytics Injury Prevention Analytics