Skip to contents

Preface

nflseedR is designed to efficiently take over the sophisticated and complex rule set of the NFL regarding division ranks, postseason seeding and draft order. It is intended to be used for NFL season simulations to help modelers focus on their models rather than the tie-breaking procedures. The NFL’s official procedures for breaking ties for postseason playoffs can be found here and this site explains the assigning of draft picks.

However, it must be mentioned that nflseedR does not support all levels of tie-breakers at the moment. The deepest tie-breaker possible at the moment is the strength of schedule. After that, the decision is made at random. It should be noted, however, that the need for additional levels is extremely unlikely in reality.

Using In-Simulation Functions

You can get NFL game data from this function:

And if you prefer, you can take or generate any set of game outcomes and let nflseedR handle all of the NFL seeding and tiebreaker math for you with three in-simulation functions (each can handle thousands of seasons at once):

The following sections will demonstrate how to use them and what input is required.

Loading the package is obligatory, so it is done first (along with dplyr for data wrangling and the pipe):

library(nflseedR)
library(dplyr, warn.conflicts = FALSE)
options(digits = 3)
options(warn = -1)

Load Sharpe Games

games <- nflseedR::load_sharpe_games()
games %>% dplyr::slice_tail(n = 20) %>% knitr::kable()
game_id season game_type week gameday weekday gametime away_team away_score home_team home_score location result total overtime old_game_id gsis nfl_detail_id pfr pff espn ftn away_rest home_rest away_moneyline home_moneyline spread_line away_spread_odds home_spread_odds total_line under_odds over_odds div_game roof surface temp wind away_qb_id home_qb_id away_qb_name home_qb_name away_coach home_coach referee stadium_id stadium
2023_18_ATL_NO 2023 REG 18 2024-01-07 Sunday 13:00 ATL 17 NO 48 Home 31 65 0 2024010700 59440 NA 202401070nor NA 401547649 NA 7 7 145 -175 3.5 -122 102 41.5 -108 -112 1 dome sportturf NA NA 00-0038122 00-0031280 Desmond Ridder Derek Carr Arthur Smith Dennis Allen John Hussey NOR00 Mercedes-Benz Superdome
2023_18_JAX_TEN 2023 REG 18 2024-01-07 Sunday 13:00 JAX 20 TEN 28 Home 8 48 0 2024010702 59443 NA 202401070oti NA 401547652 NA 7 7 -185 154 -3.5 -102 -118 41.5 -112 -108 1 outdoors grass 41 11 00-0036971 00-0029701 Trevor Lawrence Ryan Tannehill Doug Pederson Mike Vrabel Tra Blake NAS00 Nissan Stadium
2023_18_SEA_ARI 2023 REG 18 2024-01-07 Sunday 16:25 SEA 21 ARI 20 Home -1 41 0 2024010712 59429 NA 202401070crd NA 401547638 NA 7 7 -155 130 -2.5 -122 102 48.0 -110 -110 1 closed grass NA NA 00-0030565 00-0035228 Geno Smith Kyler Murray Pete Carroll Jonathan Gannon Adrian Hill PHO00 State Farm Stadium
2023_18_CHI_GB 2023 REG 18 2024-01-07 Sunday 16:25 CHI 9 GB 17 Home 8 26 0 2024010706 59434 NA 202401070gnb NA 401547643 NA 7 7 124 -148 2.5 -102 -118 45.5 -108 -112 1 outdoors grass 34 7 00-0036945 00-0036264 Justin Fields Jordan Love Matt Eberflus Matt LaFleur Carl Cheffers GNB00 Lambeau Field
2023_18_KC_LAC 2023 REG 18 2024-01-07 Sunday 16:25 KC 13 LAC 12 Home -1 25 0 2024010709 59436 NA 202401070sdg NA 401547645 NA 7 7 154 -185 3.5 -115 -105 35.0 -108 -115 1 dome matrixturf NA NA 00-0027948 00-0035282 Blaine Gabbert Easton Stick Andy Reid Brandon Staley Scott Novak LAX01 SoFi Stadium
2023_18_DEN_LV 2023 REG 18 2024-01-07 Sunday 16:25 DEN 14 LV 27 Home 13 41 0 2024010708 59437 NA 202401070rai NA 401547646 NA 7 7 145 -175 3.5 -118 -102 37.5 -115 -105 1 dome grass NA NA 00-0035264 00-0038579 Jarrett Stidham Aidan O’Connell Sean Payton Antonio Pierce Shawn Hochuli VEG00 Allegiant Stadium
2023_18_PHI_NYG 2023 REG 18 2024-01-07 Sunday 16:25 PHI 10 NYG 27 Home 17 37 0 2024010711 59441 NA 202401070nyg NA 401547650 NA 7 7 -238 190 -4.5 -112 -108 43.0 -105 -115 1 outdoors fieldturf 36 12 00-0036389 00-0028118 Jalen Hurts Tyrod Taylor Nick Sirianni Brian Daboll Craig Wrolstad NYC01 MetLife Stadium
2023_18_LA_SF 2023 REG 18 2024-01-07 Sunday 16:25 LA 21 SF 20 Home -1 41 0 2024010710 59442 NA 202401070sfo NA 401547651 NA 7 7 200 -245 5.5 -108 -112 40.0 -108 -112 1 outdoors grass 52 11 00-0032950 00-0034869 Carson Wentz Sam Darnold Sean McVay Kyle Shanahan Clay Martin SFO01 Levi’s Stadium
2023_18_DAL_WAS 2023 REG 18 2024-01-07 Sunday 16:25 DAL 38 WAS 10 Home -28 48 0 2024010707 59444 NA 202401070was NA 401547653 NA 8 7 -850 575 -13.0 -115 -105 47.5 -110 -110 1 outdoors grass 48 13 00-0033077 00-0037077 Dak Prescott Sam Howell Mike McCarthy Ron Rivera Shawn Smith WAS00 FedExField
2023_18_BUF_MIA 2023 REG 18 2024-01-07 Sunday 20:20 BUF 21 MIA 14 Home -7 35 0 2024010713 59438 NA 202401070mia NA 401547647 NA 7 7 -155 130 -2.5 -125 105 47.5 -110 -110 1 outdoors grass 63 6 00-0034857 00-0036212 Josh Allen Tua Tagovailoa Sean McDermott Mike McDaniel Alex Kemp MIA00 Hard Rock Stadium
2023_19_CLE_HOU 2023 WC 19 2024-01-13 Saturday 16:30 CLE 14 HOU 45 Home 31 59 0 2024011300 59494 NA 202401130htx NA 401547749 NA 6 7 -148 124 -2.5 -110 -110 45.0 -105 -115 0 closed astroturf NA NA 00-0026158 00-0039163 Joe Flacco C.J. Stroud Kevin Stefanski DeMeco Ryans Clay Martin HOU00 NRG Stadium
2023_19_MIA_KC 2023 WC 19 2024-01-13 Saturday 20:00 MIA 7 KC 26 Home 19 33 0 2024011301 59495 NA 202401130kan NA 401547750 NA 6 6 190 -230 4.5 -102 -118 43.5 -118 -102 0 outdoors grass -4 19 00-0036212 00-0033873 Tua Tagovailoa Patrick Mahomes Mike McDaniel Andy Reid Brad Rogers KAN00 GEHA Field at Arrowhead Stadium
2023_19_GB_DAL 2023 WC 19 2024-01-14 Sunday 16:30 GB 48 DAL 32 Home -16 80 0 2024011401 59497 NA 202401140dal NA 401547752 NA 7 7 275 -345 7.0 102 -122 52.5 -105 -115 0 closed matrixturf NA NA 00-0036264 00-0033077 Jordan Love Dak Prescott Matt LaFleur Mike McCarthy Ron Torbert DAL00 AT&T Stadium
2023_19_LA_DET 2023 WC 19 2024-01-14 Sunday 20:00 LA 23 DET 24 Home 1 47 0 2024011402 59498 NA 202401140det NA 401547753 NA 7 7 136 -162 3.5 -122 102 52.5 -102 -118 0 dome fieldturf NA NA 00-0026498 00-0033106 Matthew Stafford Jared Goff Sean McVay Dan Campbell Craig Wrolstad DET00 Ford Field
2023_19_PIT_BUF 2023 WC 19 2024-01-15 Monday 16:30 PIT 17 BUF 31 Home 14 48 0 2024011501 59496 NA 202401150buf NA 401547751 NA 9 8 370 -485 10.0 -108 -112 39.5 -115 -105 0 outdoors a_turf 17 10 00-0034771 00-0034857 Mason Rudolph Josh Allen Mike Tomlin Sean McDermott Carl Cheffers BUF00 New Era Field
2023_19_PHI_TB 2023 WC 19 2024-01-15 Monday 20:00 PHI 9 TB 32 Home 23 41 0 2024011500 59499 NA 202401150tam NA 401547754 NA 8 8 -162 136 -2.5 -125 105 43.0 -102 -118 0 outdoors grass 65 2 00-0036389 00-0034855 Jalen Hurts Baker Mayfield Nick Sirianni Todd Bowles Adrian Hill TAM00 Raymond James Stadium
2023_20_HOU_BAL 2023 DIV 20 2024-01-20 Saturday 16:30 HOU NA BAL NA Home NA NA NA 2024012001 NA NA 202401200rav NA NA NA 7 14 340 -440 9.5 -110 -110 43.5 -105 -115 0 outdoors grass NA NA 00-0039163 00-0034796 C.J. Stroud Lamar Jackson DeMeco Ryans John Harbaugh NA BAL00 M&T Bank Stadium
2023_20_GB_SF 2023 DIV 20 2024-01-20 Saturday 20:15 GB NA SF NA Home NA NA NA 2024012002 NA NA 202401200sfo NA NA NA 6 13 370 -485 10.0 -110 -110 50.5 -105 -115 0 outdoors grass NA NA 00-0036264 00-0037834 Jordan Love Brock Purdy Matt LaFleur Kyle Shanahan NA SFO01 Levi’s Stadium
2023_20_TB_DET 2023 DIV 20 2024-01-21 Sunday 15:00 TB NA DET NA Home NA NA NA 2024012101 NA NA 202401210det NA NA NA 6 7 230 -285 6.0 -110 -110 49.5 -110 -110 0 dome fieldturf NA NA 00-0034855 00-0033106 Baker Mayfield Jared Goff Todd Bowles Dan Campbell NA DET00 Ford Field
2023_20_KC_BUF 2023 DIV 20 2024-01-21 Sunday 18:30 KC NA BUF NA Home NA NA NA 2024012102 NA NA 202401210buf NA NA NA 8 6 120 -142 2.5 -105 -115 45.5 -110 -110 0 outdoors NA NA 00-0033873 00-0034857 Patrick Mahomes Josh Allen Andy Reid Sean McDermott NA BUF00 New Era Field

