Playoff shot quality difference stats for ’23 contenders (top five Vegas odds):
Den - 5/15 (33%) playoff record; positive shot quality difference in 8/15 (53%) games; 8/15 (53%) games can be predicted by shot quality difference.
Bos - 15/29 (52%) playoff record; positive shot quality difference in 20/29 (69%) games; 18/29 (62%) games can be predicted by shot quality difference.
Mil - 23/35 (66%) playoff record; positive shot quality difference in 26/35 (74%) games; 26/35 (74%) games can be predicted by shot quality difference.
Phi - 13/24 (54%) playoff record; positive shot quality difference in 11/24 (46%) games; 20/24 (83%) games can be predicted by shot quality difference.
Phx - 21/35 (60%) playoff record; positive shot quality difference in 12/35 (34%) games; 16/35 (46%) games can be predicted by shot quality difference.
Playoff Shot Quality difference predictive strength by round:
Round 1 -
Round 2 -
Conference Finals -
Finals -
Last two rounds combined -
*Screenshots of work will be provided in email.
library(tidyverse)
library(jsonlite)
library(janitor)
library(dplyr)
library(nbastatR)
library(reactable)
library(reactablefmtr)
library(plotly)
teams <- c("Denver", "Boston", "Milwaukee", "Philadelphia", "Phoenix")
record <- c(.33, .52, .66, .54, .60)
shot_quality <- c( .53, .69, .74, .46, .34)
predictability<- c(.53, .62, .74, .83, .46)
data <- data.frame(teams, record, shot_quality, predictability)
plot_ly(data, x = ~teams, y = ~record,
type = "bar",
marker = list(color = c("lightblue", "green", "tan", "blue", "orange"))) %>%
layout( title = "Playoff Winning %, '21 & '22")
plot_ly(data, x = ~teams , y = ~shot_quality,
type = "bar",
marker = list(color = c("lightblue", "green", "tan", "blue", "orange"))) %>%
layout( title = "% of playoff games with positive shot quality difference, '21 & '22")
plot_ly(data, x = ~teams, y = ~predictability,
type = "bar",
marker = list(color = c("lightblue", "green", "tan", "blue", "orange"))) %>%
layout( title = "% of playoff games predicted by shot quality difference, '21 & '22")
plot_ly(data, x = ~teams, y = ~record,
type = "bar",
name = "Playoff record") %>%
add_trace( y = ~shot_quality, name = "% of games with + shot qaulity diff") %>%
add_trace( y = ~predictability, name = "Predictability strength of shot quality diff") %>%
layout( title = "Combined chart, '21 & '22 playoffs")
round <- c("Round 1", "Round 2", "Confernce Finals", "Finals", "Final two rounds")
predictive_strength <- c(.63, .63, .70, .44, .62)
data2 <- data.frame(round, predictive_strength)
plot_ly(data2, x = ~round, y = ~predictive_strength,
type = "bar",
color = ~round) %>%
layout(title = "Predictive strength of shot quality difference by round, '21 & '22 playoffs")
bos_opp_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612738&EntityType=Opponent"
bos_opp <- read_json(bos_opp_url)
bos_opp <- bos_opp[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
opp_sq <- bos_opp %>%
select(date,
shot_quality_avg) %>%
mutate(opp_shot_quality_avg = shot_quality_avg) %>%
select(opp_shot_quality_avg)
rf_opp <- bos_opp %>%
select(date,
at_rim_frequency) %>%
mutate(opp_at_rim_freq = at_rim_frequency) %>%
select(opp_at_rim_freq)
bos_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612738&EntityType=Team"
bos <- read_json(bos_url)
bos <- bos[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
sq <- bos %>%
select(date,
shot_quality_avg)
rf <- bos %>%
select(date,
at_rim_frequency)
sq_anal <- cbind(sq, opp_sq) %>%
mutate( shot_qual_diff = (100*shot_quality_avg - 100*opp_shot_quality_avg) ) %>%
mutate_at(vars(shot_qual_diff), funs(round(.,4)))
bos <- game_logs(
seasons = c(2022,2021),
league = "NBA",
result_types = "team",
season_types = "Playoffs"
) %>%
filter(nameTeam == "Boston Celtics")
## Acquiring NBA basic team game logs for the 2020-21 Playoffs
## Acquiring NBA basic team game logs for the 2021-22 Playoffs
bos_wl <- bos %>%
select(outcomeGame,
slugOpponent)
cbind(sq_anal, bos_wl) %>%
select(date,
shot_quality_avg,
opp_shot_quality_avg,
shot_qual_diff,
outcomeGame,
slugOpponent) %>%
mutate( 'Team SQ' = shot_quality_avg,
'Opp SQ' = opp_shot_quality_avg,
'SQ Diff' = shot_qual_diff,
Outcome = outcomeGame,
Opponent = slugOpponent) %>%
select( date,
'Team SQ',
'Opp SQ',
'SQ Diff',
Outcome,
Opponent) %>%
mutate_at(vars('Team SQ', 'Opp SQ'), funs(round(.,4)))%>%
reactable( theme = espn(),
defaultPageSize = 20,
sortable = TRUE,
filterable = TRUE,
searchable = TRUE)
den_opp_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612743&EntityType=Opponent"
den_opp <- read_json(den_opp_url)
den_opp <- den_opp[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
den_opp_sq <- den_opp %>%
select(date,
shot_quality_avg) %>%
mutate(opp_shot_quality_avg = shot_quality_avg) %>%
select(opp_shot_quality_avg)
den_rf_opp <- den_opp %>%
select(date,
at_rim_frequency) %>%
mutate(opp_at_rim_freq = at_rim_frequency) %>%
select(opp_at_rim_freq)
den_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612743&EntityType=Team"
den <- read_json(den_url)
den <- den[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
den_sq <- den %>%
select(date,
shot_quality_avg)
den_rf <- den %>%
select(date,
at_rim_frequency)
sq_anal_den <- cbind(den_sq, den_opp_sq) %>%
mutate( shot_qual_diff = (100*shot_quality_avg - 100*opp_shot_quality_avg) ) %>%
mutate_at(vars(shot_qual_diff), funs(round(.,4)))
den_pl <- game_logs(
seasons = c(2022,2021),
league = "NBA",
result_types = "team",
season_types = "Playoffs"
) %>%
filter(nameTeam == "Denver Nuggets")
## Acquiring NBA basic team game logs for the 2020-21 Playoffs
## Acquiring NBA basic team game logs for the 2021-22 Playoffs
den_wl <- den_pl %>%
select(outcomeGame,
slugOpponent)
cbind(sq_anal_den, den_wl) %>%
select(date,
shot_quality_avg,
opp_shot_quality_avg,
shot_qual_diff,
outcomeGame,
slugOpponent) %>%
mutate( 'Team SQ' = shot_quality_avg,
'Opp SQ' = opp_shot_quality_avg,
'SQ Diff' = shot_qual_diff,
Outcome = outcomeGame,
Opponent = slugOpponent) %>%
select( date,
'Team SQ',
'Opp SQ',
'SQ Diff',
Outcome,
Opponent) %>%
mutate_at(vars('Team SQ', 'Opp SQ'), funs(round(.,4))) %>%
reactable( theme = espn(),
defaultPageSize = 20,
sortable = TRUE,
filterable = TRUE,
searchable = TRUE)
mil_opp_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612749&EntityType=Opponent"
mil_opp <- read_json(mil_opp_url)
mil_opp <- mil_opp[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
mil_opp_sq <- mil_opp %>%
select(date,
shot_quality_avg) %>%
mutate(opp_shot_quality_avg = shot_quality_avg) %>%
select(opp_shot_quality_avg)
mil_rf_opp <- mil_opp %>%
select(date,
at_rim_frequency) %>%
mutate(opp_at_rim_freq = at_rim_frequency) %>%
select(opp_at_rim_freq)
mil_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612749&EntityType=Team"
mil <- read_json(mil_url)
mil <- mil[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
mil_sq <- mil %>%
select(date,
shot_quality_avg)
mil_rf <- mil %>%
select(date,
at_rim_frequency)
sq_anal_mil <- cbind(mil_sq, mil_opp_sq) %>%
mutate( shot_qual_diff = (100*shot_quality_avg - 100*opp_shot_quality_avg) ) %>%
mutate_at(vars(shot_qual_diff), funs(round(.,4)))
mil_pl <- game_logs(
seasons = c(2022,2021),
league = "NBA",
result_types = "team",
season_types = "Playoffs"
) %>%
filter(nameTeam == "Milwaukee Bucks")
## Acquiring NBA basic team game logs for the 2020-21 Playoffs
## Acquiring NBA basic team game logs for the 2021-22 Playoffs
mil_wl <- mil_pl %>%
select(outcomeGame,
slugOpponent)
cbind(sq_anal_mil, mil_wl) %>%
select(date,
shot_quality_avg,
opp_shot_quality_avg,
shot_qual_diff,
outcomeGame,
slugOpponent) %>%
mutate( 'Team SQ' = shot_quality_avg,
'Opp SQ' = opp_shot_quality_avg,
'SQ Diff' = shot_qual_diff,
Outcome = outcomeGame,
Opponent = slugOpponent) %>%
select( date,
'Team SQ',
'Opp SQ',
'SQ Diff',
Outcome,
Opponent) %>%
mutate_at(vars('Team SQ', 'Opp SQ'), funs(round(.,4))) %>%
reactable( theme = espn(),
defaultPageSize = 20,
sortable = TRUE,
filterable = TRUE,
searchable = TRUE)
phi_opp_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612755&EntityType=Opponent"
phi_opp <- read_json(phi_opp_url)
phi_opp <- phi_opp[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
phi_opp_sq <- phi_opp %>%
select(date,
shot_quality_avg) %>%
mutate(opp_shot_quality_avg = shot_quality_avg) %>%
select(opp_shot_quality_avg)
phi_rf_opp <- phi_opp %>%
select(date,
at_rim_frequency) %>%
mutate(opp_at_rim_freq = at_rim_frequency) %>%
select(opp_at_rim_freq)
phi_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612755&EntityType=Team"
phi <- read_json(phi_url)
phi <- phi[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
phi_sq <- phi %>%
select(date,
shot_quality_avg)
phi_rf <- phi %>%
select(date,
at_rim_frequency)
phi_sq_anal <- cbind(phi_sq, phi_opp_sq) %>%
mutate( shot_qual_diff = (100*shot_quality_avg - 100*opp_shot_quality_avg) ) %>%
mutate_at(vars(shot_qual_diff), funs(round(.,4)))
phi <- game_logs(
seasons = c(2022,2021),
league = "NBA",
result_types = "team",
season_types = "Playoffs"
) %>%
filter(nameTeam == "Philadelphia 76ers")
## Acquiring NBA basic team game logs for the 2020-21 Playoffs
## Acquiring NBA basic team game logs for the 2021-22 Playoffs
phi_wl <- phi %>%
select(outcomeGame,
slugOpponent)
cbind(phi_sq_anal, phi_wl) %>%
select(date,
shot_quality_avg,
opp_shot_quality_avg,
shot_qual_diff,
outcomeGame,
slugOpponent) %>%
mutate( 'Team SQ' = shot_quality_avg,
'Opp SQ' = opp_shot_quality_avg,
'SQ Diff' = shot_qual_diff,
Outcome = outcomeGame,
Opponent = slugOpponent) %>%
select( date,
'Team SQ',
'Opp SQ',
'SQ Diff',
Outcome,
Opponent) %>%
mutate_at(vars('Team SQ', 'Opp SQ'), funs(round(.,4))) %>%
reactable( theme = espn(),
defaultPageSize = 20,
sortable = TRUE,
filterable = TRUE,
searchable = TRUE)
phx_opp_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612756&EntityType=Opponent"
phx_opp <- read_json(phx_opp_url)
phx_opp <- phx_opp[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
phx_opp_sq <- phx_opp %>%
select(date,
shot_quality_avg) %>%
mutate(opp_shot_quality_avg = shot_quality_avg) %>%
select(opp_shot_quality_avg)
phx_rf_opp <- phx_opp %>%
select(date,
at_rim_frequency) %>%
mutate(opp_at_rim_freq = at_rim_frequency) %>%
select(opp_at_rim_freq)
phx_url <- "https://api.pbpstats.com/get-game-logs/nba?Season=2021-22,2020-21&SeasonType=Playoffs&EntityId=1610612756&EntityType=Team"
phx <- read_json(phx_url)
phx <- phx[["multi_row_table_data"]] %>%
bind_rows() %>%
clean_names()
phx_sq <- phx %>%
select(date,
shot_quality_avg)
phx_rf <- phx %>%
select(date,
at_rim_frequency)
phx_sq_anal <- cbind(phx_sq, phx_opp_sq) %>%
mutate( shot_qual_diff = (100*shot_quality_avg - 100*opp_shot_quality_avg) ) %>%
mutate_at(vars(shot_qual_diff), funs(round(.,4)))
phx <- game_logs(
seasons = c(2022,2021),
league = "NBA",
result_types = "team",
season_types = "Playoffs"
) %>%
filter(nameTeam == "Phoenix Suns")
## Acquiring NBA basic team game logs for the 2020-21 Playoffs
## Acquiring NBA basic team game logs for the 2021-22 Playoffs
phx_wl <- phx %>%
select(outcomeGame,
slugOpponent)
cbind(phx_sq_anal, phx_wl) %>%
select(date,
shot_quality_avg,
opp_shot_quality_avg,
shot_qual_diff,
outcomeGame,
slugOpponent) %>%
mutate( 'Team SQ' = shot_quality_avg,
'Opp SQ' = opp_shot_quality_avg,
'SQ Diff' = shot_qual_diff,
Outcome = outcomeGame,
Opponent = slugOpponent) %>%
select( date,
'Team SQ',
'Opp SQ',
'SQ Diff',
Outcome,
Opponent) %>%
mutate_at(vars('Team SQ', 'Opp SQ'), funs(round(.,4))) %>%
reactable( theme = espn(),
defaultPageSize = 20,
sortable = TRUE,
filterable = TRUE,
searchable = TRUE)