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 tie-breaking procedures. The NFL’s official procedures for breaking ties for postseason playoffs may be found here, and this site explains the assignment of draft pick order.

nflseedR does not support all levels of tie-breakers at the moment. The deepest tie-breaker currently is strength of schedule. After that, the decision is made at random. However, the need for additional levels is extremely unlikely in practice and deeper levels have never actually been needed to resolve season-end standings since the NFL expanded to 32 teams.

Using In-Simulation Functions

You can get NFL game data from this function:

If preferred, one can obtain 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
2024_17_ATL_WAS 2024 REG 17 2024-12-29 Sunday 13:00 ATL NA WAS NA Home NA NA NA 2024122904 59755 NA 202412290was NA 401671842 6696 7 7 NA NA NA NA NA NA NA NA 0 outdoors grass NA NA NA NA NA NA Raheem Morris Dan Quinn NA WAS00 FedExField
2024_17_DAL_PHI 2024 REG 17 2024-12-29 Sunday 16:25 DAL NA PHI NA Home NA NA NA 2024122910 59761 NA 202412290phi NA 401671765 6702 7 7 NA NA NA NA NA NA NA NA 1 outdoors grass NA NA NA NA NA NA Mike McCarthy Nick Sirianni NA PHI00 Lincoln Financial Field
2024_17_MIA_CLE 2024 REG 17 2024-12-29 Sunday 20:20 MIA NA CLE NA Home NA NA NA 2024122911 59762 NA 202412290cle NA 401671877 6703 7 10 NA NA NA NA NA NA NA NA 0 outdoors grass NA NA NA NA NA NA Mike McDaniel Kevin Stefanski NA CLE00 FirstEnergy Stadium
2024_17_DET_SF 2024 REG 17 2024-12-30 Monday 20:15 DET NA SF NA Home NA NA NA 2024123000 59763 NA 202412300sfo NA 401671698 6704 8 8 NA NA NA NA NA NA NA NA 0 outdoors grass NA NA NA NA NA NA Dan Campbell Kyle Shanahan NA SFO01 Levi’s Stadium
2024_18_SF_ARI 2024 REG 18 2025-01-05 Sunday 13:00 SF NA ARI NA Home NA NA NA 2025010500 59764 NA 202501050crd NA 401671845 6705 6 7 NA NA NA NA NA NA NA NA 1 closed grass NA NA NA NA NA NA Kyle Shanahan Jonathan Gannon NA PHO00 State Farm Stadium
2024_18_CAR_ATL 2024 REG 18 2025-01-05 Sunday 13:00 CAR NA ATL NA Home NA NA NA 2025010501 59765 NA 202501050atl NA 401671827 6706 7 7 NA NA NA NA NA NA NA NA 1 closed fieldturf NA NA NA NA NA NA Dave Canales Raheem Morris NA ATL97 Mercedes-Benz Stadium
2024_18_CLE_BAL 2024 REG 18 2025-01-05 Sunday 13:00 CLE NA BAL NA Home NA NA NA 2025010502 59766 NA 202501050rav NA 401671834 6707 7 11 NA NA NA NA NA NA NA NA 1 outdoors grass NA NA NA NA NA NA Kevin Stefanski John Harbaugh NA BAL00 M&T Bank Stadium
2024_18_WAS_DAL 2024 REG 18 2025-01-05 Sunday 13:00 WAS NA DAL NA Home NA NA NA 2025010503 59767 NA 202501050dal NA 401671840 6708 7 7 NA NA NA NA NA NA NA NA 1 closed matrixturf NA NA NA NA NA NA Dan Quinn Mike McCarthy NA DAL00 AT&T Stadium
2024_18_KC_DEN 2024 REG 18 2025-01-05 Sunday 13:00 KC NA DEN NA Home NA NA NA 2025010504 59768 NA 202501050den NA 401671838 6709 11 7 NA NA NA NA NA NA NA NA 1 outdoors grass NA NA NA NA NA NA Andy Reid Sean Payton NA DEN00 Empower Field at Mile High
2024_18_MIN_DET 2024 REG 18 2025-01-05 Sunday 13:00 MIN NA DET NA Home NA NA NA 2025010505 59769 NA 202501050det NA 401671843 6710 7 6 NA NA NA NA NA NA NA NA 1 dome fieldturf NA NA NA NA NA NA Kevin O’Connell Dan Campbell NA DET00 Ford Field
2024_18_CHI_GB 2024 REG 18 2025-01-05 Sunday 13:00 CHI NA GB NA Home NA NA NA 2025010506 59770 NA 202501050gnb NA 401671844 6711 10 7 NA NA NA NA NA NA NA NA 1 outdoors grass NA NA NA NA NA NA Matt Eberflus Matt LaFleur NA GNB00 Lambeau Field
2024_18_JAX_IND 2024 REG 18 2025-01-05 Sunday 13:00 JAX NA IND NA Home NA NA NA 2025010507 59771 NA 202501050clt NA 401671837 6712 7 7 NA NA NA NA NA NA NA NA 1 closed fieldturf NA NA NA NA NA NA Doug Pederson Shane Steichen NA IND00 Lucas Oil Stadium
2024_18_SEA_LA 2024 REG 18 2025-01-05 Sunday 13:00 SEA NA LA NA Home NA NA NA 2025010508 59772 NA 202501050ram NA 401671830 6713 10 7 NA NA NA NA NA NA NA NA 1 dome matrixturf NA NA NA NA NA NA Mike Macdonald Sean McVay NA LAX01 SoFi Stadium
2024_18_LAC_LV 2024 REG 18 2025-01-05 Sunday 13:00 LAC NA LV NA Home NA NA NA 2025010509 59773 NA 202501050rai NA 401671839 6714 7 7 NA NA NA NA NA NA NA NA 1 dome grass NA NA NA NA NA NA Jim Harbaugh Antonio Pierce NA VEG00 Allegiant Stadium
2024_18_BUF_NE 2024 REG 18 2025-01-05 Sunday 13:00 BUF NA NE NA Home NA NA NA 2025010510 59774 NA 202501050nwe NA 401671831 6715 7 7 NA NA NA NA NA NA NA NA 1 outdoors fieldturf NA NA NA NA NA NA Sean McDermott Jerod Mayo NA BOS00 Gillette Stadium
2024_18_MIA_NYJ 2024 REG 18 2025-01-05 Sunday 13:00 MIA NA NYJ NA Home NA NA NA 2025010511 59775 NA 202501050nyj NA 401671833 6716 7 7 NA NA NA NA NA NA NA NA 1 outdoors fieldturf NA NA NA NA NA NA Mike McDaniel Robert Saleh NA NYC01 MetLife Stadium
2024_18_NYG_PHI 2024 REG 18 2025-01-05 Sunday 13:00 NYG NA PHI NA Home NA NA NA 2025010512 59776 NA 202501050phi NA 401671841 6717 7 7 NA NA NA NA NA NA NA NA 1 outdoors grass NA NA NA NA NA NA Brian Daboll Nick Sirianni NA PHI00 Lincoln Financial Field
2024_18_CIN_PIT 2024 REG 18 2025-01-05 Sunday 13:00 CIN NA PIT NA Home NA NA NA 2025010513 59777 NA 202501050pit NA 401671836 6718 7 11 NA NA NA NA NA NA NA NA 1 outdoors grass NA NA NA NA NA NA Zac Taylor Mike Tomlin NA PIT00 Acrisure Stadium
2024_18_NO_TB 2024 REG 18 2025-01-05 Sunday 13:00 NO NA TB NA Home NA NA NA 2025010514 59778 NA 202501050tam NA 401671828 6719 7 7 NA NA NA NA NA NA NA NA 1 outdoors grass NA NA NA NA NA NA Dennis Allen Todd Bowles NA TAM00 Raymond James Stadium
2024_18_HOU_TEN 2024 REG 18 2025-01-05 Sunday 13:00 HOU NA TEN NA Home NA NA NA 2025010515 59779 NA 202501050oti NA 401671826 6720 11 7 NA NA NA NA NA NA NA NA 1 outdoors grass NA NA NA NA NA NA DeMeco Ryans Brian Callahan NA NAS00 Nissan 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 function 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)
#>  11:48:17 | Calculating team data
#>  11:48:17 | Calculating head to head
#>  11:48:17 | Calculating division rank #1
#>  11:48:17 | DIV (2): Head-to-head
#>  11:48:17 | DIV (2): Division Record
#>  11:48:17 | Calculating division rank #2
#>  11:48:17 | DIV (3): Head-to-head
#>  11:48:17 | DIV (3): Division Record
#>  11:48:17 | DIV (3): Common Record
#>  11:48:17 | DIV (2): Head-to-head
#>  11:48:17 | DIV (2): Division Record
#>  11:48:17 | DIV (2): Common Record
#>  11:48:17 | DIV (2): Conference Record
#>  11:48:17 | Calculating division rank #3
#>  11:48:17 | DIV (2): Head-to-head
#>  11:48:17 | DIV (2): Division Record
#>  11:48:17 | DIV (2): Common Record
#>  11:48:17 | 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, and 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().

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 second-place finish in 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 forward with a 2-way head-to-head comparison.

