| Title: | Optimal Fourth Down Decisions in College Football |
|---|---|
| Description: | Estimate the outcomes of fourth down plays in National Collegiate Athletic Association (NCAA) football and compare the win probability of going for it, attempting a field goal and punting. Each option is scored with expected points, field goal, fourth down conversion and win probability models fitted on 'cfbfastR' play-by-play data, following the approach of 'nfl4th' for the National Football League. Fourth down plays from a single game can be pulled from 'ESPN' and prepared for scoring, and whole seasons of 'cfbfastR' play-by-play can be loaded with the decision columns added. |
| Authors: | Jared Lee [aut, cph], Ben Baldwin [aut], Sebastian Carl [ctb], Saiem Gilani [aut, cre] (ORCID: <https://orcid.org/0000-0002-7194-9067>) |
| Maintainer: | Saiem Gilani <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.2.0 |
| Built: | 2026-10-18 14:48:26 UTC |
| Source: | https://github.com/sportsdataverse/cfb4th |
Get various probabilities associated with each option on 4th downs (go for it, kick field goal, punt).
add_4th_probs(df)add_4th_probs(df)
df |
A data frame of decisions to be computed for. |
The input data frame with the following columns added:
Gain (or loss) in win prob associated with choosing to go for it (percentage points).
Probability of earning a first down if going for it on 4th down.
Win probability in the event of a failed 4th down attempt.
Win probability in the event of a successful 4th down attempt.
Average win probability when going for it on 4th down.
Probability of making field goal.
Win probability in the event of a missed field goal.
Win probability in the event of a made field goal.
Average win probability when attempting field goal.
Average win probability when punting.
play <- tibble::tibble( # Game Info home = "Utah", away = "BYU", pos_team = "Utah", def_pos_team = "BYU", spread = -7, over_under = 55, # Situation Info half = 2, period = 3, # Quarter TimeSecsRem = 900, # Half Seconds Remaining adj_TimeSecsRem = 900, # Game Seconds Remaining down = 4, distance = 4, yards_to_goal = 40, pos_score_diff_start = 7, pos_team_receives_2H_kickoff = 1, pos_team_timeouts_rem_before = 3, def_pos_team_timeouts_rem_before = 3 ) # the fourth-down and win-probability models are downloaded the first time # they are needed; try() keeps the example from failing without network try(cfb4th::add_4th_probs(play))play <- tibble::tibble( # Game Info home = "Utah", away = "BYU", pos_team = "Utah", def_pos_team = "BYU", spread = -7, over_under = 55, # Situation Info half = 2, period = 3, # Quarter TimeSecsRem = 900, # Half Seconds Remaining adj_TimeSecsRem = 900, # Game Seconds Remaining down = 4, distance = 4, yards_to_goal = 40, pos_score_diff_start = 7, pos_team_receives_2H_kickoff = 1, pos_team_timeouts_rem_before = 3, def_pos_team_timeouts_rem_before = 3 ) # the fourth-down and win-probability models are downloaded the first time # they are needed; try() keeps the example from failing without network try(cfb4th::add_4th_probs(play))
The fourth-down conversion and win-probability models are downloaded the
first time they are needed and cached under
tools::R_user_dir("cfb4th", "cache"). Clear the cache to force a fresh
download, for example after a model update.
cfb4th_clear_cache(type = c("all", "fd_model", "wp_model"))cfb4th_clear_cache(type = c("all", "fd_model", "wp_model"))
type |
One of |
Returns TRUE invisibly once the cache has been cleared.
cfb4th_clear_cache()cfb4th_clear_cache()
Get 4th down plays from a game.
get_4th_plays(df)get_4th_plays(df)
df |
A data frame of a game to get 4th down decisions of. |
Obtains a data frame that can be used with add_4th_probs(). The following columns
must be present:
game_id : ESPN game ID from ESPN or cfbfastR (e.g. '401114223')
home_team : Name of the home team
away_team : Name of the away team
A data frame of the game's fourth down plays, one row per play (the input data frame is only used to identify the game), with the columns:
Play description from ESPN.
Play type text from ESPN.
Index number of play from a given game. Useful for tracking plays (e.g. for 4th down bot).
All the columns needed for add_4th_probs().
## Not run: game <- cfbfastR::cfbd_game_info(2019, team = "Utah", week = 3) plays <- cfb4th::get_4th_plays(game) dplyr::glimpse(plays) ## End(Not run)## Not run: game <- cfbfastR::cfbd_game_info(2019, team = "Utah", week = 3) plays <- cfb4th::get_4th_plays(game) dplyr::glimpse(plays) ## End(Not run)
cfbfastR dataLoad calculated 4th down probabilities from cfbfastR data.
load_4th_pbp(seasons)load_4th_pbp(seasons)
seasons |
Seasons to load. Must be 2014 and later. |
cfbfastR data on 4th downs with the add_4th_probs() columns added and also the following:
100 if a team went for it on 4th down, 0 otherwise. It's 100 and 0 as a convenience for obtaining percent of times going for it.
## Not run: cfb4th::load_4th_pbp(2020) ## End(Not run)## Not run: cfb4th::load_4th_pbp(2020) ## End(Not run)
Get a table with the probabilities on 4th down.
make_table_data(df)make_table_data(df)
df |
A data frame consisting of one play that has had |
A table showing the probabilities associated with each possible choice.
play <- tibble::tibble( # Game Info home = "Utah", away = "BYU", pos_team = "Utah", def_pos_team = "BYU", spread = -7, over_under = 55, # Situation Info half = 2, period = 3, # Quarter TimeSecsRem = 900, # Half Seconds Remaining adj_TimeSecsRem = 900, # Game Seconds Remaining down = 4, distance = 4, yards_to_goal = 40, pos_score_diff_start = 7, pos_team_receives_2H_kickoff = 1, pos_team_timeouts_rem_before = 3, def_pos_team_timeouts_rem_before = 3 ) # the fourth-down and win-probability models are downloaded the first time # they are needed; try() keeps the example from failing without network try({ probs <- cfb4th::add_4th_probs(play) cfb4th::make_table_data(probs) })play <- tibble::tibble( # Game Info home = "Utah", away = "BYU", pos_team = "Utah", def_pos_team = "BYU", spread = -7, over_under = 55, # Situation Info half = 2, period = 3, # Quarter TimeSecsRem = 900, # Half Seconds Remaining adj_TimeSecsRem = 900, # Game Seconds Remaining down = 4, distance = 4, yards_to_goal = 40, pos_score_diff_start = 7, pos_team_receives_2H_kickoff = 1, pos_team_timeouts_rem_before = 3, def_pos_team_timeouts_rem_before = 3 ) # the fourth-down and win-probability models are downloaded the first time # they are needed; try() keeps the example from failing without network try({ probs <- cfb4th::add_4th_probs(play) cfb4th::make_table_data(probs) })