EPV

SDS 355

Prof. Baumer

October 8, 2025

Expected Point Value (EPV)

Who deserves what credit for this play?

SportVu tracking data

EPV Dashboard

https://josedv.shinyapps.io/EPV_NBA_Dashboard/

Raw data

library(tidyverse)
epv <- read_csv(here::here("data-large/2013_11_01_MIA_BKN.csv"))
epv_small <- epv |>
  filter(possID < 10) |>
  write_rds(here::here("data/epv_small.rds"))
library(tidyverse)
epv_small <- read_rds(here::here("data/epv_small.rds"))
dim(epv_small)
[1] 2913   49
players <- read_csv(here::here("data/players2013.csv"))
head(players)
# A tibble: 6 × 9
  player_id firstname lastname position       height weight byear rookie
      <dbl> <chr>     <chr>    <chr>           <dbl>  <dbl> <dbl>  <dbl>
1      3306 Elton     Brand    Forward-Center     81    254  1979   1999
2     58293 Kyle      Korver   Guard-Forward      79    212  1981   2003
3    292401 Lou       Williams Guard              73    175  1986   2005
4    237675 Paul      Millsap  Forward-Center     80    258  1985   2006
5    280587 Al        Horford  Forward-Center     82    250  1986   2007
6    398043 Jeff      Teague   Point-Guard        74    181  1988   2009
# ℹ 1 more variable: position.number <dbl>

What’s in there?

epv_small |>
  group_by(possID) |>
  count()
# A tibble: 9 × 2
# Groups:   possID [9]
  possID     n
   <dbl> <int>
1      1   471
2      2   175
3      3   351
4      4   435
5      5   460
6      6   279
7      7   288
8      8   273
9      9   181

Where did the ball go?

epv_small |>
  ggplot(aes(x = x, y = y)) +
  geom_point() +
  facet_wrap(vars(possID))

Tracking Paul Pierce

epv_small |>
  filter(h2_ent == 3235, possID < 10) |>
  ggplot(aes(x = h2_x, y = h2_y)) +
  geom_point() +
  facet_wrap(vars(possID))

The first play

The second play