First R Final

Page content

How does the current NBA look like compared to the NBA over time?

Authors: Vu, Praneeth, M

Research Question : How does the current NBA look like compared to the NBA over time?

Set up:

Opening libraries

rm(list = ls())
# Data manipulation libraries
library(lubridate)
library(tidyverse)
library(dplyr)
# Plotting
library(ggplot2)
library(rattle)
# Machine Learning libraries
library(rpart.plot)
library(RColorBrewer)

Data Intake:

# Reading in the data
champ <- read.csv("./championsdata.csv")
runnerups <- read.csv("./runnerupsdata.csv")
nba_team <- read.csv("./NBA_Team_Stats.csv")
historical <- read.csv("./Historical_NBA_Performance.csv")
DefRating <- read.csv("./NBA_Defensive_Ratings.csv")

Data Cleanup:

# Filtering out the empty values, and pulling out the first 4 columns
historical <- historical[1:4]
historical <- historical %>% na.omit()
# Shortening every season name to only include the first year
season <- DefRating$SEASON
season <- as.numeric(substr(season, 1, 4))
DefRating$SEASON <- season 
# Renaming the defensive rating variable
def_rating <- DefRating$DEF.RTG
DefRating$def_rating <- def_rating
DefRating <- DefRating %>% select(-7)
# Calculate average defensive rating per season
DefRatingAvg <-
  DefRating %>%
  group_by(SEASON) %>%
  summarise(defratingSeasonAvg = sum(def_rating)/n())

summarise() ungrouping output (override with .groups argument)

# Renaming another variable
rating_Vs_League_Avg <- DefRating$RTG.vs..LEAGUE.AVG
DefRating$rating_Vs_League_Avg<- rating_Vs_League_Avg
DefRating <- DefRating %>% select(-7)
# Making the final datasets from merging two tables, champ and runner-ups
Result <- "Winner"
champ <- cbind(champ,Result)

Result <- "Runner-up"
runnerups <- cbind(runnerups, Result)

FinalsGames = champ %>%
  full_join(runnerups,by=c('Year','Team','Game','Win','Home','MP','FG','FGA','FGP','TP','TPA','TPP','FT','FTA','FTP','ORB','DRB','TRB','AST','STL','BLK','TOV','PF','PTS','Result'))

# Finding average points scored each year
AveragePoints <-
  FinalsGames %>%
  group_by(Year,Result) %>%
  summarise(AveragePTS=(sum(PTS)/n()))

summarise() regrouping output by ‘Year’ (override with .groups argument)

# Finding average three point attempts and three point percentage per year
ThreePointsStat <-
  FinalsGames %>%
  group_by(Year, Result) %>%
  summarise(ThreePtsAttempt=(sum(TPA)/n()),
            ThreePtsPerc=(sum(TPP)/n()))

summarise() regrouping output by ‘Year’ (override with .groups argument)

# Comparing the average three point attempts from the winner teams with the runner-up teams in the NBA Finals from 1980 to 2018
ThreePtsCompare <-
  ThreePointsStat %>%
  select(Year,Result,ThreePtsAttempt) %>%
  pivot_wider(names_from=Result, values_from=ThreePtsAttempt)

Examine Data Source:

The origin of our data was from a Website knows as Kaggle. The website is known for having a huge compilation of datasets, in order for people to learn data science.There are 4 data tables that we are currently working with. The four tables are Champion data, runner-up data, historical NBA data, and NBA team data. The data was collected from stats of past games that the NBA collects and has collected since its inception.

The Champion Table is data about the championship winning teams from 1980 to 2018. It looks at variables such as Field Goals, wins, free throw percentage, and more.

The Runner-Up Data includes the same 24 variables and number of cases as the champions data, but this cases are for the the yearly runner-up.

The third table is the tables on NBA Team Data. It has 22 variables ranging from points to year. This data is for every NBA regular season for each team from 1997 to 2021.

The final table is the table on historical team data Historical Team Data , which is just data on every teams win percentage throughout the years.

Key Variables to look at across the data sets would be the team, year, wins, loses, defensive rating (defrating), points (pts), rebounds, assists (AST), steals (STL), blocks (BLK), winning percentage(Winning.Percentage), and defensive rebounds. As these will be our metric to give a holistic view of each team over the years and how the game has changed.