This pulls game information from the games.rds file (equivalent to the games.csv file) from Lee Sharpe’s NFL Data Github

Find Division Ranks

This functions computes division ranks based on a data frame containing game results of one or more NFL seasons. So let’s load some game data first (this example uses the game data of the 2012 and 2019 seasons):

games <- nflseedR::load_sharpe_games() %>%
  dplyr::filter(season %in% c(2012, 2019)) %>%
  dplyr::select(sim = season, game_type, week, away_team, home_team, result)

dplyr::glimpse(games)
#> Rows: 534
#> Columns: 6
#> $ sim       <int> 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, …
#> $ game_type <chr> "REG", "REG", "REG", "REG", "REG", "REG", "REG", "REG", "REG…
#> $ week      <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, …
#> $ away_team <chr> "DAL", "IND", "PHI", "STL", "MIA", "ATL", "JAX", "WAS", "BUF…
#> $ home_team <chr> "NYG", "CHI", "CLE", "DET", "HOU", "KC", "MIN", "NO", "NYJ",…
#> $ result    <int> -7, 20, -1, 4, 20, -16, 3, -8, 20, -21, 4, -8, 6, 12, 31, -8…

Please note the required column names:

  • sim : A simulation ID. Normally 1 - n simulated seasons or (like in this case) just the year.

  • game_type : One of ‘REG’, ‘WC’, ‘DIV’, ‘CON’, ‘SB’ indicating if a game was a regular season game or one of the playoff rounds.

  • week : The week of the corresponding NFL season.

  • away_team : Team abbreviation of the away team.

  • home_team : Team abbreviation of the home team.

  • result : Equals home score - away score.

