Skip to content

[BUG] Bad Kickoff EP Calibration for all non-standard kickoffs #570

Description

@TheMathNinja

Is there an existing issue for this?

  • I have searched the existing issues

Have you installed the latest development version of the package(s) in question?

  • I have installed the latest development version of the package.

If this is a data issue, have you tried clearing your nflverse cache?

I have cleared my nflverse cache and the issue persists.

What version of the package do you have?

[1] ‘5.2.0.9003’

Describe the bug

Ok I know I haven't installed the lastest nflfastR (I have to fix some of my code first so it doesn't break). But this is an issue regardless, I'm 98% sure.

The current EP calculation seems not to account for various yardlines for the kickoff event, such that kickoffs from the 20 yardline and 40 yardline share very similar EP, and therefore result in strongly non-zero EPA's in aggregate. This is especially important because it affects all of EP/EPA scoring because prob(safety) is included throughout EP/EPA calculation, and safeties result in a kickoff from the 20. Getting EP on this play right also effects EPA on all safeties (and therefore all plays).

I got this result:

# A tibble: 4 × 4
  yardline_100     n mean_ep mean_epa
         <dbl> <int>   <dbl>    <dbl>
1           20    66    1.04   0.484 
2           35  8424    1.09  -0.0086
3           40    37    1.11  -0.214 
4           50    50    1.04  -0.307 

Reprex

kickoff_epa_by_yardline <- nflreadr::load_pbp(seasons = 2015:2023) %>%
  dplyr::filter(
    kickoff_attempt == 1,
    play_type == "kickoff"
  ) %>%
  dplyr::group_by(yardline_100) %>%
  dplyr::summarise(
    n = dplyr::n(),
    mean_ep  = round(mean(ep, na.rm = TRUE), 4),
    mean_epa = round(mean(epa, na.rm = TRUE), 4),
    .groups = "drop"
  ) %>%
  dplyr::filter(n >= 25) %>%
  dplyr::arrange(yardline_100) %>%
  print()

Expected Behavior

I expect EP to decrease with yardline and EPA to remain ~0 on average.

nflverse_sitrep

── System Info ─────────────────────────────────────────────────────────────────────────
• R version 4.5.2 (2025-10-31 ucrt) • Running under: Windows 11 x64 (build 26100)
── Package Status ──────────────────────────────────────────────────────────────────────
   package  installed  cran  dev behind
1   nfl4th      1.0.5 1.0.5 <NA>       
2 nflfastR 5.2.0.9003 5.2.0 <NA>       
3 nflplotR      1.6.0 1.6.0 <NA>       
4 nflreadr 1.5.0.9001 1.5.0 <NA>       
5 nflseedR      2.0.2 2.0.2 <NA>       
6 nflverse 1.0.3.9001 1.0.3 <NA>       
── Package Options ─────────────────────────────────────────────────────────────────────
• No options set for above packages
── Package Dependencies ────────────────────────────────────────────────────────────────
• base64enc   (0.1-3)   • isoband      (0.3.0)   • scales      (1.4.0)    
• bigD        (0.3.1)   • janitor      (2.2.1)   • snakecase   (0.11.1)   
• bitops      (1.0-9)   • jquerylib    (0.1.4)   • stringi     (1.8.7)    
• bslib       (0.9.0)   • jsonlite     (2.0.0)   • stringr     (1.6.0)    
• cachem      (1.1.0)   • juicyjuice   (0.1.0)   • tibble      (3.3.0)    
• cli         (3.6.5)   • knitr        (1.51)    • tidyr       (1.3.2)    
• commonmark  (2.0.0)   • labeling     (0.4.3)   • tidyselect  (1.2.1)    
• cpp11       (0.5.2)   • lifecycle    (1.0.5)   • timechange  (0.3.0)    
• crayon      (1.5.3)   • listenv      (0.10.0)  • tinytex     (0.58)     
• curl        (7.0.0)   • litedown     (0.9)     • utf8        (1.2.6)    
• data.table  (1.18.0)  • lubridate    (1.9.4)   • V8          (8.0.1)    
• digest      (0.6.39)  • magick       (2.9.0)   • vctrs       (0.6.5)    
• dplyr       (1.1.4)   • magrittr     (2.0.4)   • viridisLite (0.4.2)    
• evaluate    (1.0.5)   • markdown     (2.0)     • withr       (3.0.2)    
• farver      (2.1.2)   • memoise      (2.0.1)   • xfun        (0.55)     
• fastmap     (1.2.0)   • mime         (0.13)    • xgboost     (3.1.2.1)  
• fastrmodels (2.1.0)   • parallelly   (1.45.0)  • xml2        (1.5.1)    
• fontawesome (0.5.3)   • pillar       (1.11.1)  • yaml        (2.3.12)   
• fs          (1.6.6)   • pkgconfig    (2.0.3)   • codetools   (0.2-20)   
• furrr       (0.3.1)   • progressr    (0.18.0)  • compiler    (4.5.2)    
• future      (1.68.0)  • proto        (1.0.0)   • graphics    (4.5.2)    
• generics    (0.1.4)   • purrr        (1.0.4)   • grDevices   (4.5.2)    
• ggpath      (1.1.1)   • R6           (2.6.1)   • grid        (4.5.2)    
• ggplot2     (4.0.1)   • rappdirs     (0.3.3)   • lattice     (0.22-7)   
• globals     (0.18.0)  • RColorBrewer (1.1-3)   • Matrix      (1.7-4)    
• glue        (1.8.0)   • Rcpp         (1.1.0)   • methods     (4.5.2)    
• gsubfn      (0.7)     • reactable    (0.4.5)   • mgcv        (1.9-3)    
• gt          (1.2.0)   • reactR       (0.6.1)   • nlme        (3.1-168)  
• gtable      (0.3.6)   • rlang        (1.1.6)   • parallel    (4.5.2)    
• highr       (0.11)    • rmarkdown    (2.30)    • splines     (4.5.2)    
• hms         (1.1.4)   • rstudioapi   (0.17.1)  • stats       (4.5.2)    
• htmltools   (0.5.9)   • S7           (0.2.1)   • tools       (4.5.2)    
• htmlwidgets (1.6.4)   • sass         (0.4.10)  • utils       (4.5.2)    
────────────────────────────────────────────────────────────────────────────────────────

Screenshots

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions