Getting and cleaning the data

With the news that the Patrick Mahomes led 15 win Kansas City Chiefs never scored more than thirty points this season, let’s look at how often each team has scored more than 30 points in a game by season since 1999. We’ll be using the nflfastR package to get the play-by-play results for each game

## # A tibble: 1,228,637 × 372
##    play_id game_id     old_game_id home_team away_team season_type  week posteam
##      <dbl> <chr>       <chr>       <chr>     <chr>     <chr>       <int> <chr>  
##  1      35 1999_01_AR… 1999091200  PHI       ARI       REG             1 PHI    
##  2      60 1999_01_AR… 1999091200  PHI       ARI       REG             1 PHI    
##  3      82 1999_01_AR… 1999091200  PHI       ARI       REG             1 PHI    
##  4     103 1999_01_AR… 1999091200  PHI       ARI       REG             1 PHI    
##  5     126 1999_01_AR… 1999091200  PHI       ARI       REG             1 PHI    
##  6     150 1999_01_AR… 1999091200  PHI       ARI       REG             1 PHI    
##  7     176 1999_01_AR… 1999091200  PHI       ARI       REG             1 ARI    
##  8     197 1999_01_AR… 1999091200  PHI       ARI       REG             1 ARI    
##  9     218 1999_01_AR… 1999091200  PHI       ARI       REG             1 ARI    
## 10     240 1999_01_AR… 1999091200  PHI       ARI       REG             1 ARI    
## # ℹ 1,228,627 more rows
## # ℹ 364 more variables: posteam_type <chr>, defteam <chr>, side_of_field <chr>,
## #   yardline_100 <dbl>, game_date <chr>, quarter_seconds_remaining <dbl>,
## #   half_seconds_remaining <dbl>, game_seconds_remaining <dbl>,
## #   game_half <chr>, quarter_end <dbl>, drive <dbl>, sp <dbl>, qtr <dbl>,
## #   down <dbl>, goal_to_go <dbl>, time <chr>, yrdln <chr>, ydstogo <dbl>,
## #   ydsnet <dbl>, desc <chr>, play_type <chr>, yards_gained <dbl>, …

There are over 1.2 million rows in the data set, where each row corresponds to a play in a game. To display how often each team scores more than 30 points, we’ll summarize the score results of each team during the regular season, condensing the data set down from 1 row = 1 play to 1 row = game (6,692 regular season games played).

date season week season_type home_team away_team home_score away_score
2001-11-18 2001 10 REG TB CHI 24 27
2002-12-08 2002 14 REG TB ATL 34 10
2003-09-07 2003 1 REG CLE IND 6 9
2007-11-04 2007 9 REG NO JAX 41 24
2009-11-22 2009 11 REG DAL WAS 7 6
2010-01-03 2009 17 REG TB ATL 10 20
2010-11-21 2010 11 REG SF TB 0 21
2011-11-06 2011 9 REG NO TB 27 16
2016-11-27 2016 12 REG CLE NYG 13 27
2021-10-31 2021 8 REG DET PHI 6 44

To better organize the teams, we’ll create a data.frame called division that indicates which team is in each division:

##    team division
## 1   BUF     AFCE
## 2   MIA     AFCE
## 3    NE     AFCE
## 4   NYJ     AFCE
## 5   BAL     AFCN
## 6   CIN     AFCN
## 7   CLE     AFCN
## 8   PIT     AFCN
## 9   HOU     AFCS
## 10  IND     AFCS
## 11  JAX     AFCS
## 12  TEN     AFCS
## 13  DEN     AFCW
## 14   KC     AFCW
## 15  LAC     AFCW
## 16   LV     AFCW
## 17  DAL     NFCE
## 18  NYG     NFCE
## 19  PHI     NFCE
## 20  WAS     NFCE
## 21  CHI     NFCN
## 22  DET     NFCN
## 23   GB     NFCN
## 24  MIN     NFCN
## 25  ATL     NFCS
## 26  CAR     NFCS
## 27   NO     NFCS
## 28   TB     NFCS
## 29  ARI     NFCW
## 30   LA     NFCW
## 31  SEA     NFCW
## 32   SF     NFCW

Next, we’ll count how many times each team scores >30 points in a season and add the division the team is in:

season team_name division 30+ point games
2002 Buffalo Bills AFCE 6
2002 Philadelphia Eagles NFCE 6
2005 Miami Dolphins AFCE 2
2009 Los Angeles Chargers AFCW 5
2009 Buffalo Bills AFCE 2
2011 Cleveland Browns AFCN 0
2017 New York Jets AFCE 2
2017 Denver Broncos AFCW 1
2023 New York Giants NFCE 2
2024 Green Bay Packers NFCN 4

Graphs

Now that we have the data, we can create a line graph per team! Additionally, we’ll add the year each team had the most 30+ games (with the most recent season being displayed if there are tied seasons)

In order to make the graph not toooo cramped, we’ll create two sets of plots, one for each conference, starting with the NFC

NFC Teams

Overall, the Washington Commanders have the worst offense since 1999 (by using >30 point games as a metric), with the Chicago Bears and Arizona Cardinals not that far behind.

AFC Teams

On the AFC side, there are several teams with most of their seasons having a below average number of more than 30 win games in that season: NY Jets, Miami Dolphins, Cleveland Browns, Pittsburgh Steelers, Houston Texans, Jacksonville Jaguars, and Tennessee Titans.

Comparing the two conferences, the NFC has teams with better offenses than the AFC, which tracks with the general sentiment that the NFC has better offenses while the AFC is the conference the better defenses.

So see if the AFC does, in general, have the better defense, let’s create the same graphs, but looking at the number of games where the teams allow more than 30 points per season

Allowing More than 30 points in a game

Getting the data set

season team_name division >30 point games allowed
2002 Buffalo Bills AFCE 5
2002 Philadelphia Eagles NFCE 1
2005 Miami Dolphins AFCE 0
2009 Los Angeles Chargers AFCW 3
2009 Buffalo Bills AFCE 4
2011 Cleveland Browns AFCN 1
2017 New York Jets AFCE 5
2017 Denver Broncos AFCW 3
2023 New York Giants NFCE 4
2024 Green Bay Packers NFCN 3

Graphs for games with more than 30 points allowed per season

NFC Teams: More than 30 points allowed

AFC Teams: More than 30 points allowed

There are several AFC teams with consistently good defenses (like the Patriots, Ravens, and Steelers), but overall, the defenses are about the same across the two conferences