Now the games data frame can be used to compute the division ranks (the parameter .debug is set to TRUE to show what the function is doing).

div_standings <- nflseedR::compute_division_ranks(games, .debug = TRUE)
#>  19:16:07 | Calculating team data
#>  19:16:07 | Calculating head to head
#>  19:16:07 | Calculating division rank #1
#>  19:16:07 | DIV (2): Head-to-head
#>  19:16:07 | DIV (2): Division Record
#>  19:16:07 | Calculating division rank #2
#>  19:16:07 | DIV (3): Head-to-head
#>  19:16:07 | DIV (3): Division Record
#>  19:16:07 | DIV (3): Common Record
#>  19:16:07 | DIV (2): Head-to-head
#>  19:16:07 | DIV (2): Division Record
#>  19:16:07 | DIV (2): Common Record
#>  19:16:07 | DIV (2): Conference Record
#>  19:16:07 | Calculating division rank #3
#>  19:16:07 | DIV (2): Head-to-head
#>  19:16:07 | DIV (2): Division Record
#>  19:16:07 | DIV (2): Common Record
#>  19:16:07 | Calculating division rank #4
dplyr::glimpse(div_standings)
#> List of 2
#>  $ standings: tibble [64 × 16] (S3: tbl_df/tbl/data.frame)
#>   ..$ sim         : int [1:64] 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 ...
#>   ..$ conf        : chr [1:64] "AFC" "AFC" "AFC" "AFC" ...
#>   ..$ division    : chr [1:64] "AFC East" "AFC East" "AFC East" "AFC East" ...
#>   ..$ team        : chr [1:64] "BUF" "MIA" "NE" "NYJ" ...
#>   ..$ games       : int [1:64] 16 16 16 16 16 16 16 16 16 16 ...
#>   ..$ wins        : num [1:64] 6 7 12 6 10 10 5 8 12 11 ...
#>   ..$ true_wins   : int [1:64] 6 7 12 6 10 10 5 8 12 11 ...
#>   ..$ losses      : int [1:64] 10 9 4 10 6 6 11 8 4 5 ...
#>   ..$ ties        : int [1:64] 0 0 0 0 0 0 0 0 0 0 ...
#>   ..$ win_pct     : num [1:64] 0.375 0.438 0.75 0.375 0.625 ...
#>   ..$ div_pct     : num [1:64] 0.333 0.333 1 0.333 0.667 ...
#>   ..$ conf_pct    : num [1:64] 0.417 0.417 0.917 0.333 0.667 ...
#>   ..$ sov         : num [1:64] 0.281 0.415 0.466 0.401 0.438 ...
#>   ..$ sos         : num [1:64] 0.48 0.5 0.496 0.512 0.496 ...
#>   ..$ div_rank    : num [1:64] 4 2 1 3 1 2 4 3 1 2 ...
#>   ..$ max_reg_week: int [1:64] 17 17 17 17 17 17 17 17 17 17 ...
#>  $ h2h      : tibble [2,048 × 6] (S3: tbl_df/tbl/data.frame)
#>   ..$ sim       : int [1:2048] 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 ...
#>   ..$ team      : chr [1:2048] "ARI" "ARI" "ARI" "ARI" ...
#>   ..$ opp       : chr [1:2048] "ARI" "ATL" "BAL" "BUF" ...
#>   ..$ h2h_games : int [1:2048] 0 1 0 1 0 1 0 0 0 0 ...
#>   ..$ h2h_wins  : num [1:2048] 0 0 0 0 0 0 0 0 0 0 ...
#>   ..$ h2h_played: num [1:2048] 0 1 0 1 0 1 0 0 0 0 ...