Discover/Explore features that may influence modeling decisions (both sources):

# Examining the modified data
head(nba_team)
TeamGMinPtsRebAStStlBlkToPfDrebOrebFgm.aPctX3gm.aPct.1Ftm.aPct.2EffDeffYear
Chicago10348.496.044.123.18.64.313.021.129.214.936.7-81.70.4493.9-12.00.32318.7-25.20.7411117.51997-1998
Utah10248.396.640.824.77.64.814.724.329.511.335.9-74.30.4833.1-8.40.36823.8-30.90.768116.317.51997-1998
Phoenix8648.699.341.925.69.25.314.421.729.812.138.2-82.00.4665.2-14.70.35517.7-23.60.747117.113.61997-1998
L.A Lakers9548.3104.842.924.38.76.814.722.929.713.238.0-79.10.4806.1-17.30.35022.8-33.70.675120.813.21997-1998
San Antonio9148.492.544.121.96.26.915.321.232.211.935.1-75.10.4683.7-10.80.34418.5-26.80.688108.013.11997-1998
indiana9848.495.338.622.47.84.513.623.028.210.435.0-74.90.4685.0-12.90.38720.3-26.60.763109.012.21997-1998
head(historical)
YearTeamRecordWinning.Percentage
2016-17Celtics25-150.0625
2015-16Celtics48-340.585
2014-15Celtics40-420.488
2013-14Celtics25-570.305
2012-13Celtics41-400.506
2011-12*Celtics39-270.591
6 rows
head(ThreePtsCompare)
YearRunner-upWinner
19802.666666670.6666667
19811.8333332.8333333
19822.3333331.5000000
19833.7500000.7500000
19842.5714293.2857143
19855.6666673.8333333
6 rows

For these Data sets there won’t be any outliers potentially as the years go on there will be a gradual increase in the statistics of the team and that will make the data more unimodal rather than skewed. And the outliers are data points that we want to include as those points would be important years to look at across all data tables.

To analyze our data there will be mostly transformations mutations, filtering and selecting variables in our data to get a better understanding of what changed in the NBA over the years.

Across all data tables there will be inherent relationships with the data as it looks at the same teams in the data over the years.

# Creating Plot
ggplot(ThreePointsStat) +
  aes(x = Year, y = ThreePtsAttempt, size = ThreePtsPerc) +
  geom_point(shape = "circle", colour = "#112446") +
  geom_smooth() +
  ylab('Three Point Attempts') +
  theme_minimal() +
  facet_wrap(~Result) +
  ggtitle("Three Point Attempts per Year \n for Runner-ups vs Winners") +
  theme(plot.title = element_text(hjust = 0.5))

https://ibb.co/H4vxnt9 Figure 1

This graph illustrates the number of three point attempts in the Finals each year with the percentage of three point made. The x-axis represents the year, the y-axis represents the number of three point attempts, and the size indicates the three point percentage. The first graph represents the statistics from the runner-up teams, and the second graph represents the statistics from the winner team.

# Creating Plot
ggplot(FinalsGames) +
  aes(x = Year, y = FGA, colour = Result) +
  geom_line(size = 0.5) +
  scale_color_hue(direction = 1) +
  ylab('Field Goal Attempt') +
  geom_smooth() +
  theme_minimal() +
  ggtitle("Field Goal Attempts per Year") +
  theme(plot.title = element_text(hjust = 0.5))

https://ibb.co/H4vxnt9 Figure 2

This graph illustrates the number of field goal attempts in Finals games from the winner team and the runner-up team over year. The y-axis is the number of field goal attempts, the x-xis is year, and the color represents winner team and runner-up team.

# Creating Plot
ggplot(AveragePoints) +
  aes(x = Year, y = AveragePTS) +
  geom_line(size = 0.5, colour = "#112446") +
  ylab('Average Points') +
  geom_smooth() +
  theme_minimal() +
  ggtitle("Average Points per Year") +
  theme(plot.title = element_text(hjust = 0.5))

https://ibb.co/H4vxnt9 Figure 3

This graph illustrates the average points scored in Finals games each year. The y-axis is the number of average points, the x-axis is the year.

