load("more/kobe.RData")
head(kobe)
## vs game quarter time
## 1 ORL 1 1 9:47
## 2 ORL 1 1 9:07
## 3 ORL 1 1 8:11
## 4 ORL 1 1 7:41
## 5 ORL 1 1 7:03
## 6 ORL 1 1 6:01
## description basket
## 1 Kobe Bryant makes 4-foot two point shot H
## 2 Kobe Bryant misses jumper M
## 3 Kobe Bryant misses 7-foot jumper M
## 4 Kobe Bryant makes 16-foot jumper (Derek Fisher assists) H
## 5 Kobe Bryant makes driving layup H
## 6 Kobe Bryant misses jumper M
In this data frame, every row records a shot taken by Kobe Bryant. If he hit the shot (made a basket), a hit, H, is recorded in the column named basket, otherwise a miss, M, is recorded.
Just looking at the string of hits and misses, it can be difficult to gauge whether or not it seems like Kobe was shooting with a hot hand. One way we can approach this is by considering the belief that hot hand shooters tend to go on shooting streaks. For this lab, we define the length of a shooting streak to be the number of consecutive baskets made until a miss occurs.
For example, in Game 1 Kobe had the following sequence of hits and misses from his nine shot attempts in the first quarter:
\[ \textrm{H M | M | H H M | M | M | M} \]
To verify this use the following command:
kobe$basket[1:9]
## [1] "H" "M" "M" "H" "H" "M" "M" "M" "M"
Within the nine shot attempts, there are six streaks, which are separated by a “|” above. Their lengths are one, zero, two, zero, zero, zero (in order of occurrence)
The custom function calc_streak, which was loaded in with the data, may be used to calculate the lengths of all shooting streaks and then look at the distribution.
kobe_streak <- calc_streak(kobe$basket)
barplot(table(kobe_streak))
While we don’t have any data from a shooter we know to have independent shots, that sort of data is very easy to simulate in R. In a simulation, you set the ground rules of a random process and then the computer uses random numbers to generate an outcome that adheres to those rules. As a simple example, you can simulate flipping a fair coin with the following.
outcomes <- c("heads", "tails")
sample(outcomes, size = 1, replace = TRUE)
## [1] "tails"
sim_fair_coin <- sample(outcomes, size = 100, replace = TRUE)
To view the results of this simulation, type the name of the object and then use table to count up the number of heads and tails.
sim_fair_coin
## [1] "heads" "heads" "heads" "heads" "heads" "tails" "tails" "heads"
## [9] "heads" "heads" "tails" "heads" "heads" "heads" "tails" "tails"
## [17] "tails" "tails" "heads" "heads" "heads" "heads" "heads" "heads"
## [25] "tails" "tails" "heads" "tails" "heads" "heads" "heads" "tails"
## [33] "heads" "tails" "heads" "heads" "heads" "heads" "heads" "tails"
## [41] "tails" "tails" "tails" "heads" "tails" "tails" "tails" "heads"
## [49] "tails" "heads" "heads" "heads" "heads" "heads" "tails" "heads"
## [57] "heads" "tails" "heads" "heads" "tails" "tails" "tails" "tails"
## [65] "tails" "heads" "tails" "tails" "heads" "heads" "heads" "tails"
## [73] "tails" "tails" "tails" "heads" "tails" "heads" "tails" "tails"
## [81] "tails" "tails" "tails" "heads" "tails" "heads" "heads" "tails"
## [89] "tails" "heads" "heads" "heads" "heads" "heads" "heads" "tails"
## [97] "tails" "tails" "tails" "heads"
table(sim_fair_coin)
## sim_fair_coin
## heads tails
## 54 46
Since there are only two elements in outcomes, the probability that we “flip” a coin and it lands heads is 0.5. Say we’re trying to simulate an unfair coin that we know only lands heads 20% of the time. We can adjust for this by adding an argument called prob, which provides a vector of two probability weights.
sim_unfair_coin <- sample(outcomes, size = 100, replace = TRUE, prob = c(0.2, 0.8))
sim_unfair_coin
## [1] "tails" "tails" "tails" "heads" "heads" "tails" "tails" "tails"
## [9] "tails" "tails" "heads" "heads" "heads" "tails" "tails" "tails"
## [17] "tails" "tails" "tails" "tails" "tails" "tails" "tails" "tails"
## [25] "heads" "tails" "tails" "tails" "tails" "tails" "tails" "tails"
## [33] "tails" "tails" "tails" "tails" "tails" "tails" "heads" "tails"
## [41] "tails" "tails" "tails" "tails" "tails" "tails" "tails" "tails"
## [49] "tails" "tails" "tails" "tails" "tails" "tails" "tails" "tails"
## [57] "tails" "heads" "heads" "tails" "tails" "heads" "tails" "tails"
## [65] "tails" "tails" "heads" "tails" "heads" "heads" "tails" "tails"
## [73] "tails" "heads" "tails" "tails" "tails" "heads" "tails" "tails"
## [81] "tails" "tails" "heads" "heads" "tails" "tails" "tails" "tails"
## [89] "tails" "heads" "heads" "tails" "heads" "tails" "heads" "heads"
## [97] "tails" "tails" "tails" "tails"
table(sim_unfair_coin)
## sim_unfair_coin
## heads tails
## 22 78
Simulating a basketball player who has independent shots uses the same mechanism that we use to simulate a coin flip. To simulate a single shot from an independent shooter with a shooting percentage of 50% we type,
outcomes <- c("H", "M")
sim_basket <- sample(outcomes, size = 1, replace = TRUE)
To make a valid comparison between Kobe and our simulated independent shooter, we need to align both their shooting percentage and the number of attempted shots.
outcomes <- c("H", "M")
sim_basket <- sample(outcomes, size = 133, replace = TRUE, prob = c(0.45, 0.55))
sim_basket
## [1] "H" "M" "M" "M" "H" "H" "H" "M" "H" "M" "M" "M" "M" "M" "M" "H" "H"
## [18] "M" "M" "H" "M" "M" "H" "H" "H" "M" "H" "M" "M" "M" "H" "H" "M" "H"
## [35] "H" "M" "M" "H" "M" "M" "M" "H" "M" "H" "M" "H" "M" "M" "H" "M" "M"
## [52] "H" "H" "M" "M" "M" "M" "H" "H" "H" "M" "H" "H" "M" "M" "H" "H" "M"
## [69] "M" "H" "M" "M" "M" "M" "M" "H" "M" "H" "M" "M" "M" "M" "H" "H" "H"
## [86] "H" "H" "M" "M" "H" "M" "M" "M" "M" "H" "H" "M" "M" "H" "H" "M" "M"
## [103] "M" "M" "M" "H" "H" "M" "H" "M" "H" "H" "H" "M" "M" "M" "M" "M" "M"
## [120] "M" "M" "M" "M" "H" "H" "M" "M" "M" "H" "H" "M" "M" "H"
Note that we’ve named the new vector sim_basket, the same name that we gave to the previous vector reflecting a shooting percentage of 50%. In this situation, R overwrites the old object with the new one, so always make sure that you don’t need the information in an old vector before reassigning its name.
With the results of the simulation saved as sim_basket, we have the data necessary to compare Kobe to our independent shooter.
Both data sets represent the results of 133 shot attempts, each with the same shooting percentage of 45%. We know that our simulated data is from a shooter that has independent shots. That is, we know the simulated shooter does not have a hot hand.
sim_streak <- calc_streak(sim_basket)
sim_streak
## [1] 1 0 0 3 1 0 0 0 0 0 2 0 1 0 3 1 0 0 2 2 0 1 0 0 1 1 1 0 1 0 2 0 0 0 3
## [36] 2 0 2 0 1 0 0 0 0 1 1 0 0 0 5 0 1 0 0 0 2 0 2 0 0 0 0 2 1 3 0 0 0 0 0
## [71] 0 0 0 0 2 0 0 2 0 1
barplot(table(sim_streak), col = "lightblue")
The distribution is right skewed.
The typical streak lenght is 0.
The longest streak of baskets is lenght 5.
If we would run the simulation of the independent shooter a second time, results will very each time we run the simulation, but would be somewhat similar.
The Kobe Bryant’s distribution have shorter streaks, while simulated shooter have some longer. We can conclude that shots are independent from each other and the hot hand theory does not hold.