Please note that the function outputs a list of data frames, the actual division standings as well as a data frame named h2h. The latter is an important input in the other functions (as it is used to break head-to-head ties) and can only be computed with compute_division_ranks().

So here is the resulting division standings data frame for the 2012 season

div_standings %>% 
  purrr::pluck("standings") %>% 
  dplyr::filter(sim == 2012) %>% 
  dplyr::select(division:div_rank) %>% 
  knitr::kable()
division team games wins true_wins losses ties win_pct div_pct conf_pct sov sos div_rank
AFC East BUF 16 6.0 6 10 0 0.375 0.333 0.417 0.281 0.480 4
AFC East MIA 16 7.0 7 9 0 0.438 0.333 0.417 0.415 0.500 2
AFC East NE 16 12.0 12 4 0 0.750 1.000 0.917 0.466 0.496 1
AFC East NYJ 16 6.0 6 10 0 0.375 0.333 0.333 0.401 0.512 3
AFC North BAL 16 10.0 10 6 0 0.625 0.667 0.667 0.438 0.496 1
AFC North CIN 16 10.0 10 6 0 0.625 0.500 0.583 0.381 0.438 2
AFC North CLE 16 5.0 5 11 0 0.312 0.333 0.417 0.388 0.508 4
AFC North PIT 16 8.0 8 8 0 0.500 0.500 0.417 0.438 0.465 3
AFC South HOU 16 12.0 12 4 0 0.750 0.833 0.833 0.432 0.496 1
AFC South IND 16 11.0 11 5 0 0.688 0.667 0.667 0.403 0.441 2
AFC South JAX 16 2.0 2 14 0 0.125 0.333 0.167 0.531 0.539 4
AFC South TEN 16 6.0 6 10 0 0.375 0.167 0.417 0.344 0.512 3
AFC West DEN 16 13.0 13 3 0 0.812 1.000 0.833 0.385 0.457 1
AFC West KC 16 2.0 2 14 0 0.125 0.000 0.000 0.438 0.516 4
AFC West OAK 16 4.0 4 12 0 0.250 0.333 0.333 0.219 0.469 3
AFC West SD 16 7.0 7 9 0 0.438 0.667 0.583 0.286 0.457 2
NFC East DAL 16 8.0 8 8 0 0.500 0.500 0.417 0.422 0.523 3
NFC East NYG 16 9.0 9 7 0 0.562 0.500 0.667 0.490 0.521 2
NFC East PHI 16 4.0 4 12 0 0.250 0.167 0.167 0.484 0.508 4
NFC East WAS 16 10.0 10 6 0 0.625 0.833 0.667 0.450 0.494 1
NFC North CHI 16 10.0 10 6 0 0.625 0.500 0.583 0.403 0.512 3
NFC North DET 16 4.0 4 12 0 0.250 0.000 0.250 0.383 0.566 4
NFC North GB 16 11.0 11 5 0 0.688 0.833 0.667 0.440 0.508 1
NFC North MIN 16 10.0 10 6 0 0.625 0.667 0.583 0.456 0.520 2
NFC South ATL 16 13.0 13 3 0 0.812 0.500 0.750 0.418 0.422 1
NFC South CAR 16 7.0 7 9 0 0.438 0.500 0.417 0.464 0.516 2
NFC South NO 16 7.0 7 9 0 0.438 0.500 0.417 0.446 0.521 3
NFC South TB 16 7.0 7 9 0 0.438 0.500 0.333 0.446 0.502 4
NFC West ARI 16 5.0 5 11 0 0.312 0.167 0.250 0.475 0.559 4
NFC West SEA 16 11.0 11 5 0 0.688 0.500 0.667 0.534 0.504 2
NFC West SF 16 11.5 11 4 1 0.719 0.583 0.625 0.477 0.504 1
NFC West STL 16 7.5 7 8 1 0.469 0.750 0.542 0.496 0.539 3

In that season the seconds division rank of the NFC South required a three way tie-breaker between the Panthers, Saints and Bucs. It was broken with the three-way Conference Record. This can be seen in the above given console output: ...DIV (3): Common Record for the division rank number 2. The Bucs lost this tie-breaker with a 0.333 win percentage in the conference and the tie-breaking procedure goes on with a 2-way head-to-head comparison.

Find Conference Seedings

This functions computes conference seedings based on the above computed division standings data frame. For efficiency reasons the above computed h2h data frame has to be passed to the function. The easiest way is to pass the list of data frames that is computed in the first step so we can do this (please note the number of playoff seeds):

seeds <- div_standings %>% 
  nflseedR::compute_conference_seeds(h2h = .$h2h, playoff_seeds = 6, .debug = TRUE)
#>  19:16:07 | Calculating seed #1
#>  19:16:07 | CONF (3): Head-to-head Sweep
#>  19:16:07 | Calculating seed #2
#>  19:16:07 | CONF (2): Head-to-head Sweep
#>  19:16:07 | CONF (2): Conference Record
#>  19:16:07 | Calculating seed #3
#>  19:16:08 | Calculating seed #4
#>  19:16:08 | Calculating seed #5
#>  19:16:08 | Calculating seed #6
#>  19:16:08 | CONF (2): Best-in-division reduction
dplyr::glimpse(seeds)
#> List of 2
#>  $ standings: tibble [64 × 17] (S3: tbl_df/tbl/data.frame)
#>   ..$ sim      : int [1:64] 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 ...
#>   ..$ conf     : chr [1:64] "AFC" "AFC" "AFC" "AFC" ...
#>   ..$ division : chr [1:64] "AFC East" "AFC East" "AFC East" "AFC East" ...
#>   ..$ team     : chr [1:64] "BUF" "MIA" "NE" "NYJ" ...
#>   ..$ games    : int [1:64] 16 16 16 16 16 16 16 16 16 16 ...
#>   ..$ wins     : num [1:64] 6 7 12 6 10 10 5 8 12 11 ...
#>   ..$ true_wins: int [1:64] 6 7 12 6 10 10 5 8 12 11 ...
#>   ..$ losses   : int [1:64] 10 9 4 10 6 6 11 8 4 5 ...
#>   ..$ ties     : int [1:64] 0 0 0 0 0 0 0 0 0 0 ...
#>   ..$ win_pct  : num [1:64] 0.375 0.438 0.75 0.375 0.625 ...
#>   ..$ div_pct  : num [1:64] 0.333 0.333 1 0.333 0.667 ...
#>   ..$ conf_pct : num [1:64] 0.417 0.417 0.917 0.333 0.667 ...
#>   ..$ sov      : num [1:64] 0.281 0.415 0.466 0.401 0.438 ...
#>   ..$ sos      : num [1:64] 0.48 0.5 0.496 0.512 0.496 ...
#>   ..$ div_rank : num [1:64] 4 2 1 3 1 2 4 3 1 2 ...
#>   ..$ seed     : num [1:64] NA NA 2 NA 4 6 NA NA 3 5 ...
#>   ..$ exit     : num [1:64] 17 17 NA 17 NA NA 17 17 NA NA ...
#>  $ h2h      : tibble [2,048 × 6] (S3: tbl_df/tbl/data.frame)
#>   ..$ sim       : int [1:2048] 2012 2012 2012 2012 2012 2012 2012 2012 2012 2012 ...
#>   ..$ team      : chr [1:2048] "ARI" "ARI" "ARI" "ARI" ...
#>   ..$ opp       : chr [1:2048] "ARI" "ATL" "BAL" "BUF" ...
#>   ..$ h2h_games : int [1:2048] 0 1 0 1 0 1 0 0 0 0 ...
#>   ..$ h2h_wins  : num [1:2048] 0 0 0 0 0 0 0 0 0 0 ...
#>   ..$ h2h_played: num [1:2048] 0 1 0 1 0 1 0 0 0 0 ...

