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 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
2022_18_CLE_PIT 2022 REG 18 2023-01-08 Sunday 13:00 CLE 14 PIT 28 Home 14 42 0 2023010810 NA NA 202301080pit NA 401437958 7 7 128 -142 2.5 -101 -109 40.0 -106 -106 1 outdoors grass 36 8 00-0033537 00-0038102 Deshaun Watson Kenny Pickett Kevin Stefanski Mike Tomlin Clete Blakeman PIT00 Acrisure Stadium
2022_18_LAC_DEN 2022 REG 18 2023-01-08 Sunday 16:25 LAC 28 DEN 31 Home 3 59 0 2023010812 NA NA 202301080den NA 401437960 7 7 222 -254 6.0 -104 -106 38.5 -103 -110 1 outdoors grass 43 4 00-0036355 00-0029263 Justin Herbert Russell Wilson Brandon Staley Jay Rosburg Shawn Hochuli DEN00 Empower Field at Mile High
2022_18_NYG_PHI 2022 REG 18 2023-01-08 Sunday 16:25 NYG 16 PHI 22 Home 6 38 0 2023010809 NA NA 202301080phi NA 401437957 7 7 858 -1252 16.5 -103 -107 42.5 -105 -107 1 outdoors grass 43 12 00-0033550 00-0036389 Davis Webb Jalen Hurts Brian Daboll Nick Sirianni Carl Cheffers PHI00 Lincoln Financial Field
2022_18_LA_SEA 2022 REG 18 2023-01-08 Sunday 16:25 LA 16 SEA 19 Home 3 35 1 2023010814 NA NA 202301080sea NA 401437963 7 7 198 -224 5.5 -112 102 41.5 -101 -111 1 outdoors fieldturf 45 4 00-0034855 00-0030565 Baker Mayfield Geno Smith Sean McVay Pete Carroll Craig Wrolstad SEA00 Lumen Field
2022_18_ARI_SF 2022 REG 18 2023-01-08 Sunday 16:25 ARI 13 SF 38 Home 25 51 0 2023010815 NA NA 202301080sfo NA 401437962 7 7 753 -1061 14.0 100 -111 40.0 -107 -105 1 outdoors grass 57 2 00-0035040 00-0037834 David Blough Brock Purdy Kliff Kingsbury Kyle Shanahan Adrian Hill SFO01 Levi’s Stadium
2022_18_DAL_WAS 2022 REG 18 2023-01-08 Sunday 16:25 DAL 6 WAS 26 Home 20 32 0 2023010811 NA NA 202301080was NA 401437959 10 7 -320 274 -7.5 -100 -110 40.5 -104 -108 1 outdoors grass 42 7 00-0033077 00-0037077 Dak Prescott Sam Howell Mike McCarthy Ron Rivera Tra Blake WAS00 FedExField
2022_18_DET_GB 2022 REG 18 2023-01-08 Sunday 20:20 DET 20 GB 16 Home -4 36 0 2023010804 NA NA 202301080gnb NA 401437952 7 7 237 -273 5.5 -110 -100 49.0 -113 101 1 outdoors grass 21 4 00-0033106 00-0023459 Jared Goff Aaron Rodgers Dan Campbell Matt LaFleur Brad Rogers GNB00 Lambeau Field
2022_19_SEA_SF 2022 WC 19 2023-01-14 Saturday 16:30 SEA 23 SF 41 Home 18 64 0 2023011400 NA NA 202301140sfo NA 401438000 6 6 367 -447 10.0 -123 112 42.0 -102 -110 1 outdoors grass 57 11 00-0030565 00-0037834 Geno Smith Brock Purdy Pete Carroll Kyle Shanahan Alex Kemp SFO01 Levi’s Stadium
2022_19_LAC_JAX 2022 WC 19 2023-01-14 Saturday 20:15 LAC 30 JAX 31 Home 1 61 0 2023011401 NA NA 202301140jax NA 401437998 6 7 -126 114 -2.0 -102 -108 46.5 -105 -107 0 outdoors grass 37 4 00-0036355 00-0036971 Justin Herbert Trevor Lawrence Brandon Staley Doug Pederson Shawn Smith JAX00 TIAA Bank Stadium
2022_19_MIA_BUF 2022 WC 19 2023-01-15 Sunday 13:00 MIA 31 BUF 34 Home 3 65 0 2023011500 NA NA 202301150buf NA 401438002 7 7 649 -882 14.0 -116 105 44.0 -105 -107 1 outdoors a_turf 27 4 00-0037327 00-0034857 Skylar Thompson Josh Allen Mike McDaniel Sean McDermott Brad Allen BUF00 New Era Field
2022_19_NYG_MIN 2022 WC 19 2023-01-15 Sunday 16:50 NYG 31 MIN 24 Home -7 55 0 2023011501 NA NA 202301150min NA 401438001 7 7 129 -142 2.5 103 -113 48.0 -104 -108 0 dome sportturf NA NA 00-0035710 00-0029604 Daniel Jones Kirk Cousins Brian Daboll Kevin O’Connell Adrian Hill MIN01 U.S. Bank Stadium
2022_19_BAL_CIN 2022 WC 19 2023-01-15 Sunday 20:15 BAL 17 CIN 24 Home 7 41 0 2023011502 NA NA 202301150cin NA 401437999 7 7 311 -370 7.5 -104 -106 40.0 -104 -108 1 outdoors fieldturf 30 4 00-0035993 00-0036442 Tyler Huntley Joe Burrow John Harbaugh Zac Taylor Clay Martin CIN00 Paycor Stadium
2022_19_DAL_TB 2022 WC 19 2023-01-16 Monday 20:15 DAL 31 TB 14 Home -17 45 0 2023011600 NA NA 202301160tam NA 401438003 8 8 -135 122 -2.5 -108 -103 45.5 -105 -107 0 outdoors grass 58 2 00-0033077 00-0019596 Dak Prescott Tom Brady Mike McCarthy Todd Bowles Craig Wrolstad TAM00 Raymond James Stadium
2022_20_JAX_KC 2022 DIV 20 2023-01-21 Saturday 16:30 JAX 20 KC 27 Home 7 47 0 2023012100 NA NA 202301210kan NA 401438005 7 14 377 -461 10.0 -119 108 52.5 -116 103 0 outdoors grass 36 6 00-0036971 00-0033873 Trevor Lawrence Patrick Mahomes Doug Pederson Andy Reid Shawn Hochuli KAN00 GEHA Field at Arrowhead Stadium
2022_20_NYG_PHI 2022 DIV 20 2023-01-21 Saturday 20:15 NYG 7 PHI 38 Home 31 45 0 2023012101 NA NA 202301210phi NA 401438004 6 13 304 -360 8.0 101 -111 48.0 -113 101 1 outdoors grass 40 6 00-0035710 00-0036389 Daniel Jones Jalen Hurts Brian Daboll Nick Sirianni Clete Blakeman PHI00 Lincoln Financial Field
2022_20_CIN_BUF 2022 DIV 20 2023-01-22 Sunday 15:00 CIN 27 BUF 10 Home -17 37 0 2023012200 NA NA 202301220buf NA 401438007 7 7 226 -259 6.0 -107 -103 48.5 -107 -105 0 outdoors a_turf 32 4 00-0036442 00-0034857 Joe Burrow Josh Allen Zac Taylor Sean McDermott Carl Cheffers BUF00 New Era Field
2022_20_DAL_SF 2022 DIV 20 2023-01-22 Sunday 18:30 DAL 12 SF 19 Home 7 31 0 2023012201 NA NA 202301220sfo NA 401438006 6 8 164 -183 3.5 -107 -103 46.5 -105 -107 0 outdoors grass 55 19 00-0033077 00-0037834 Dak Prescott Brock Purdy Mike McCarthy Kyle Shanahan Bill Vinovich SFO01 Levi’s Stadium
2022_21_SF_PHI 2022 CON 21 2023-01-29 Sunday 15:00 SF 7 PHI 31 Home 24 38 0 2023012900 NA NA 202301290phi NA 401438009 7 8 133 -147 2.5 105 -116 45.0 -114 101 0 outdoors grass 52 14 00-0037834 00-0036389 Brock Purdy Jalen Hurts Kyle Shanahan Nick Sirianni John Hussey PHI00 Lincoln Financial Field
2022_21_CIN_KC 2022 CON 21 2023-01-29 Sunday 18:30 CIN 20 KC 23 Home 3 43 0 2023012901 NA NA 202301290kan NA 401438008 7 8 119 -131 2.0 -103 -107 48.5 -106 -106 0 outdoors grass 22 13 00-0036442 00-0033873 Joe Burrow Patrick Mahomes Zac Taylor Andy Reid Ron Torbert KAN00 GEHA Field at Arrowhead Stadium
2022_22_KC_PHI 2022 SB 22 2023-02-12 Sunday 18:30 KC 38 PHI 35 Neutral -3 73 0 2023021200 NA NA 202302120phi NA 401438030 14 14 104 -115 1.0 -103 -107 51.0 -104 -108 0 closed grass NA NA 00-0033873 00-0036389 Patrick Mahomes Jalen Hurts Andy Reid Nick Sirianni Carl Cheffers PHO00 State Farm 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)
#>  13:10:57 | Calculating team data
#>  13:10:57 | Calculating head to head
#>  13:10:57 | Calculating division rank #1
#>  13:10:57 | DIV (2): Head-to-head
#>  13:10:58 | DIV (2): Division Record
#>  13:10:58 | Calculating division rank #2
#>  13:10:58 | DIV (3): Head-to-head
#>  13:10:58 | DIV (3): Division Record
#>  13:10:58 | DIV (3): Common Record
#>  13:10:58 | DIV (2): Head-to-head
#>  13:10:59 | DIV (2): Division Record
#>  13:10:59 | DIV (2): Common Record
#>  13:10:59 | DIV (2): Conference Record
#>  13:10:59 | Calculating division rank #3
#>  13:10:59 | DIV (2): Head-to-head
#>  13:10:59 | DIV (2): Division Record
#>  13:10:59 | DIV (2): Common Record
#>  13:11:00 | 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)
#>  13:11:00 | Calculating seed #1
#>  13:11:00 | CONF (3): Head-to-head Sweep
#>  13:11:00 | Calculating seed #2
#>  13:11:00 | CONF (2): Head-to-head Sweep
#>  13:11:01 | CONF (2): Conference Record
#>  13:11:01 | Calculating seed #3
#>  13:11:01 | Calculating seed #4
#>  13:11:01 | Calculating seed #5
#>  13:11:01 | Calculating seed #6
#>  13:11:01 | 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)
#>  13:11:02 | Calculating draft order #32
#>  13:11:02 | Calculating draft order #31
#>  13:11:02 | Calculating draft order #30
#>  13:11:02 | Calculating draft order #29
#>  13:11:02 | Calculating draft order #28
#>  13:11:02 | Calculating draft order #27
#>  13:11:02 | Calculating draft order #26
#>  13:11:02 | Calculating draft order #25
#>  13:11:02 | Calculating draft order #24
#>  13:11:02 | Calculating draft order #23
#>  13:11:02 | Calculating draft order #22
#>  13:11:02 | Calculating draft order #21
#>  13:11:02 | Calculating draft order #20
#>  13:11:02 | Calculating draft order #19
#>  13:11:02 | Calculating draft order #18
#>  13:11:02 | Calculating draft order #17
#>  13:11:03 | Calculating draft order #16
#>  13:11:03 | Calculating draft order #15
#>  13:11:03 | Calculating draft order #14
#>  13:11:03 | Calculating draft order #13
#>  13:11:03 | Calculating draft order #12
#>  13:11:03 | Calculating draft order #11
#>  13:11:03 | Calculating draft order #10
#>  13:11:03 | DRAFT: Divisional Rank
#>  13:11:03 | DRAFT: Conference Rank
#>  13:11:03 | CONF (2): Best-in-division reduction
#>  13:11:03 | CONF (2): Head-to-head Sweep
#>  13:11:03 | Calculating draft order #9
#>  13:11:03 | Calculating draft order #8
#>  13:11:03 | Calculating draft order #7
#>  13:11:03 | Calculating draft order #6
#>  13:11:03 | Calculating draft order #5
#>  13:11:03 | Calculating draft order #4
#>  13:11:03 | Calculating draft order #3
#>  13:11:04 | Calculating draft order #2
#>  13:11:04 | 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