Get started with nflseedR
Sebastian Carl and Lee Sharpe
Source:vignettes/articles/nflseedR.Rmd
nflseedR.Rmd
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:
-
load_sharpe_games()
to collect game information and results
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):
-
compute_division_ranks()
to find all division winners, -
compute_conference_seeds()
to get the playoff participants, and -
compute_draft_order()
to find the resulting draft pick for each team.
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
):
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):
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 |