Just like compute_division_ranks(), this function returns a list of two data frames so we can use it within a pipe. The resulting seeds for the 2012 season are given below.

seeds %>% 
  purrr::pluck("standings") %>% 
  dplyr::filter(sim == 2012) %>% 
  dplyr::select(division:seed) %>% 
  knitr::kable()
division team games wins true_wins losses ties win_pct div_pct conf_pct sov sos div_rank seed
AFC East BUF 16 6.0 6 10 0 0.375 0.333 0.417 0.281 0.480 4 NA
AFC East MIA 16 7.0 7 9 0 0.438 0.333 0.417 0.415 0.500 2 NA
AFC East NE 16 12.0 12 4 0 0.750 1.000 0.917 0.466 0.496 1 2
AFC East NYJ 16 6.0 6 10 0 0.375 0.333 0.333 0.401 0.512 3 NA
AFC North BAL 16 10.0 10 6 0 0.625 0.667 0.667 0.438 0.496 1 4
AFC North CIN 16 10.0 10 6 0 0.625 0.500 0.583 0.381 0.438 2 6
AFC North CLE 16 5.0 5 11 0 0.312 0.333 0.417 0.388 0.508 4 NA
AFC North PIT 16 8.0 8 8 0 0.500 0.500 0.417 0.438 0.465 3 NA
AFC South HOU 16 12.0 12 4 0 0.750 0.833 0.833 0.432 0.496 1 3
AFC South IND 16 11.0 11 5 0 0.688 0.667 0.667 0.403 0.441 2 5
AFC South JAX 16 2.0 2 14 0 0.125 0.333 0.167 0.531 0.539 4 NA
AFC South TEN 16 6.0 6 10 0 0.375 0.167 0.417 0.344 0.512 3 NA
AFC West DEN 16 13.0 13 3 0 0.812 1.000 0.833 0.385 0.457 1 1
AFC West KC 16 2.0 2 14 0 0.125 0.000 0.000 0.438 0.516 4 NA
AFC West OAK 16 4.0 4 12 0 0.250 0.333 0.333 0.219 0.469 3 NA
AFC West SD 16 7.0 7 9 0 0.438 0.667 0.583 0.286 0.457 2 NA
NFC East DAL 16 8.0 8 8 0 0.500 0.500 0.417 0.422 0.523 3 NA
NFC East NYG 16 9.0 9 7 0 0.562 0.500 0.667 0.490 0.521 2 NA
NFC East PHI 16 4.0 4 12 0 0.250 0.167 0.167 0.484 0.508 4 NA
NFC East WAS 16 10.0 10 6 0 0.625 0.833 0.667 0.450 0.494 1 4
NFC North CHI 16 10.0 10 6 0 0.625 0.500 0.583 0.403 0.512 3 NA
NFC North DET 16 4.0 4 12 0 0.250 0.000 0.250 0.383 0.566 4 NA
NFC North GB 16 11.0 11 5 0 0.688 0.833 0.667 0.440 0.508 1 3
NFC North MIN 16 10.0 10 6 0 0.625 0.667 0.583 0.456 0.520 2 6
NFC South ATL 16 13.0 13 3 0 0.812 0.500 0.750 0.418 0.422 1 1
NFC South CAR 16 7.0 7 9 0 0.438 0.500 0.417 0.464 0.516 2 NA
NFC South NO 16 7.0 7 9 0 0.438 0.500 0.417 0.446 0.521 3 NA
NFC South TB 16 7.0 7 9 0 0.438 0.500 0.333 0.446 0.502 4 NA
NFC West ARI 16 5.0 5 11 0 0.312 0.167 0.250 0.475 0.559 4 NA
NFC West SEA 16 11.0 11 5 0 0.688 0.500 0.667 0.534 0.504 2 5
NFC West SF 16 11.5 11 4 1 0.719 0.583 0.625 0.477 0.504 1 2
NFC West STL 16 7.5 7 8 1 0.469 0.750 0.542 0.496 0.539 3 NA

