Load Packages
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.4.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.5.1
## ✔ ggplot2 3.5.1 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(nflfastR)
## Warning: package 'nflfastR' was built under R version 4.4.3
library(formattable)
## Warning: package 'formattable' was built under R version 4.4.3
library(circlize)
## Warning: package 'circlize' was built under R version 4.4.3
## ========================================
## circlize version 0.4.16
## CRAN page: https://cran.r-project.org/package=circlize
## Github page: https://github.com/jokergoo/circlize
## Documentation: https://jokergoo.github.io/circlize_book/book/
##
## If you use it in published research, please cite:
## Gu, Z. circlize implements and enhances circular visualization
## in R. Bioinformatics 2014.
##
## This message can be suppressed by:
## suppressPackageStartupMessages(library(circlize))
## ========================================
library(DT)
## Warning: package 'DT' was built under R version 4.4.3
Load Play-By-Play
pbp <- load_pbp(2025)
get_team_data <- function(team_input, pbp) {
# Get offensive rush epa
off_rush <- pbp %>%
filter(posteam == team_input, rush == 1) %>%
group_by(posteam) %>%
summarize(o_r_epa = round(mean(epa, na.rm = TRUE), 3)) %>%
rename(team = posteam)
# Get offensive pass epa
off_pass <- pbp %>%
filter(posteam == team_input, pass == 1) %>%
group_by(posteam) %>%
summarize(o_p_epa = round(mean(epa, na.rm = TRUE), 3)) %>%
select(o_p_epa)
# Get defensive rush epa
def_rush <- pbp %>%
filter(defteam == team_input, rush == 1) %>%
group_by(defteam) %>%
summarize(d_r_epa = round(mean(epa, na.rm = TRUE), 3)) %>%
select(d_r_epa)
# Get defensive pass epa
def_pass <- pbp %>%
filter(defteam == team_input, pass == 1) %>%
group_by(defteam) %>%
summarize(d_p_epa = round(mean(epa, na.rm = TRUE), 3)) %>%
select(d_p_epa)
result <- cbind(off_rush, off_pass, def_rush, def_pass)
return(result)
}
teams <- unique(na.omit(pbp$posteam))
team_results <- tibble()
for (i in teams) {
team_results <- bind_rows(team_results, get_team_data(i, pbp))
}
ranks <- team_results %>%
arrange(-o_r_epa) %>%
mutate(o_r_rank = row_number()) %>%
arrange(-o_p_epa) %>%
mutate(o_p_rank = row_number()) %>%
arrange(d_r_epa) %>%
mutate(d_r_rank = row_number()) %>%
arrange(d_p_epa) %>%
mutate(d_p_rank = row_number(),
avg_rank = round((o_r_rank+o_p_rank+d_r_rank+d_p_rank) / 4, 1)) %>%
arrange(avg_rank)
datatable(ranks)
pbp2024 <- load_pbp(2024)
teams <- unique(na.omit(pbp$posteam))
team_results_2024 <- tibble()
for (i in teams) {
team_results_2024 <- bind_rows(team_results_2024, get_team_data(i, pbp2024))
}
ranks_2024 <- team_results_2024 %>%
arrange(-o_r_epa) %>%
mutate(o_r_rank = row_number()) %>%
arrange(-o_p_epa) %>%
mutate(o_p_rank = row_number()) %>%
arrange(d_r_epa) %>%
mutate(d_r_rank = row_number()) %>%
arrange(d_p_epa) %>%
mutate(d_p_rank = row_number(),
avg_rank = round((o_r_rank+o_p_rank+d_r_rank+d_p_rank) / 4, 1)) %>%
arrange(avg_rank)
datatable(ranks_2024)