With the game on the line, there are many variables that can affect the outcome. The pressure of winning games can affect the performances of players and their respective teams. For this analysis, we will focus on the performance of players and teams during clutch situations, exploring how their performances are affected by pressure situations. More specifically, do teams/players perform better or worse from the regular season to the playoffs?
The term “clutch” is defined as a situation when a game is within 5 points in the final 5 minutes. We will examine data that compares team clutch stats with non-clutch stats, focusing specifically on the regular season. Additionally, we will also analyze regular season and playoff clutch performances for both teams and players, respectively. The data we collected centered on 20 NBA seasons for team statistics from 2001-2002 to 2021-2022, and 10 NBA seasons for players from 2011-2012 to 2021-2022. We will use traditional statistics such as field goal and free throw percentages, win percentage, total points, and plus/minus, which measures whether the score margin increased or decreased with the team or player on the court. While there are numerous amounts of advanced stats, we will use only two metrics for this analysis: true shooting percentage, which uses field goal and free throw attempts to calculate a team and player’s shooting percentages, and turnover rate, which is calculated utilizing turnovers, field goal and free throw attempts. This data was obtained using the hoopR library. libraries.
new_team_csv <- read.csv("https://raw.githubusercontent.com/moham6839/Data607_Final_Project/master/Team_Clutch_Data.csv")
DT::datatable(new_team_csv)
# split the dataset into regular season and playoff seasons
regular_season_dataset <- new_team_csv %>%
filter(Season_Type == "Regular Season")
playoff_season_dataset <- new_team_csv %>%
filter(Season_Type == "Playoffs")
team_rs_clutch <- regular_season_dataset %>%
select(TEAM_NAME, PLUS_MINUS, FGM, FGA, FG3M, FG3A, FTM, FTA, GP, W, PTS, REB, TOV) %>%
group_by(TEAM_NAME) %>%
summarise(total_pm = sum(PLUS_MINUS),
points_per_game = sum(PTS)/sum(GP),
total_games = sum(GP),
total_wins = sum(W),
win_pct = sum(W)/sum(GP),
total_points = sum(PTS),
total_rebounds = sum(REB),
total_fgm = sum(FGM),
total_fga = sum(FGA),
total_fgpct = sum(FGM)/sum(FGA),
total_fg3pct = sum(`FG3M`)/sum(`FG3A`),
total_ftm = sum(FTM),
total_fta = sum(FTA),
total_tov = sum(TOV),
ft_pct = sum(FTM)/sum(FTA),
#True shooting percentage: PT/(2*(FGA+0.44*FTA))
true_shoot_pct = total_points/(2*(total_fga+0.44*total_fta)),
# Turnover Rate = 100*TO/(FGA+0.44*FTA+TO)
tov_rate = 100*total_tov /(total_fga+0.44*total_fta+total_tov)
) %>%
arrange(desc(total_pm), win_pct)
DT::datatable(team_rs_clutch)
team_rs_win_pct <- team_rs_clutch %>%
select(TEAM_NAME, win_pct) %>%
#filter(total_games >= 20) %>%
arrange(desc(win_pct))
DT::datatable(team_rs_win_pct)
ggplot(data=team_rs_win_pct, aes(x=reorder(TEAM_NAME, win_pct), y=win_pct)) +
geom_bar(stat="identity", position="dodge", fill = "orange") +
theme_minimal() +
labs(title="NBA Regular Season Team Clutch Win %",
y="Win %",
x="Team") +
coord_flip()
team_rs_pm <- team_rs_clutch %>%
select(TEAM_NAME, total_pm) %>%
arrange(desc(total_pm))
DT::datatable(team_rs_pm)
color <- ifelse(team_rs_pm$total_pm < 0, "lightblue", "orange")
ggplot(data=team_rs_pm, aes(x=reorder(TEAM_NAME, -total_pm), y=total_pm)) +
geom_bar(stat="identity",
position="dodge",
fill = color,
show.legend = FALSE) +
geom_text(aes(label = total_pm,
hjust = ifelse(total_pm < 0, 1.25, -.25),
vjust = 0.5),
size = 2) +
theme_minimal() +
labs(title="NBA Regular Season Team Clutch Plus/Minus",
y="Plus/Minus",
x="Team") +
coord_flip()
team_rs_ppg <- team_rs_clutch %>%
select(TEAM_NAME, points_per_game) %>%
arrange(desc(points_per_game))
DT::datatable(team_rs_ppg)
ggplot(data=team_rs_ppg, aes(x=reorder(TEAM_NAME, points_per_game), y=points_per_game)) +
geom_bar(stat="identity",
position="dodge",
color = "white",
fill = "red",
show.legend = FALSE) +
geom_text(aes(label = round(points_per_game, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="NBA Regular Season Team Clutch Points Per Game",
y="Points Per Game",
x="Team") +
coord_flip()
team_rs_fgpct <- team_rs_clutch %>%
select(TEAM_NAME, total_fgpct) %>%
arrange(desc(total_fgpct))
DT::datatable(team_rs_fgpct)
ggplot(data=team_rs_fgpct, aes(x=reorder(TEAM_NAME, total_fgpct), y=total_fgpct)) +
geom_bar(stat="identity",
position="dodge",
color = "white",
fill = "orange",
show.legend = FALSE) +
geom_text(aes(label = round(total_fgpct, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="NBA Regular Season Total Clutch Team Field Goal %",
y="Field Goal Percentage",
x="Team") +
coord_flip()
team_rs_ftpct <- team_rs_clutch %>%
select(TEAM_NAME, ft_pct) %>%
arrange(desc(ft_pct))
DT::datatable(team_rs_ftpct)
ggplot(data=team_rs_ftpct, aes(x=reorder(TEAM_NAME, ft_pct), y=ft_pct)) +
geom_bar(stat="identity",
position="dodge",
color = "white",
fill = "lightblue",
show.legend = FALSE) +
geom_text(aes(label = round(ft_pct, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="NBA Regular Season Team Clutch Free Throw %",
y="Free Throw %",
x="Team") +
coord_flip()
team_rs_ts <- team_rs_clutch %>%
select(TEAM_NAME, true_shoot_pct) %>%
arrange(desc(true_shoot_pct))
DT::datatable(team_rs_ts)
ggplot(data=team_rs_ts, aes(x=reorder(TEAM_NAME, true_shoot_pct), y=true_shoot_pct)) +
geom_bar(stat="identity",
position="dodge",
color = "white",
fill = "red",
show.legend = FALSE) +
geom_text(aes(label = round(true_shoot_pct, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(y="True Shooting Percentage",
x="Team") +
coord_flip()
team_rs_tov <- team_rs_clutch %>%
select(TEAM_NAME, tov_rate) %>%
arrange(desc(tov_rate))
DT::datatable(team_rs_tov)
ggplot(data=team_rs_tov, aes(x=reorder(TEAM_NAME, -tov_rate), y=tov_rate)) +
geom_bar(stat="identity",
position="dodge",
fill = "lightblue") +
geom_text(aes(label = round(tov_rate, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(
y="Turnover Rate",
x="Team") +
coord_flip()
# Team Clutch Stats - Playoffs 2001-02 to 2021-22
team_playoff_clutch <- playoff_season_dataset %>%
select(TEAM_NAME, PLUS_MINUS, FGM, FGA, FG3M, FG3A, FTM, FTA, GP, W, PTS, REB, TOV) %>%
group_by(TEAM_NAME) %>%
summarise(total_pm = sum(PLUS_MINUS),
points_per_game = sum(PTS)/sum(GP),
total_games = sum(GP),
total_wins = sum(W),
win_pct = sum(W)/sum(GP),
total_points = sum(PTS),
total_rebounds = sum(REB),
total_fgm = sum(FGM),
total_fga = sum(FGA),
total_fgpct = sum(FGM)/sum(FGA),
total_fg3pct = sum(`FG3M`)/sum(`FG3A`),
total_ftm = sum(FTM),
total_fta = sum(FTA),
total_tov = sum(TOV),
ft_pct = sum(FTM)/sum(FTA),
#True shooting percentage: PT/(2*(FGA+0.44*FTA))
true_shoot_pct = total_points/(2*(total_fga+0.44*total_fta)),
# Turnover Rate = 100*TO/(FGA+0.44*FTA+TO)
tov_rate = 100*total_tov /(total_fga+0.44*total_fta+total_tov)
) %>%
# using filter to remove outlier
filter(win_pct < 0.8) %>%
arrange(desc(total_pm), win_pct)
DT::datatable(team_playoff_clutch)
team_playoff_win_pct <- team_playoff_clutch %>%
select(TEAM_NAME, win_pct, total_games) %>%
filter(total_games >= 10) %>%
arrange(desc(win_pct))
DT::datatable(team_playoff_win_pct)
ggplot(data=team_playoff_win_pct, aes(x=reorder(TEAM_NAME, win_pct), y=win_pct)) +
geom_bar(stat="identity",
position="dodge",
fill = "red") +
theme_minimal() +
labs(title="NBA Playoffs Team Clutch Win Percentage",
y="Win Percentage",
x="Team") +
coord_flip()
team_playoff_pm <- team_playoff_clutch %>%
select(TEAM_NAME, total_pm) %>%
arrange(desc(total_pm))
DT::datatable(team_playoff_pm)
color <- ifelse(team_playoff_pm$total_pm < 0, "lightblue", "orange")
ggplot(data=team_playoff_pm, aes(x=reorder(TEAM_NAME, -total_pm), y=total_pm)) +
geom_bar(stat="identity",
position="dodge",
fill = color) +
geom_text(aes(label = round(total_pm, 3),
hjust = ifelse(total_pm < 0, 1.25, -.25),
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="NBA Playoffs Team Clutch Plus/Minus",
y="Plus/Minus",
x="Team") +
coord_flip()
team_playoff_fg_pct <- team_playoff_clutch %>%
select(TEAM_NAME, total_fgpct) %>%
arrange(desc(total_fgpct))
DT::datatable(team_playoff_fg_pct)
ggplot(data=team_playoff_fg_pct, aes(x=reorder(TEAM_NAME, total_fgpct), y=total_fgpct)) +
geom_bar(stat="identity",
position="dodge",
fill = "orange") +
geom_text(aes(label = round(total_fgpct, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="NBA Playoffs Team Clutch Field Goal %",
y="Field Goal %",
x="Team") +
coord_flip()
team_playoff_ft_pct <- team_playoff_clutch %>%
select(TEAM_NAME, ft_pct) %>%
arrange(desc(ft_pct))
DT::datatable(team_playoff_ft_pct)
ggplot(data=team_playoff_ft_pct, aes(x=reorder(TEAM_NAME, ft_pct), y=ft_pct)) +
geom_bar(stat="identity",
position="dodge",
fill = "lightblue") +
geom_text(aes(label = round(ft_pct, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="NBA Playoffs Team Clutch Free Throw %",
y="Free Throw %",
x="Team") +
coord_flip()
team_playoff_ppg <- team_playoff_clutch %>%
select(TEAM_NAME, points_per_game) %>%
arrange(desc(points_per_game))
DT::datatable(team_playoff_ppg)
ggplot(data=team_playoff_ppg, aes(x=reorder(TEAM_NAME, points_per_game), y=points_per_game)) +
geom_bar(stat="identity",
position="dodge",
fill = "red") +
geom_text(aes(label = round(points_per_game, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="NBA Playoffs Team Clutch Points Per Game ",
y="Total Points",
x="Team") +
coord_flip()
team_playoff_ts <- team_playoff_clutch %>%
select(TEAM_NAME, true_shoot_pct) %>%
arrange(desc(true_shoot_pct))
DT::datatable(team_playoff_ts)
ggplot(data=team_playoff_ts, aes(x=reorder(TEAM_NAME, true_shoot_pct), y=true_shoot_pct)) +
geom_bar(stat="identity",
position="dodge",
fill = "orange") +
geom_text(aes(label = round(true_shoot_pct, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="NBA Playoffs Team Clutch True Shooting % ",
y="True Shooting %",
x="Team") +
coord_flip()
team_playoff_tov <- team_playoff_clutch %>%
select(TEAM_NAME, tov_rate) %>%
arrange(desc(tov_rate))
DT::datatable(team_playoff_tov)
ggplot(data=team_playoff_tov, aes(x=reorder(TEAM_NAME, -tov_rate), y=tov_rate)) +
geom_bar(stat="identity",
position="dodge",
fill = "lightblue") +
geom_text(aes(label = round(tov_rate, 3),
hjust = -.25,
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="NBA Playoffs Team Clutch Turnover Rate",
y="Turnover Rate",
x="Team") +
coord_flip()
## Combining Team Regular Season and Playoff Clutch Stats
combined_team_winpct <- inner_join(team_rs_win_pct, team_playoff_win_pct, by="TEAM_NAME") %>%
mutate(diff = win_pct.y - win_pct.x) %>%
arrange(desc(diff))
DT::datatable(combined_team_winpct)
color <- ifelse(combined_team_winpct$diff < 0, "lightblue", "orange")
ggplot(data=combined_team_winpct, aes(x=reorder(TEAM_NAME, diff), y=diff)) +
geom_bar(stat="identity",
position="dodge",
fill = color) +
geom_text(aes(label = round(diff, 3),
hjust = ifelse(diff < 0, 1.25, -.25),
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="Team Differential in Win %",
y="Win %",
x="Team") +
coord_flip()
### Plus/Minus
combined_team_pm <- inner_join(team_rs_pm, team_playoff_pm, by="TEAM_NAME") %>%
mutate(diff = total_pm.x - total_pm.y) %>%
arrange(desc(diff))
DT::datatable(combined_team_pm)
ggplot(data=combined_team_pm, aes(x=reorder(TEAM_NAME, diff), y=diff)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="Team Differential in Plus/Minus",
y="Plus/Minus",
x="Team") +
coord_flip()
combined_team_fgpct <- inner_join(team_rs_fgpct, team_playoff_fg_pct, by="TEAM_NAME") %>%
mutate(diff = round((total_fgpct.y - total_fgpct.x), digits=3)) %>%
arrange(desc(diff))
DT::datatable(combined_team_fgpct)
color <- ifelse(combined_team_fgpct$diff < 0, "lightblue", "orange")
ggplot(data=combined_team_fgpct, aes(x=reorder(TEAM_NAME, diff), y=diff)) +
geom_bar(stat="identity", position="dodge", fill = color) +
geom_text(aes(label = round(diff, 3),
hjust = ifelse(diff < 0, 1.25, -.25),
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="Team Differential in Field Goal %",
y="Win %",
x="Team") +
coord_flip()
combined_team_ppg <- inner_join(team_rs_ppg, team_playoff_ppg, by="TEAM_NAME") %>%
mutate(diff = round((points_per_game.y - points_per_game.x), digits=3))%>%
arrange(desc(diff))
DT::datatable(combined_team_ppg)
color <- ifelse(combined_team_ppg$diff < 0, "lightblue", "orange")
ggplot(data=combined_team_ppg, aes(x=reorder(TEAM_NAME, diff), y=diff)) +
geom_bar(stat="identity", position="dodge", fill = color) +
geom_text(aes(label = round(diff, 3),
hjust = ifelse(diff < 0, 1.25, -.25),
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="Team Differential in Points Per Game",
y="PPG",
x="Team") +
coord_flip()
combined_team_ftpct <- inner_join(team_rs_ftpct, team_playoff_ft_pct, by="TEAM_NAME") %>%
mutate(diff = ft_pct.y - ft_pct.x) %>%
arrange(desc(diff))
DT::datatable(combined_team_ftpct)
color <- ifelse(combined_team_ftpct$diff < 0, "lightblue", "orange")
ggplot(data=combined_team_ftpct, aes(x=reorder(TEAM_NAME, diff), y=diff)) +
geom_bar(stat="identity", position="dodge", fill = color) +
geom_text(aes(label = round(diff, 3),
hjust = ifelse(diff < 0, 1.25, -.25),
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="Team Differential in Free Throw %",
y="FT %",
x="Team") +
coord_flip()
combined_team_tspct <- inner_join(team_rs_ts, team_playoff_ts, by="TEAM_NAME") %>%
mutate(diff = true_shoot_pct.y - true_shoot_pct.x) %>%
arrange(desc(diff))
DT::datatable(combined_team_tspct)
color <- ifelse(combined_team_tspct$diff < 0, "lightblue", "orange")
ggplot(data=combined_team_tspct, aes(x=reorder(TEAM_NAME, diff), y=diff)) +
geom_bar(stat="identity", position="dodge", fill = color) +
geom_text(aes(label = round(diff, 3),
hjust = ifelse(diff < 0, 1.25, -.25),
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="Team Differential in True Shooting %",
y="TS %",
x="Team") +
coord_flip()
combined_team_tov <- inner_join(team_rs_tov, team_playoff_tov, by="TEAM_NAME") %>%
mutate(diff = tov_rate.y - tov_rate.x) %>%
arrange(desc(diff))
DT::datatable(combined_team_tov)
color <- ifelse(combined_team_tov$diff < 0, "lightblue", "orange")
ggplot(data=combined_team_tov, aes(x=reorder(TEAM_NAME, diff), y=diff)) +
geom_bar(stat="identity", position="dodge", fill = color) +
geom_text(aes(label = round(diff, 3),
hjust = ifelse(diff < 0, 1.25, -.25),
vjust = 0.25),
size = 2) +
theme_minimal() +
labs(title="Team Differential in Turnover Rate",
y="Turnover Rate",
x="Team") +
coord_flip()
After reviewing both regular and playoffs season, we see that under pressure, teams performance do get impacted, for better or worse. For instance, Cleveland Cavalier have the biggest change in terms of winning percentage due to an average winning performance during regular season. They do score the highest percentage during playoffs.
In term of points per game, Orlando Magic shows the biggest change. Interestingly, Portland Trail Blazer have the highest PPG on both regular and playoffs season, hence the differential is small.
For Field Goal %, Philly 76ers shows the strongest change due lackluster % in regular reason and big improvement in the playoffs. Utah Jazz have the top spot of field goal % during regular season, but performed poorly during playoffs. For playoffs season, that goes to Phoenix Suns.
We see a lot of significant changes in free throw %. Dallas Maverick have the highest free throw % during regular season and Atlanta Hawks have the highest with 84% during playoffs, making a significant change with 7.2% increase. Maverick is not that far off with 82.3% in that aspect.
We see small positive changes on true shooting %. Utah Jazz have the highest true shooting % during playoffs while LA Clippers scores the highest in regular seasons. From there, we see a significant drop with Clippers (-23.5%).
Finally on turnover rate, we see that Milwaukee Buck have the biggest change. They performed below average during regular season and exceed during playoffs.
Cleveland, Miami, Golden State, and Los Angelos Lakers were the top 4 teams in team clutch win % differential from the regular season to playoffs. Unsurprisingly, all four teams have won NBA championships.
During the regular season, the San Antonio Spurs performed superbly in the clutch. They were 1st in clutch win percentage, ranking 2nd in Plus/Minus, 5th in field goal clutch percentage, 6th in points per game and true shooting percentage. This success in clutch moments translated to the playoffs, ranking 5th in clutch win %, 4th in clutch field goal percentage, 4th in plus/minus, 4th in points per game and 7th in true shooting %.
new_player_csv <- read.csv("https://raw.githubusercontent.com/moham6839/Data607_Final_Project/master/Player_Clutch_Data.csv")
DT::datatable(new_player_csv)
## Warning in instance$preRenderHook(instance): It seems your data is too big for
## client-side DataTables. You may consider server-side processing:
## https://rstudio.github.io/DT/server.html
regular_season_player_dataset <- new_player_csv %>%
filter(Season_Type == "Regular Season")
rs_clutch_player <- regular_season_player_dataset %>%
select(PLAYER_NAME, PLUS_MINUS, FGM, FGA, FG3M, FG3A, FTM, FTA, GP, W, PTS, REB, TOV) %>%
group_by(PLAYER_NAME) %>%
summarise(total_pm = sum(PLUS_MINUS),
points_per_game = sum(PTS)/sum(GP),
total_games = sum(GP),
total_wins = sum(W),
win_pct = sum(W)/sum(GP),
total_points = sum(PTS),
total_rebounds = sum(REB),
total_fgm = sum(FGM),
total_fga = sum(FGA),
total_fgpct = sum(FGM)/sum(FGA),
total_fg3pct = sum(`FG3M`)/sum(`FG3A`),
total_ftm = sum(FTM),
total_fta = sum(FTA),
total_tov = sum(TOV),
ft_pct = sum(FTM)/sum(FTA),
#True shooting percentage: PT/(2*(FGA+0.44*FTA))
true_shoot_pct = total_points/(2*(total_fga+0.44*total_fta)),
# Turnover Rate = 100*TO/(FGA+0.44*FTA+TO)
tov_rate = 100*total_tov /(total_fga+0.44*total_fta+total_tov)
) %>%
arrange(desc(total_pm), win_pct)
DT::datatable(rs_clutch_player)
player_rs_pm <- rs_clutch_player %>%
select(PLAYER_NAME, total_pm, total_games) %>%
filter(total_games >= 200) %>%
arrange(desc(total_pm))
DT::datatable(player_rs_pm)
ggplot(data=player_rs_pm[1:25, ], aes(x=reorder(PLAYER_NAME, -total_pm), y=total_pm)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Regular Season Top 25 Player Clutch Plus/Minus",
y="Total Plus/Minus",
x="Player") +
coord_flip()
player_rs_win_pct <- rs_clutch_player %>%
select(PLAYER_NAME, win_pct, total_games) %>%
filter(total_games >= 200) %>%
arrange(desc(win_pct))
DT::datatable(player_rs_win_pct)
ggplot(data=player_rs_win_pct[1:25, ], aes(x=reorder(PLAYER_NAME, -win_pct), y=win_pct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Top 25 Regular Season Player Clutch Win %",
y="Win Percentage",
x="Player") +
coord_flip()
player_rs_ppg <- rs_clutch_player %>%
select(PLAYER_NAME, points_per_game, total_games) %>%
filter(total_games >= 200) %>%
arrange(desc(points_per_game))
DT::datatable(player_rs_ppg)
ggplot(data=player_rs_ppg[1:25, ], aes(x=reorder(PLAYER_NAME, -points_per_game), y=points_per_game)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Regular Season Top 25 Player Clutch Points Per Game",
y="Points Per Game",
x="Player") +
coord_flip()
player_rs_fgpct <- rs_clutch_player %>%
select(PLAYER_NAME, total_fgpct, total_fga) %>%
filter(total_fga >=200) %>%
arrange(desc(total_fgpct))
DT::datatable(player_rs_fgpct)
ggplot(data=player_rs_fgpct[1:25, ], aes(x=reorder(PLAYER_NAME, -total_fgpct), y=total_fgpct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Regular Season Top 25 Player Clutch Field Goal %",
y="Field Goal %",
x="Player") +
coord_flip()
player_rs_ftpct <- rs_clutch_player %>%
select(PLAYER_NAME, ft_pct, total_fta, total_games) %>%
filter(total_games >= 200 & total_fta >=100) %>%
arrange(desc(ft_pct))
DT::datatable(player_rs_ftpct)
ggplot(data=player_rs_ftpct[1:25, ], aes(x=reorder(PLAYER_NAME, -ft_pct), y=ft_pct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Regular Season Top 20 Player Clutch Free Throw %",
y="Free Throw %",
x="Player") +
coord_flip()
player_rs_tspct <- rs_clutch_player %>%
select(PLAYER_NAME, true_shoot_pct, total_fga, total_fta) %>%
filter(total_fga >= 200 & total_fta >= 100) %>%
arrange(desc(true_shoot_pct))
DT::datatable(player_rs_tspct)
ggplot(data=player_rs_tspct[1:25, ], aes(x=reorder(PLAYER_NAME, -true_shoot_pct), y=true_shoot_pct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Regular Season Top 25 Player Clutch True Shooting %",
y="True Shooting %",
x="Player") +
coord_flip()
playoff_season_player_dataset <- new_player_csv %>%
filter(Season_Type == "Playoffs")
playoff_performers <- playoff_season_player_dataset %>%
select(PLAYER_NAME, PLUS_MINUS, FGM, FGA, FG3M, FG3A, FTM, FTA, GP, W, PTS, REB, TOV) %>%
group_by(PLAYER_NAME) %>%
summarise(total_pm = sum(PLUS_MINUS),
points_per_game = sum(PTS)/sum(GP),
total_games = sum(GP),
total_wins = sum(W),
win_pct = sum(W)/sum(GP),
total_points = sum(PTS),
total_rebounds = sum(REB),
total_fgm = sum(FGM),
total_fga = sum(FGA),
total_fgpct = sum(FGM)/sum(FGA),
total_fg3pct = sum(`FG3M`)/sum(`FG3A`),
total_ftm = sum(FTM),
total_fta = sum(FTA),
total_tov = sum(TOV),
ft_pct = sum(FTM)/sum(FTA),
#True shooting percentage: PT/(2*(FGA+0.44*FTA))
true_shoot_pct = total_points/(2*(total_fga+0.44*total_fta)),
# Turnover Rate = 100*TO/(FGA+0.44*FTA+TO)
tov_rate = 100*total_tov /(total_fga+0.44*total_fta+total_tov)
) %>%
arrange(desc(total_pm), win_pct)
DT::datatable(playoff_performers)
player_playoff_pm <- playoff_performers %>%
select(PLAYER_NAME, total_pm, total_games) %>%
#filter(total_games >= 25) %>%
arrange(desc(total_pm))
DT::datatable(player_playoff_pm)
ggplot(data=player_playoff_pm[1:20, ], aes(x=reorder(PLAYER_NAME, -total_pm), y=total_pm)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Top 20 Players Clutch Plus/Minus",
y="Plus/Minus",
x="Player") +
coord_flip()
ggplot(data=playoff_performers[494:514, ], aes(x=reorder(PLAYER_NAME, total_pm), y=total_pm)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Bottom 20 Players Clutch Plus/Minus",
y="Plus/Minus",
x="Player") +
coord_flip()
player_playoff_win_pct <- playoff_performers %>%
select(PLAYER_NAME, win_pct, total_games) %>%
filter(total_games >= 20) %>%
arrange(desc(win_pct))
DT::datatable(player_playoff_win_pct)
ggplot(data=player_playoff_win_pct[1:20, ], aes(x=reorder(PLAYER_NAME, -win_pct), y=win_pct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Top 20 Players Clutch Win %",
y="Win %",
x="Player") +
coord_flip()
ggplot(data=player_playoff_win_pct[71:91, ], aes(x=reorder(PLAYER_NAME, win_pct), y=win_pct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Bottom 20 Players Clutch Win %",
y="Win %",
x="Player") +
coord_flip()
player_playoff_fg_pct <- playoff_performers %>%
select(PLAYER_NAME, total_fgpct, total_fga) %>%
filter(total_fga >= 40) %>%
arrange(desc(total_fgpct))
DT::datatable(player_playoff_fg_pct)
ggplot(data=player_playoff_fg_pct[1:20, ], aes(x=reorder(PLAYER_NAME, -total_fgpct), y=total_fgpct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Top 20 Players Clutch Field Goal %",
y="Win %",
x="Player") +
coord_flip()
ggplot(data=player_playoff_fg_pct[21:41, ], aes(x=reorder(PLAYER_NAME, total_fgpct), y=total_fgpct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Bottom 20 Players Clutch Field Goal %",
y="Field Goal %",
x="Player") +
coord_flip()
player_playoff_ft_pct <- playoff_performers %>%
select(PLAYER_NAME, ft_pct, total_fta) %>%
filter(total_fta >= 25) %>%
arrange(desc(ft_pct))
DT::datatable(player_playoff_ft_pct)
ggplot(data=player_playoff_ft_pct[1:32, ], aes(x=reorder(PLAYER_NAME, -ft_pct), y=ft_pct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title= "NBA Playoffs Players Clutch Free Throw %",
y="Free Throw %",
x="Player") +
coord_flip()
player_playoff_ppg <- playoff_performers %>%
select(PLAYER_NAME, points_per_game, total_games) %>%
filter(total_games >= 25) %>%
arrange(desc(points_per_game))
DT::datatable(player_playoff_ppg)
ggplot(data=player_playoff_ppg[1:20, ], aes(x=reorder(PLAYER_NAME, -points_per_game), y=points_per_game)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Top 20 Players Clutch Points Per Game",
y="Points Per Game",
x="Player") +
coord_flip()
ggplot(data=player_playoff_ppg[45:65, ], aes(x=reorder(PLAYER_NAME, -points_per_game), y=points_per_game)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Bottom 20 Players Clutch Points Per Game",
y="Points Per Game",
x="Player") +
coord_flip()
player_playoff_ts_pct <- playoff_performers %>%
select(PLAYER_NAME, true_shoot_pct, total_fga, total_fta) %>%
filter(total_fga >= 50 & total_fta >= 25) %>%
arrange(desc(true_shoot_pct))
DT::datatable(player_playoff_ts_pct)
ggplot(data=player_playoff_ts_pct[1:20, ], aes(x=reorder(PLAYER_NAME, -true_shoot_pct), y=true_shoot_pct)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Top Players True Shooting %",
y="True Shooting %",
x="Player") +
coord_flip()
combined_fgpct_df <- inner_join(player_rs_fgpct, player_playoff_fg_pct, by="PLAYER_NAME") %>%
mutate(diff = total_fgpct.y - total_fgpct.x) %>%
arrange(diff)
DT::datatable(combined_fgpct_df)
ggplot(data=combined_fgpct_df, aes(x=reorder(PLAYER_NAME, -diff), y=diff)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="NBA Playoffs Player Field Goal %",
y="Field Goal %",
x="Player") +
coord_flip()
combined_ppg_df <- inner_join(player_rs_ppg, player_playoff_ppg, by="PLAYER_NAME") %>%
mutate(diff = round((points_per_game.y - points_per_game.x), digits=3)) %>%
arrange(diff)
DT::datatable(combined_ppg_df)
ggplot(data=combined_ppg_df[1:20, ], aes(x=reorder(PLAYER_NAME, diff), y=diff)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="Player Points Per Game (Minimum 25 Games)",
y="Plus/Minus",
x="Player") +
coord_flip()
ggplot(data=combined_ppg_df[27:47, ], aes(x=reorder(PLAYER_NAME, -diff), y=diff)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="Player Difference Points Per Game (Minimum 25 Games)",
y="Points Per Game",
x="Player") +
coord_flip()
combined_ftpct_df <- inner_join(player_rs_ftpct, player_playoff_ft_pct, by="PLAYER_NAME") %>%
mutate(diff = round((ft_pct.y - ft_pct.x), digits=3)) %>%
arrange(diff)
DT::datatable(combined_ftpct_df)
ggplot(data=combined_ftpct_df, aes(x=reorder(PLAYER_NAME, -diff), y=diff)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="Player Free Throw Percentage Difference (Minimum 25 FTA)",
y="Plus/Minus",
x="Player") +
coord_flip()
combined_win_pct_df <- inner_join(player_rs_win_pct, player_playoff_win_pct, by="PLAYER_NAME") %>%
mutate(diff = round((win_pct.y - win_pct.x), digits=3)) %>%
arrange(desc(diff))
DT::datatable(combined_win_pct_df)
ggplot(data=combined_win_pct_df[1:20, ], aes(x=reorder(PLAYER_NAME, -diff), y=diff)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="Player Winning % Difference (Minimum 200 Reg. Season and 20 Playoff Games)",
y="Win %",
x="Player") +
coord_flip()
ggplot(data=combined_win_pct_df[45:65, ], aes(x=reorder(PLAYER_NAME, -diff), y=diff)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="Player Win % Difference (Minimum 200 Reg. Season and 20 PO Games)",
y="Win %",
x="Player") +
coord_flip()
combined_tspct_df <- inner_join(player_rs_tspct, player_playoff_ts_pct, by="PLAYER_NAME") %>%
mutate(diff = round((true_shoot_pct.y - true_shoot_pct.x), digits=3)) %>%
arrange(desc(diff))
DT::datatable(combined_tspct_df)
ggplot(data=combined_tspct_df[1:19, ], aes(x=reorder(PLAYER_NAME, -diff), y=diff)) +
geom_bar(stat="identity", position="dodge") +
theme_minimal() +
labs(title="Player TS % Difference",
y="TS %",
x="Player") +
coord_flip()
Kyrie Irving has the biggest decline in Points Per Game in clutch situations from the regular season to playoffs, followed by Russell Westbrook. Other notable names in the top 10 in declining points per game were Kevin Durant and James Harden.
While Chris Paul had the highest positive Plus/Minus number among all players in the regular season, he had one of the highest negative Plus/Minus in the playoffs. Notably, his clutch win % declined in the playoffs as well, from winning 65% of regular season games to just 50% in the playoffs.
LeBron James produced in the clutch. He ranked 3rd in points per game during the regular season and playoffs, with a slight decrease of approximately 0.14 points from the regular season to playoffs. Despite having a decrease in field goal percentage from the regular season to playoffs, his win percentage increased by 0.03, illustrating his level of clutch play.
While Kawhi Leonard ranked first in clutch win percentage during the regular season, he did not rank high in some of the statistical categories. He ranked 12th in plus/minus, 24th in points per game, and 54th in field goal percentage. Additionally, there was a significant decrease in win percentage , from close to 66% in the regular season to 52% in the playoffs, showing declines in both points per game and field goal percentage.
Possible next steps that can be explored include using more advanced stats such as rebounding rate, effective field goal and assist percentages. Additionally, with the exception of Plus/Minus, this analysis does not measure the impact of defense in clutch situations. Traditional defensive stats such as blocks and steals, as well as advanced stats such as defensive efficiency, could shed light on the affects of defense in clutch situations from a team perspective.
The game of basketball is a team sport. However, players who are capable of making pressurized shots that help their teams win games is an important quality that enables teams to win a lot of games and in some situations a championship. Performing in the clutch is a special skill that permeates throughout sports. In basketball, being “clutch” means that a player is able to make a score a basket or make a play that helps their team to a win. This analysis explores that various stats that can help explain how teams and players have performed in clutch situations, providing a groundwork to build on to perform further and future analyses on clutch team and player stats.