Import Libraries

library(readr)
library(gridtext)
library(magrittr)
library(nflplotR)
library(ggplot2)
library(nflreadr)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(readxl)
library(tidyverse)
## -- Attaching packages --------------------------------------- tidyverse 1.3.1 --
## v tibble  3.1.5     v stringr 1.4.0
## v tidyr   1.1.4     v forcats 0.5.1
## v purrr   0.3.4
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x tidyr::extract()   masks magrittr::extract()
## x dplyr::filter()    masks stats::filter()
## x dplyr::lag()       masks stats::lag()
## x purrr::set_names() masks magrittr::set_names()

Here we import the data from the Python dataframe

wk <- "Week 14"

python_data <- read_excel("C:\\Users\\onetr\\OneDrive\\Documents\\NFL Analysis.xlsx", wk)
teams_sorted <-python_data[order(python_data$Team),]

Begin loading NFL Plot R Data and match team nomenclature with NFL Plot R:

pbp <- nflreadr::load_pbp(2020) %>% 
  dplyr::filter(season_type == "REG") %>%
  dplyr::filter(!is.na(posteam) & (rush == 1 | pass == 1))

teams_nflplotR <- pbp %>%
  dplyr::group_by(team = posteam) %>%
  dplyr::summarise(off_epa = mean(epa, na.rm = TRUE)) %>%
  dplyr::select(-off_epa)

python_final <- teams_sorted %>%
  dplyr::mutate(Team = teams_nflplotR$team)

# Verify that python_final is correctly assigned and loaded
python_final$Team
##  [1] "ARI" "ATL" "BAL" "BUF" "CAR" "CHI" "CIN" "CLE" "DAL" "DEN" "DET" "GB" 
## [13] "HOU" "IND" "JAX" "KC"  "LA"  "LAC" "LV"  "MIA" "MIN" "NE"  "NO"  "NYG"
## [25] "NYJ" "PHI" "PIT" "SEA" "SF"  "TB"  "TEN" "WAS"

Graphing!

First, we compare 3rd Down Differential on the x-axis to Points-per-game (PPG) Differential.
3rd Down Differential = Offensive 3rd Down Conversion Rate - Opponent 3rd Down Conversion Rate for each team.
PPG Differential = Offensive PPG - Opponent PPG.

ggplot2::ggplot(python_final, aes(x = `3rd Down Differential`, y = `2021 PPG Differential`)) +
  ggplot2::geom_smooth(method = "lm", formula = y ~ x) +
  nflplotR::geom_mean_lines(aes(v_var = `3rd Down Differential` , h_var = `2021 PPG Differential`)) +
  nflplotR::geom_nfl_logos(aes(team_abbr = Team), width = 0.065, alpha = 0.6) +
  ggplot2::labs(
    x = "3rd Down Differential",
    y = "2021 PPG Differential",
    caption = "Data: @nflfastR, https://www.teamrankings.com/nfl/stat/",
    title = paste("2021 NFL 3rd Down Diff to PPG Diff through", wk)
  ) +
  ggplot2::theme_minimal() +
  ggplot2::theme(
    plot.title = ggplot2::element_text(face = "bold"),
    plot.title.position = "plot"
  )

Next, we look at 3rd Down Differential on the x-axis with Time of Possession on the y-axis.
3rd Down Differential = Offensive 3rd Down Conversion Rate - Opponent 3rd Down Conversion Rate for each team.

ggplot2::ggplot(python_final, aes(x = `3rd Down Differential`, y = `2021 ToP as Float`)) +
  ggplot2::geom_smooth(method = "lm", formula = y ~ x) +
  nflplotR::geom_mean_lines(aes(v_var = `3rd Down Differential` , h_var = `2021 ToP as Float`)) +
  nflplotR::geom_nfl_logos(aes(team_abbr = Team), width = 0.065, alpha = 0.6) +
  ggplot2::labs(
    x = "3rd Down Differential",
    y = "2021 ToP as Float",
    caption = "Data: @nflfastR, https://www.teamrankings.com/nfl/stat/",
    title = paste("2021 NFL 3rd Down Diff to Time of Possession through", wk)
  ) +
  ggplot2::theme_minimal() +
  ggplot2::theme(
    plot.title = ggplot2::element_text(face = "bold"),
    plot.title.position = "plot"
  )

Third, let’s look at the relationship between PPG Differential the x-axis and Time of Possession on the y-axis.
PPG Differential = Offensive PPG - Opponent PPG.

