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(ggrepel)
library(nflfastR)
## Warning: package 'nflfastR' was built under R version 4.4.3
library(nflplotR)
## Warning: package 'nflplotR' was built under R version 4.4.3

grab pbp data

data <- load_pbp(2024)

Left Run Statistics:

left_run <- data %>% 
  filter(posteam == "LAC", rush == 1, down <= 4, play_type == "run") %>% 
  group_by(rusher) %>% 
  summarize(
    left_run_percentage = mean(run_location == "left", na.rm = TRUE) * 100,
    mean_epa = mean(ifelse(run_location == "left", epa, NA), na.rm = TRUE),
    success_rate = mean(ifelse(run_location == "left", success, NA), na.rm = TRUE),
    ypc = mean(ifelse(run_location == "left", yards_gained, NA), na.rm = TRUE),
    plays = sum(run_location == "left", na.rm = TRUE),
    long = max(ifelse(run_location == "left", yards_gained, NA), na.rm = TRUE)
  ) %>% 
  filter(plays >= 3) %>% 
  arrange(-mean_epa) %>% 
  mutate(across(where(is.numeric), round, 3))
## Warning: There were 3 warnings in `summarize()`.
## The first warning was:
## ℹ In argument: `long = max(ifelse(run_location == "left", yards_gained, NA),
##   na.rm = TRUE)`.
## ℹ In group 1: `rusher = "B.Bozeman"`.
## Caused by warning in `max()`:
## ! no non-missing arguments to max; returning -Inf
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 2 remaining warnings.
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `across(where(is.numeric), round, 3)`.
## Caused by warning:
## ! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
## Supply arguments directly to `.fns` through an anonymous function instead.
## 
##   # Previously
##   across(a:b, mean, na.rm = TRUE)
## 
##   # Now
##   across(a:b, \(x) mean(x, na.rm = TRUE))
left_run

Right run statistics:

right_run <- data %>% 
  filter(posteam == "LAC", rush == 1, down <= 4, play_type == "run") %>% 
  group_by(rusher) %>% 
  summarize(
    right_run_percentage = mean(run_location == "right", na.rm = TRUE) * 100,
    mean_epa = mean(ifelse(run_location == "right", epa, NA), na.rm = TRUE),
    success_rate = mean(ifelse(run_location == "right", success, NA), na.rm = TRUE),
    ypc = mean(ifelse(run_location == "right", yards_gained, NA), na.rm = TRUE),
    plays = sum(run_location == "right", na.rm = TRUE),
    long = max(ifelse(run_location == "right", yards_gained, NA), na.rm = TRUE)
  ) %>% 
  filter(plays >= 3) %>% 
  arrange(-mean_epa) %>% 
  mutate(across(where(is.numeric), round, 3))
## Warning: There were 2 warnings in `summarize()`.
## The first warning was:
## ℹ In argument: `long = max(ifelse(run_location == "right", yards_gained, NA),
##   na.rm = TRUE)`.
## ℹ In group 1: `rusher = "B.Bozeman"`.
## Caused by warning in `max()`:
## ! no non-missing arguments to max; returning -Inf
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 1 remaining warning.
right_run

Middle run statistics:

middle_run <- data %>% 
  filter(posteam == "LAC", rush == 1, down <= 4, play_type == "run") %>% 
  group_by(rusher) %>% 
  summarize(
    middle_run_percentage = mean(run_location == "middle", na.rm = TRUE) * 100,
    mean_epa = mean(ifelse(run_location == "middle", epa, NA), na.rm = TRUE),
    success_rate = mean(ifelse(run_location == "middle", success, NA), na.rm = TRUE),
    ypc = mean(ifelse(run_location == "middle", yards_gained, NA), na.rm = TRUE),
    plays = sum(run_location == "middle", na.rm = TRUE),
    long = max(ifelse(run_location == "middle", yards_gained, NA), na.rm = TRUE)
  ) %>% 
  filter(plays >= 3) %>% 
  arrange(-mean_epa) %>% 
  mutate(across(where(is.numeric), round, 3))
## Warning: There were 5 warnings in `summarize()`.
## The first warning was:
## ℹ In argument: `long = max(ifelse(run_location == "middle", yards_gained, NA),
##   na.rm = TRUE)`.
## ℹ In group 1: `rusher = "B.Bozeman"`.
## Caused by warning in `max()`:
## ! no non-missing arguments to max; returning -Inf
## ℹ Run `dplyr::last_dplyr_warnings()` to see the 4 remaining warnings.
middle_run