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 %>% utils::tail(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 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
2021_18_SEA_ARI 2021 REG 18 2022-01-09 Sunday 16:25 SEA 38 ARI 30 Home -8 68 0 2022010912 58771 10160000-0587-7113-a978-455fec3cda14 202201090crd 19876 401326597 7 7 190 -235 5.5 -110 -110 48.0 100 -120 1 closed grass NA NA 00-0029263 00-0035228 Russell Wilson Kyler Murray Pete Carroll Kliff Kingsbury NA PHO00 State Farm Stadium
2021_18_NO_ATL 2021 REG 18 2022-01-09 Sunday 16:25 NO 30 ATL 20 Home -10 50 0 2022010900 58759 10160000-0587-592f-94b1-30be78f17918 202201090atl 19864 401326585 7 7 -213 186 -4.5 -111 -100 40.0 102 -113 1 NA fieldturf NA NA 00-0033357 00-0026143 Taysom Hill Matt Ryan Sean Payton Arthur Smith NA ATL97 Mercedes-Benz Stadium
2021_18_NYJ_BUF 2021 REG 18 2022-01-09 Sunday 16:25 NYJ 10 BUF 27 Home 17 37 0 2022010902 58761 10160000-0587-6129-08e1-f057261766a8 202201090buf 19866 401326587 7 7 750 -1250 16.0 -110 -110 43.0 -110 -110 1 outdoors astroturf NA NA 00-0037013 00-0034857 Zach Wilson Josh Allen Robert Saleh Sean McDermott NA BUF00 New Era Field
2021_18_SF_LA 2021 REG 18 2022-01-09 Sunday 16:25 SF 27 LA 24 Home -3 51 1 2022010914 58773 10160000-0587-738e-2b05-95daf03cb563 202201090ram 19879 401326599 7 7 150 -170 3.0 -105 -115 46.5 -115 -105 1 dome matrixturf NA NA 00-0031345 00-0026498 Jimmy Garoppolo Matthew Stafford Kyle Shanahan Sean McVay NA LAX01 SoFi Stadium
2021_18_NE_MIA 2021 REG 18 2022-01-09 Sunday 16:25 NE 24 MIA 33 Home 9 57 0 2022010907 58766 10160000-0587-66a3-2df9-03ed8161cc2e 202201090mia 19871 401326592 7 7 -250 200 -6.0 -110 -110 41.0 -110 -110 1 outdoors grass NA NA 00-0036972 00-0036212 Mac Jones Tua Tagovailoa Bill Belichick Brian Flores NA MIA00 Hard Rock Stadium
2021_18_CAR_TB 2021 REG 18 2022-01-09 Sunday 16:25 CAR 17 TB 41 Home 24 58 0 2022010911 58770 10160000-0587-704e-6295-0c29cd0a1891 202201090tam 19874 401326596 7 7 375 -510 11.0 -110 -110 43.0 -105 -115 1 outdoors grass NA NA 00-0034869 00-0019596 Sam Darnold Tom Brady Matt Rhule Bruce Arians NA TAM00 Raymond James Stadium
2021_18_LAC_LV 2021 REG 18 2022-01-09 Sunday 20:20 LAC 32 LV 35 Home 3 67 1 2022010915 58774 10160000-0587-7450-0923-b0f39c686c28 202201090rai 19878 401326600 7 7 -180 155 -3.5 -110 -110 48.0 -110 -110 1 dome grass NA NA 00-0036355 00-0031280 Justin Herbert Derek Carr Brandon Staley Rich Bisaccia NA VEG00 Allegiant Stadium
2021_19_LV_CIN 2021 WC 19 2022-01-15 Saturday 16:30 LV 19 CIN 26 Home 7 45 0 2022011501 NA NA 202201150cin 21523 401326627 6 6 214 -248 6.0 -103 -109 48.5 -106 -105 0 outdoors grass NA NA 00-0031280 00-0036442 Derek Carr Joe Burrow Rich Bisaccia Zac Taylor NA CIN00 Paul Brown Stadium
2021_19_NE_BUF 2021 WC 19 2022-01-15 Saturday 20:15 NE 17 BUF 47 Home 30 64 0 2022011502 NA NA 202201150buf 21524 401326626 6 6 181 -207 4.5 -111 -100 43.0 -111 -101 1 outdoors astroturf NA NA 00-0036972 00-0034857 Mac Jones Josh Allen Bill Belichick Sean McDermott NA BUF00 New Era Field
2021_19_PHI_TB 2021 WC 19 2022-01-16 Sunday 13:00 PHI 15 TB 31 Home 16 46 0 2022011601 NA NA 202201160tam 21525 401326630 8 7 293 -352 7.5 -107 -104 45.5 100 -112 0 outdoors grass NA NA 00-0036389 00-0019596 Jalen Hurts Tom Brady Nick Sirianni Bruce Arians NA TAM00 Raymond James Stadium
2021_19_SF_DAL 2021 WC 19 2022-01-16 Sunday 16:30 SF 23 DAL 17 Home -6 40 0 2022011602 NA NA 202201160dal 21526 401326629 7 8 144 -162 3.0 100 -112 51.0 -111 100 0 closed fieldturf NA NA 00-0031345 00-0033077 Jimmy Garoppolo Dak Prescott Kyle Shanahan Mike McCarthy NA DAL00 AT&T Stadium
2021_19_PIT_KC 2021 WC 19 2022-01-16 Sunday 20:15 PIT 21 KC 42 Home 21 63 0 2022011603 NA NA 202201160kan 21527 401326628 7 8 522 -697 13.0 -124 111 46.0 -107 -104 0 outdoors astroturf NA NA 00-0022924 00-0033873 Ben Roethlisberger Patrick Mahomes Mike Tomlin Andy Reid NA KAN00 GEHA Field at Arrowhead Stadium
2021_19_ARI_LA 2021 WC 19 2022-01-17 Monday 20:15 ARI 11 LA 34 Home 23 45 0 2022011701 NA NA 202201170ram 21528 401326625 8 8 158 -179 4.0 -117 105 49.5 -103 -109 1 dome matrixturf NA NA 00-0035228 00-0026498 Kyler Murray Matthew Stafford Kliff Kingsbury Sean McVay NA LAX01 SoFi Stadium
2021_20_CIN_TEN 2021 DIV 20 2022-01-22 Saturday 16:30 CIN 19 TEN 16 Home -3 35 0 2022012201 NA NA 202201220oti 21529 401326632 7 13 170 -191 4.0 -109 -102 48.5 -102 -110 0 outdoors grass NA NA 00-0036442 00-0029701 Joe Burrow Ryan Tannehill Zac Taylor Mike Vrabel NA NAS00 Nissan Stadium
2021_20_SF_GB 2021 DIV 20 2022-01-22 Saturday 20:15 SF 13 GB 10 Home -3 23 0 2022012202 NA NA 202201220gnb 21530 401326631 6 13 228 -261 5.5 102 -114 47.0 -104 -107 0 outdoors grass NA NA 00-0031345 00-0023459 Jimmy Garoppolo Aaron Rodgers Kyle Shanahan Matt LaFleur NA GNB00 Lambeau Field
2021_20_LA_TB 2021 DIV 20 2022-01-23 Sunday 15:00 LA 30 TB 27 Home -3 57 0 2022012301 NA NA 202201230tam 21531 401326634 6 7 131 -145 2.5 108 -121 48.0 -102 -109 0 outdoors grass NA NA 00-0026498 00-0019596 Matthew Stafford Tom Brady Sean McVay Bruce Arians NA TAM00 Raymond James Stadium
2021_20_BUF_KC 2021 DIV 20 2022-01-23 Sunday 18:30 BUF 36 KC 42 Home 6 78 1 2022012302 NA NA 202201230kan 21532 401326633 8 7 124 -138 2.5 -101 -110 54.0 -105 -106 0 outdoors astroturf NA NA 00-0034857 00-0033873 Josh Allen Patrick Mahomes Sean McDermott Andy Reid NA KAN00 GEHA Field at Arrowhead Stadium
2021_21_CIN_KC 2021 CON 21 2022-01-30 Sunday 15:00 CIN 27 KC 24 Home -3 51 1 2022013001 NA NA 202201300kan 21534 401326635 8 7 250 -320 7.0 -105 -115 54.5 -110 -110 0 outdoors astroturf NA NA 00-0036442 00-0033873 Joe Burrow Patrick Mahomes Zac Taylor Andy Reid NA KAN00 GEHA Field at Arrowhead Stadium
2021_21_SF_LA 2021 CON 21 2022-01-30 Sunday 18:30 SF 17 LA 20 Home 3 37 0 2022013002 NA NA 202201300ram 21535 401326636 8 7 155 -180 3.5 -110 -110 45.5 -105 -115 1 dome matrixturf NA NA 00-0031345 00-0026498 Jimmy Garoppolo Matthew Stafford Kyle Shanahan Sean McVay NA LAX01 SoFi Stadium
2021_22_LA_CIN 2021 SB 22 2022-02-13 Sunday 18:30 LA 23 CIN 20 Neutral -3 43 0 2022021301 NA NA 202202130cin 21536 401326638 14 14 -190 160 -4.5 -110 -110 48.5 -110 -110 0 dome matrixturf NA NA 00-0026498 00-0036442 Matthew Stafford Joe Burrow Sean McVay Zac Taylor NA LAX01 SoFi Stadium

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)
#>  2022-03-28 11:58:22: Calculating team data
#>  2022-03-28 11:58:22: Calculating head to head
#>  2022-03-28 11:58:22: Calculating division rank #1
#>  2022-03-28 11:58:22: DIV (2): Head-to-head
#>  2022-03-28 11:58:22: DIV (2): Division Record
#>  2022-03-28 11:58:22: Calculating division rank #2
#>  2022-03-28 11:58:22: DIV (3): Head-to-head
#>  2022-03-28 11:58:23: DIV (3): Division Record
#>  2022-03-28 11:58:23: DIV (3): Common Record
#>  2022-03-28 11:58:23: DIV (2): Head-to-head
#>  2022-03-28 11:58:23: DIV (2): Division Record
#>  2022-03-28 11:58:23: DIV (2): Common Record
#>  2022-03-28 11:58:23: DIV (2): Conference Record
#>  2022-03-28 11:58:23: Calculating division rank #3
#>  2022-03-28 11:58:23: DIV (2): Head-to-head
#>  2022-03-28 11:58:23: DIV (2): Division Record
#>  2022-03-28 11:58:23: DIV (2): Common Record
#>  2022-03-28 11:58:23: Calculating division rank #4
dplyr::glimpse(div_standings)
#> List of 2
#>  $ standings: tibble [64 × 14] (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 ...
#>   ..$ 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 win_pct div_pct conf_pct sov sos div_rank
AFC East BUF 16 6.0 6 0.375 0.333 0.417 0.281 0.480 4
AFC East MIA 16 7.0 7 0.438 0.333 0.417 0.415 0.500 2
AFC East NE 16 12.0 12 0.750 1.000 0.917 0.466 0.496 1
AFC East NYJ 16 6.0 6 0.375 0.333 0.333 0.401 0.512 3
AFC North BAL 16 10.0 10 0.625 0.667 0.667 0.438 0.496 1
AFC North CIN 16 10.0 10 0.625 0.500 0.583 0.381 0.438 2
AFC North CLE 16 5.0 5 0.312 0.333 0.417 0.388 0.508 4
AFC North PIT 16 8.0 8 0.500 0.500 0.417 0.438 0.465 3
AFC South HOU 16 12.0 12 0.750 0.833 0.833 0.432 0.496 1
AFC South IND 16 11.0 11 0.688 0.667 0.667 0.403 0.441 2
AFC South JAX 16 2.0 2 0.125 0.333 0.167 0.531 0.539 4
AFC South TEN 16 6.0 6 0.375 0.167 0.417 0.344 0.512 3
AFC West DEN 16 13.0 13 0.812 1.000 0.833 0.385 0.457 1
AFC West KC 16 2.0 2 0.125 0.000 0.000 0.438 0.516 4
AFC West OAK 16 4.0 4 0.250 0.333 0.333 0.219 0.469 3
AFC West SD 16 7.0 7 0.438 0.667 0.583 0.286 0.457 2
NFC East DAL 16 8.0 8 0.500 0.500 0.417 0.422 0.523 3
NFC East NYG 16 9.0 9 0.562 0.500 0.667 0.490 0.521 2
NFC East PHI 16 4.0 4 0.250 0.167 0.167 0.484 0.508 4
NFC East WAS 16 10.0 10 0.625 0.833 0.667 0.450 0.494 1
NFC North CHI 16 10.0 10 0.625 0.500 0.583 0.403 0.512 3
NFC North DET 16 4.0 4 0.250 0.000 0.250 0.383 0.566 4
NFC North GB 16 11.0 11 0.688 0.833 0.667 0.440 0.508 1
NFC North MIN 16 10.0 10 0.625 0.667 0.583 0.456 0.520 2
NFC South ATL 16 13.0 13 0.812 0.500 0.750 0.418 0.422 1
NFC South CAR 16 7.0 7 0.438 0.500 0.417 0.464 0.516 2
NFC South NO 16 7.0 7 0.438 0.500 0.417 0.446 0.521 3
NFC South TB 16 7.0 7 0.438 0.500 0.333 0.446 0.502 4
NFC West ARI 16 5.0 5 0.312 0.167 0.250 0.475 0.559 4
NFC West SEA 16 11.0 11 0.688 0.500 0.667 0.534 0.504 2
NFC West SF 16 11.5 11 0.719 0.583 0.625 0.477 0.504 1
NFC West STL 16 7.5 7 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)
#>  2022-03-28 11:58:23: Calculating seed #1
#>  2022-03-28 11:58:23: CONF (3): Head-to-head Sweep
#>  2022-03-28 11:58:24: Calculating seed #2
#>  2022-03-28 11:58:24: CONF (2): Head-to-head Sweep
#>  2022-03-28 11:58:24: CONF (2): Conference Record
#>  2022-03-28 11:58:24: Calculating seed #3
#>  2022-03-28 11:58:24: Calculating seed #4
#>  2022-03-28 11:58:24: Calculating seed #5
#>  2022-03-28 11:58:24: Calculating seed #6
#>  2022-03-28 11:58:24: CONF (2): Best-in-division reduction
dplyr::glimpse(seeds)
#> List of 2
#>  $ standings: tibble [64 × 15] (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 ...
#>   ..$ 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 win_pct div_pct conf_pct sov sos div_rank seed
AFC East BUF 16 6.0 6 0.375 0.333 0.417 0.281 0.480 4 NA
AFC East MIA 16 7.0 7 0.438 0.333 0.417 0.415 0.500 2 NA
AFC East NE 16 12.0 12 0.750 1.000 0.917 0.466 0.496 1 2
AFC East NYJ 16 6.0 6 0.375 0.333 0.333 0.401 0.512 3 NA
AFC North BAL 16 10.0 10 0.625 0.667 0.667 0.438 0.496 1 4
AFC North CIN 16 10.0 10 0.625 0.500 0.583 0.381 0.438 2 6
AFC North CLE 16 5.0 5 0.312 0.333 0.417 0.388 0.508 4 NA
AFC North PIT 16 8.0 8 0.500 0.500 0.417 0.438 0.465 3 NA
AFC South HOU 16 12.0 12 0.750 0.833 0.833 0.432 0.496 1 3
AFC South IND 16 11.0 11 0.688 0.667 0.667 0.403 0.441 2 5
AFC South JAX 16 2.0 2 0.125 0.333 0.167 0.531 0.539 4 NA
AFC South TEN 16 6.0 6 0.375 0.167 0.417 0.344 0.512 3 NA
AFC West DEN 16 13.0 13 0.812 1.000 0.833 0.385 0.457 1 1
AFC West KC 16 2.0 2 0.125 0.000 0.000 0.438 0.516 4 NA
AFC West OAK 16 4.0 4 0.250 0.333 0.333 0.219 0.469 3 NA
AFC West SD 16 7.0 7 0.438 0.667 0.583 0.286 0.457 2 NA
NFC East DAL 16 8.0 8 0.500 0.500 0.417 0.422 0.523 3 NA
NFC East NYG 16 9.0 9 0.562 0.500 0.667 0.490 0.521 2 NA
NFC East PHI 16 4.0 4 0.250 0.167 0.167 0.484 0.508 4 NA
NFC East WAS 16 10.0 10 0.625 0.833 0.667 0.450 0.494 1 4
NFC North CHI 16 10.0 10 0.625 0.500 0.583 0.403 0.512 3 NA
NFC North DET 16 4.0 4 0.250 0.000 0.250 0.383 0.566 4 NA
NFC North GB 16 11.0 11 0.688 0.833 0.667 0.440 0.508 1 3
NFC North MIN 16 10.0 10 0.625 0.667 0.583 0.456 0.520 2 6
NFC South ATL 16 13.0 13 0.812 0.500 0.750 0.418 0.422 1 1
NFC South CAR 16 7.0 7 0.438 0.500 0.417 0.464 0.516 2 NA
NFC South NO 16 7.0 7 0.438 0.500 0.417 0.446 0.521 3 NA
NFC South TB 16 7.0 7 0.438 0.500 0.333 0.446 0.502 4 NA
NFC West ARI 16 5.0 5 0.312 0.167 0.250 0.475 0.559 4 NA
NFC West SEA 16 11.0 11 0.688 0.500 0.667 0.534 0.504 2 5
NFC West SF 16 11.5 11 0.719 0.583 0.625 0.477 0.504 1 2
NFC West STL 16 7.5 7 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)
#>  2022-03-28 11:58:25: Calculating draft order #32
#>  2022-03-28 11:58:25: Calculating draft order #31
#>  2022-03-28 11:58:25: Calculating draft order #30
#>  2022-03-28 11:58:25: Calculating draft order #29
#>  2022-03-28 11:58:25: Calculating draft order #28
#>  2022-03-28 11:58:25: Calculating draft order #27
#>  2022-03-28 11:58:25: Calculating draft order #26
#>  2022-03-28 11:58:25: Calculating draft order #25
#>  2022-03-28 11:58:25: Calculating draft order #24
#>  2022-03-28 11:58:25: Calculating draft order #23
#>  2022-03-28 11:58:25: Calculating draft order #22
#>  2022-03-28 11:58:25: Calculating draft order #21
#>  2022-03-28 11:58:25: Calculating draft order #20
#>  2022-03-28 11:58:25: Calculating draft order #19
#>  2022-03-28 11:58:25: Calculating draft order #18
#>  2022-03-28 11:58:25: Calculating draft order #17
#>  2022-03-28 11:58:25: Calculating draft order #16
#>  2022-03-28 11:58:25: Calculating draft order #15
#>  2022-03-28 11:58:25: Calculating draft order #14
#>  2022-03-28 11:58:25: Calculating draft order #13
#>  2022-03-28 11:58:25: Calculating draft order #12
#>  2022-03-28 11:58:25: Calculating draft order #11
#>  2022-03-28 11:58:26: Calculating draft order #10
#>  2022-03-28 11:58:26: DRAFT: Divisional Rank
#>  2022-03-28 11:58:26: DRAFT: Conference Rank
#>  2022-03-28 11:58:26: CONF (2): Best-in-division reduction
#>  2022-03-28 11:58:26: CONF (2): Head-to-head Sweep
#>  2022-03-28 11:58:26: Calculating draft order #9
#>  2022-03-28 11:58:26: Calculating draft order #8
#>  2022-03-28 11:58:26: Calculating draft order #7
#>  2022-03-28 11:58:26: Calculating draft order #6
#>  2022-03-28 11:58:26: Calculating draft order #5
#>  2022-03-28 11:58:26: Calculating draft order #4
#>  2022-03-28 11:58:26: Calculating draft order #3
#>  2022-03-28 11:58:26: Calculating draft order #2
#>  2022-03-28 11:58:26: Calculating draft order #1
dplyr::glimpse(draft)
#> Rows: 64
#> Columns: 16
#> $ 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…
#> $ 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 win_pct div_pct conf_pct sov sos div_rank seed exit draft_order
AFC East 16 6.0 6 0.375 0.333 0.417 0.281 0.480 4 NA 17 8
AFC East 16 7.0 7 0.438 0.333 0.417 0.415 0.500 2 NA 17 12
AFC East 16 12.0 12 0.750 1.000 0.917 0.466 0.496 1 2 20 29
AFC East 16 6.0 6 0.375 0.333 0.333 0.401 0.512 3 NA 17 9
AFC North 16 10.0 10 0.625 0.667 0.667 0.438 0.496 1 4 22 32
AFC North 16 10.0 10 0.625 0.500 0.583 0.381 0.438 2 6 18 21
AFC North 16 5.0 5 0.312 0.333 0.417 0.388 0.508 4 NA 17 6
AFC North 16 8.0 8 0.500 0.500 0.417 0.438 0.465 3 NA 17 17
AFC South 16 12.0 12 0.750 0.833 0.833 0.432 0.496 1 3 19 27
AFC South 16 11.0 11 0.688 0.667 0.667 0.403 0.441 2 5 18 24
AFC South 16 2.0 2 0.125 0.333 0.167 0.531 0.539 4 NA 17 2
AFC South 16 6.0 6 0.375 0.167 0.417 0.344 0.512 3 NA 17 10
AFC West 16 13.0 13 0.812 1.000 0.833 0.385 0.457 1 1 19 28
AFC West 16 2.0 2 0.125 0.000 0.000 0.438 0.516 4 NA 17 1
AFC West 16 4.0 4 0.250 0.333 0.333 0.219 0.469 3 NA 17 3
AFC West 16 7.0 7 0.438 0.667 0.583 0.286 0.457 2 NA 17 11
NFC East 16 8.0 8 0.500 0.500 0.417 0.422 0.523 3 NA 17 18
NFC East 16 9.0 9 0.562 0.500 0.667 0.490 0.521 2 NA 17 19
NFC East 16 4.0 4 0.250 0.167 0.167 0.484 0.508 4 NA 17 4
NFC East 16 10.0 10 0.625 0.833 0.667 0.450 0.494 1 4 18 22
NFC North 16 10.0 10 0.625 0.500 0.583 0.403 0.512 3 NA 17 20
NFC North 16 4.0 4 0.250 0.000 0.250 0.383 0.566 4 NA 17 5
NFC North 16 11.0 11 0.688 0.833 0.667 0.440 0.508 1 3 19 26
NFC North 16 10.0 10 0.625 0.667 0.583 0.456 0.520 2 6 18 23
NFC South 16 13.0 13 0.812 0.500 0.750 0.418 0.422 1 1 20 30
NFC South 16 7.0 7 0.438 0.500 0.417 0.464 0.516 2 NA 17 14
NFC South 16 7.0 7 0.438 0.500 0.417 0.446 0.521 3 NA 17 15
NFC South 16 7.0 7 0.438 0.500 0.333 0.446 0.502 4 NA 17 13
NFC West 16 5.0 5 0.312 0.167 0.250 0.475 0.559 4 NA 17 7
NFC West 16 11.0 11 0.688 0.500 0.667 0.534 0.504 2 5 19 25
NFC West 16 11.5 11 0.719 0.583 0.625 0.477 0.504 1 2 21 31
NFC West 16 7.5 7 0.469 0.750 0.542 0.496 0.539 3 NA 17 16