ggplot2::ggplot(python_final, aes(x = `2021 PPG Differential`, y = `2021 ToP as Float`)) +
  ggplot2::geom_smooth(method = "lm", formula = y ~ x) +
  nflplotR::geom_mean_lines(aes(v_var = `2021 PPG Differential` , h_var = `2021 ToP as Float`)) +
  nflplotR::geom_nfl_logos(aes(team_abbr = Team), width = 0.065, alpha = 0.6) +
  ggplot2::labs(
    x = "2021 PPG Differential",
    y = "2021 ToP as Float",
    caption = "Data: @nflfastR, https://www.teamrankings.com/nfl/stat/",
    title = paste("2021 NFL PPG Diff to Time of Possession through", wk)
  ) +
  ggplot2::theme_minimal() +
  ggplot2::theme(
    plot.title = ggplot2::element_text(face = "bold"),
    plot.title.position = "plot"
  )

Let’s take a look at the Offense now. We put 2021 Offense on the x-axis and 2021 PPG on the y-axis.

ggplot2::ggplot(python_final, aes(x = `2021 Offense`, y = `2021 PPG`)) +
  ggplot2::geom_smooth(method = "lm", formula = y ~ x) +
  nflplotR::geom_mean_lines(aes(v_var = `2021 Offense` , h_var = `2021 PPG`)) +
  nflplotR::geom_nfl_logos(aes(team_abbr = Team), width = 0.065, alpha = 0.6) +
  ggplot2::labs(
    x = "Offensive Third Down Conversion Rate",
    y = "Points-per-game",
    caption = "Data: @nflfastR, https://www.teamrankings.com/nfl/stat/",
    title = paste("2021 NFL Third Down Conversion to Points-per-game through", wk)
  ) +
  ggplot2::theme_minimal() +
  ggplot2::theme(
    plot.title = ggplot2::element_text(face = "bold"),
    plot.title.position = "plot"
  )

Now we will isolate the Defense. We put 2021 Defense on the x-axis and 2021 Opponent PPG on the y-axis.

ggplot2::ggplot(python_final, aes(x = `2021 Defense`, y = `2021 Opponent PPG`)) +
  ggplot2::geom_smooth(method = "lm", formula = y ~ x) +
  nflplotR::geom_mean_lines(aes(v_var = `2021 Defense` , h_var = `2021 Opponent PPG`)) +
  nflplotR::geom_nfl_logos(aes(team_abbr = Team), width = 0.065, alpha = 0.6) +
  ggplot2::labs(
    x = "Opponent Third Down Conversion Rate",
    y = "Opponent Points-per-game",
    caption = "Data: @nflfastR, https://www.teamrankings.com/nfl/stat/",
    title = paste("2021 NFL Opponent Third Down Conversion to Opponent Points-per-game through", wk)
  ) +
  ggplot2::theme_minimal() +
  ggplot2::theme(
    plot.title = ggplot2::element_text(face = "bold"),
    plot.title.position = "plot"
  )

How about Offensive Third Down Conversion with Time of Possession?
This would indicate how well teams do on 1st and 2nd down.

ggplot2::ggplot(python_final, aes(x = `2021 Offense`, y = `2021 ToP as Float`)) +
  ggplot2::geom_smooth(method = "lm", formula = y ~ x) +
  nflplotR::geom_mean_lines(aes(v_var = `2021 Offense` , h_var = `2021 ToP as Float`)) +
  nflplotR::geom_nfl_logos(aes(team_abbr = Team), width = 0.065, alpha = 0.6) +
  ggplot2::labs(
    x = "Offensive Third Down Conversion Rate",
    y = "2021 ToP as Float",
    caption = "Data: @nflfastR, https://www.teamrankings.com/nfl/stat/",
    title = paste("2021 NFL Third Down Conversion to Time of Possession through", wk)
  ) +
  ggplot2::theme_minimal() +
  ggplot2::theme(
    plot.title = ggplot2::element_text(face = "bold"),
    plot.title.position = "plot"
  )

Speaking of how well teams do on 1st and 2nd down, let’s evaluate Third Down Conversion rate against First Downs PG

ggplot2::ggplot(python_final, aes(x = `2021 Offense`, y = `2021 First Downs PG`)) +
  ggplot2::geom_smooth(method = "lm", formula = y ~ x) +
  nflplotR::geom_mean_lines(aes(v_var = `2021 Offense` , h_var = `2021 First Downs PG`)) +
  nflplotR::geom_nfl_logos(aes(team_abbr = Team), width = 0.065, alpha = 0.6) +
  ggplot2::labs(
    x = "Offensive Third Down Conversion Rate",
    y = "2021 First Downs PG",
    caption = "Data: @nflfastR, https://www.teamrankings.com/nfl/stat/",
    title = paste("2021 NFL Third Down Conversion to First Downs PG through", wk)
  ) +
  ggplot2::theme_minimal() +
  ggplot2::theme(
    plot.title = ggplot2::element_text(face = "bold"),
    plot.title.position = "plot"
  )