Find Conference Seedings

This function computes conference seedings based on the above computed division standings data frame. For efficiency, reasons the h2h data frame computed above 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. For example (please note the number of playoff seeds):

seeds <- div_standings %>% 
  nflseedR::compute_conference_seeds(h2h = .$h2h, playoff_seeds = 6, .debug = TRUE)
#>  11:48:17 | Calculating seed #1
#>  11:48:17 | CONF (3): Head-to-head Sweep
#>  11:48:17 | Calculating seed #2
#>  11:48:17 | CONF (2): Head-to-head Sweep
#>  11:48:17 | CONF (2): Conference Record
#>  11:48:17 | Calculating seed #3
#>  11:48:17 | Calculating seed #4
#>  11:48:17 | Calculating seed #5
#>  11:48:17 | Calculating seed #6
#>  11:48:17 | 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 playoff outcomes 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 h2h data frame computed above 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)
#>  11:48:18 | Calculating draft order #32
#>  11:48:18 | Calculating draft order #31
#>  11:48:18 | Calculating draft order #30
#>  11:48:18 | Calculating draft order #29
#>  11:48:18 | Calculating draft order #28
#>  11:48:18 | Calculating draft order #27
#>  11:48:18 | Calculating draft order #26
#>  11:48:18 | Calculating draft order #25
#>  11:48:18 | Calculating draft order #24
#>  11:48:18 | Calculating draft order #23
#>  11:48:18 | Calculating draft order #22
#>  11:48:18 | Calculating draft order #21
#>  11:48:18 | Calculating draft order #20
#>  11:48:18 | Calculating draft order #19
#>  11:48:18 | Calculating draft order #18
#>  11:48:18 | Calculating draft order #17
#>  11:48:18 | Calculating draft order #16
#>  11:48:18 | Calculating draft order #15
#>  11:48:18 | Calculating draft order #14
#>  11:48:18 | Calculating draft order #13
#>  11:48:18 | Calculating draft order #12
#>  11:48:18 | Calculating draft order #11
#>  11:48:18 | Calculating draft order #10
#>  11:48:18 | DRAFT: Divisional Rank
#>  11:48:18 | DRAFT: Conference Rank
#>  11:48:18 | CONF (2): Best-in-division reduction
#>  11:48:18 | CONF (2): Head-to-head Sweep
#>  11:48:18 | Calculating draft order #9
#>  11:48:18 | Calculating draft order #8
#>  11:48:18 | Calculating draft order #7
#>  11:48:18 | Calculating draft order #6
#>  11:48:18 | Calculating draft order #5
#>  11:48:18 | Calculating draft order #4
#>  11:48:18 | Calculating draft order #3
#>  11:48:18 | Calculating draft order #2
#>  11:48:18 | 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