Find Draft Order

This function computes the draft order based on the playoff outcome and the regular season games. It requires all playoff results in the games data frame and the game_type of the Super Bowl has to be "SB". For efficiency reasons the above computed h2h data frame has to be passed to the function as well. The easiest way is to pass the list of data frames that is computed in the above steps:

draft <- seeds %>% 
  nflseedR::compute_draft_order(games = games, h2h = .$h2h, .debug = TRUE)
#>  19:16:08 | Calculating draft order #32
#>  19:16:08 | Calculating draft order #31
#>  19:16:08 | Calculating draft order #30
#>  19:16:08 | Calculating draft order #29
#>  19:16:08 | Calculating draft order #28
#>  19:16:08 | Calculating draft order #27
#>  19:16:08 | Calculating draft order #26
#>  19:16:08 | Calculating draft order #25
#>  19:16:08 | Calculating draft order #24
#>  19:16:08 | Calculating draft order #23
#>  19:16:08 | Calculating draft order #22
#>  19:16:08 | Calculating draft order #21
#>  19:16:08 | Calculating draft order #20
#>  19:16:08 | Calculating draft order #19
#>  19:16:08 | Calculating draft order #18
#>  19:16:08 | Calculating draft order #17
#>  19:16:08 | Calculating draft order #16
#>  19:16:08 | Calculating draft order #15
#>  19:16:08 | Calculating draft order #14
#>  19:16:08 | Calculating draft order #13
#>  19:16:08 | Calculating draft order #12
#>  19:16:08 | Calculating draft order #11
#>  19:16:08 | Calculating draft order #10
#>  19:16:08 | DRAFT: Divisional Rank
#>  19:16:08 | DRAFT: Conference Rank
#>  19:16:08 | CONF (2): Best-in-division reduction
#>  19:16:08 | CONF (2): Head-to-head Sweep
#>  19:16:08 | Calculating draft order #9
#>  19:16:08 | Calculating draft order #8
#>  19:16:09 | Calculating draft order #7
#>  19:16:09 | Calculating draft order #6
#>  19:16:09 | Calculating draft order #5
#>  19:16:09 | Calculating draft order #4
#>  19:16:09 | Calculating draft order #3
#>  19:16:09 | Calculating draft order #2
#>  19:16:09 | Calculating draft order #1
dplyr::glimpse(draft)
#> Rows: 64
#> Columns: 18
#> $ sim         <int> 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012, 2012…
#> $ team        <chr> "BUF", "MIA", "NE", "NYJ", "BAL", "CIN", "CLE", "PIT", "HO…
#> $ conf        <chr> "AFC", "AFC", "AFC", "AFC", "AFC", "AFC", "AFC", "AFC", "A…
#> $ division    <chr> "AFC East", "AFC East", "AFC East", "AFC East", "AFC North…
#> $ games       <int> 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16…
#> $ wins        <dbl> 6, 7, 12, 6, 10, 10, 5, 8, 12, 11, 2, 6, 13, 2, 4, 7, 8, 9…
#> $ true_wins   <int> 6, 7, 12, 6, 10, 10, 5, 8, 12, 11, 2, 6, 13, 2, 4, 7, 8, 9…
#> $ losses      <int> 10, 9, 4, 10, 6, 6, 11, 8, 4, 5, 14, 10, 3, 14, 12, 9, 8, …
#> $ ties        <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
#> $ win_pct     <dbl> 0.375, 0.438, 0.750, 0.375, 0.625, 0.625, 0.312, 0.500, 0.…
#> $ div_pct     <dbl> 0.333, 0.333, 1.000, 0.333, 0.667, 0.500, 0.333, 0.500, 0.…
#> $ conf_pct    <dbl> 0.417, 0.417, 0.917, 0.333, 0.667, 0.583, 0.417, 0.417, 0.…
#> $ sov         <dbl> 0.281, 0.415, 0.466, 0.401, 0.438, 0.381, 0.388, 0.438, 0.…
#> $ sos         <dbl> 0.480, 0.500, 0.496, 0.512, 0.496, 0.438, 0.508, 0.465, 0.…
#> $ div_rank    <dbl> 4, 2, 1, 3, 1, 2, 4, 3, 1, 2, 4, 3, 1, 4, 3, 2, 3, 2, 4, 1…
#> $ seed        <dbl> NA, NA, 2, NA, 4, 6, NA, NA, 3, 5, NA, NA, 1, NA, NA, NA, …
#> $ exit        <dbl> 17, 17, 20, 17, 22, 18, 17, 17, 19, 18, 17, 17, 19, 17, 17…
#> $ draft_order <dbl> 8, 12, 29, 9, 32, 21, 6, 17, 27, 24, 2, 10, 28, 1, 3, 11, …