# Creating Plot
ggplot(DefRatingAvg) +
 aes(x = SEASON, y = defratingSeasonAvg) +
 geom_line(size = 1L, colour = "#0c4c8a") +
 geom_smooth() +
 ylab('Defensive Rating Average') +
 xlab('Year') +
 theme_minimal() +
 ggtitle("Defensive Rating Average per Year") +
 theme(plot.title = element_text(hjust = 0.5))

https://ibb.co/H4vxnt9 Figure 4

Since the average defensive rating has increased overtime, we can conclude that the defensive play per team has slowly gotten better overtime as the rating increased by about 5 points from 1996.

# Creating a table that filters out a few important variables to analyze how they affects the result variable
TheBest <-
 FinalsGames %>%
  select(FGP, TPP, ORB, DRB, STL, BLK, Result) %>%
  na.omit()
TheBest$Result[which(TheBest$Result == "Winner")] = 1
TheBest$Result[which(TheBest$Result == "Runner-up")] = 0
TheBest$Result <- as.numeric(TheBest$Result)

# Making the machine learning model
MachineL <-rpart(Result ~ FGP  + TPP, data = TheBest,method = "class" , minsplit = 2, minbucket = 1, cp =-1)
MachineL <-prune(MachineL, cp = 0.01)

# Plotting the model
fancyRpartPlot(MachineL,caption = NULL)

https://ibb.co/H4vxnt9 Figure 5

This is to show the effects of each variable as it pertains to wins and losses for teams. For instance we can see a trend where as teams have a higher FGP that they usually tend to win the championship. Not only this but conversely we see that if the field goal percentage is less than 55% that teams do not end up winning the championship. I think that these are some useful patterns to look at in our data because we can see the effects of different variables and extract our predicted output which variables are useful in addressing our research question. To be more specific, Does field goal percentage have an impact on whether or not a team was a winner for that year? And answering this question is something that I believe machine learning does well to solve as it splits the data nicely and shows the changes in variables.

When looking at our data we can see that a lot of what one would assume is true as it pertains to the data. As the points increases we see that the teams tend to win more often and they also tend to have a higher field goal percentage as well. This can be useful in practical sense as it pertains to coaching where a team might decide to have more three point shots than two pointers. As doing so based on this model tends to lead to increase their chances of winning the game. Address Research Question:

Our initial analysis is that the game has changed a lot over time, but that can be hard to see if you were to just look at the average teams points per game in 1980 and compare it to 2018. We can see that there was a dip in the points per game that reached a minimum in the mid 2000s, but it has slowly gone up since then, and it is back to where it was in the 1980s. This data perfectly lines up with the field goals attempted on average starting high with the 80s, slightly decreasing, and then going back up to present day. One area where we have seen a massive change is the amount of three pointers attempted per year. For this figure the amount of three point shots attempted has only gone up since the 1980s. The increase has been massive, with the amount of three pointers attempted in the 80s being under 10 per game, to reaching over 30 per game in the current NBA.

We slightly changed our research question as our understanding of the data improved. Originally our research question was “how does the NBA of today compare to the NBA of the 1980s?” But now that we see trends in the data that don’t reflect if you just look at stats today versus in the 1980s. In order to cover those trends we refined our question to be more of an all encompassing “how does our current NBA compare to the NBA over time?” This way we can point out more meaningful changes. Updated Answer For The Research Question:

After further analyzing and visualizing our data, we have come to a realization of how the NBA play style has changed over time. Figure 4 shows that the defensive rating has been trending up, which means that the defense had found an effective way to block close-range attacks. Therefore, the teams had to adapt and improvise different strategies, hence the uptrend of the three point attempts in Figure 1. The total number of field goal attempts as well as average points from 1980 has stayed relatively close to what we have now, but the number of three point attempts have increased substantially.

From these insights, we have come to a conclusion that from 1980, the games were all about close-range attacks, because the three-point line was only invented in 1979, a year before the start of this dataset. As the defense got better at blocking close-range attacks, the teams had to find their way in by shooting three’s. As they found that going for a three point is an effective way to attack, more teams have switched to a three-point play style, and gradually they got better and more precise with ranged shots.