As this is the final step, the function compute_draft_order does not output h2h again. Instead it directly outputs the final standings including the draft order and the variable exit which indicates the week number of each team’s final game (the Super Bowl Winner’s exit equals 22):

draft %>% 
  dplyr::filter(sim == 2012) %>% 
  dplyr::select(division:draft_order) %>% 
  knitr::kable()
division games wins true_wins losses ties win_pct div_pct conf_pct sov sos div_rank seed exit draft_order
AFC East 16 6.0 6 10 0 0.375 0.333 0.417 0.281 0.480 4 NA 17 8
AFC East 16 7.0 7 9 0 0.438 0.333 0.417 0.415 0.500 2 NA 17 12
AFC East 16 12.0 12 4 0 0.750 1.000 0.917 0.466 0.496 1 2 20 29
AFC East 16 6.0 6 10 0 0.375 0.333 0.333 0.401 0.512 3 NA 17 9
AFC North 16 10.0 10 6 0 0.625 0.667 0.667 0.438 0.496 1 4 22 32
AFC North 16 10.0 10 6 0 0.625 0.500 0.583 0.381 0.438 2 6 18 21
AFC North 16 5.0 5 11 0 0.312 0.333 0.417 0.388 0.508 4 NA 17 6
AFC North 16 8.0 8 8 0 0.500 0.500 0.417 0.438 0.465 3 NA 17 17
AFC South 16 12.0 12 4 0 0.750 0.833 0.833 0.432 0.496 1 3 19 27
AFC South 16 11.0 11 5 0 0.688 0.667 0.667 0.403 0.441 2 5 18 24
AFC South 16 2.0 2 14 0 0.125 0.333 0.167 0.531 0.539 4 NA 17 2
AFC South 16 6.0 6 10 0 0.375 0.167 0.417 0.344 0.512 3 NA 17 10
AFC West 16 13.0 13 3 0 0.812 1.000 0.833 0.385 0.457 1 1 19 28
AFC West 16 2.0 2 14 0 0.125 0.000 0.000 0.438 0.516 4 NA 17 1
AFC West 16 4.0 4 12 0 0.250 0.333 0.333 0.219 0.469 3 NA 17 3
AFC West 16 7.0 7 9 0 0.438 0.667 0.583 0.286 0.457 2 NA 17 11
NFC East 16 8.0 8 8 0 0.500 0.500 0.417 0.422 0.523 3 NA 17 18
NFC East 16 9.0 9 7 0 0.562 0.500 0.667 0.490 0.521 2 NA 17 19
NFC East 16 4.0 4 12 0 0.250 0.167 0.167 0.484 0.508 4 NA 17 4
NFC East 16 10.0 10 6 0 0.625 0.833 0.667 0.450 0.494 1 4 18 22
NFC North 16 10.0 10 6 0 0.625 0.500 0.583 0.403 0.512 3 NA 17 20
NFC North 16 4.0 4 12 0 0.250 0.000 0.250 0.383 0.566 4 NA 17 5
NFC North 16 11.0 11 5 0 0.688 0.833 0.667 0.440 0.508 1 3 19 26
NFC North 16 10.0 10 6 0 0.625 0.667 0.583 0.456 0.520 2 6 18 23
NFC South 16 13.0 13 3 0 0.812 0.500 0.750 0.418 0.422 1 1 20 30
NFC South 16 7.0 7 9 0 0.438 0.500 0.417 0.464 0.516 2 NA 17 14
NFC South 16 7.0 7 9 0 0.438 0.500 0.417 0.446 0.521 3 NA 17 15
NFC South 16 7.0 7 9 0 0.438 0.500 0.333 0.446 0.502 4 NA 17 13
NFC West 16 5.0 5 11 0 0.312 0.167 0.250 0.475 0.559 4 NA 17 7
NFC West 16 11.0 11 5 0 0.688 0.500 0.667 0.534 0.504 2 5 19 25
NFC West 16 11.5 11 4 1 0.719 0.583 0.625 0.477 0.504 1 2 21 31
NFC West 16 7.5 7 8 1 0.469 0.750 0.542 0.496 0.539 3 NA 17 16