Last active
March 31, 2018 13:30
-
-
Save bayesball/71f5839529cfa1589f41f4edb938e349 to your computer and use it in GitHub Desktop.
R code to find optimal launch angles from Statcast data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# read in tidyveres package | |
library(tidyverse) | |
# read in the Statcast data for the 2017 season | |
# the file statcast2017.csv can be downloaded from the folder | |
# http://www-math.bgsu.edu/~albert/statcast/ | |
sc <- read_csv("statcast2017.csv") | |
# only consider balls put in play | |
sc_ip <- filter(sc, type == "X") | |
# exploring relationship between launch angle, | |
# exit velocity, and hit/out | |
# first remove home runs and focus on | |
# P(hit | in play and not home run) | |
# Also remove sac hits and sac flies | |
# define the hit variable | |
sc_ip %>% filter(events != "home_run", | |
! (events %in% | |
c("sac_bunt", "sac_fly", | |
"sac_fly_double_play"))) %>% | |
mutate(hit = ifelse(events %in% | |
c("single", "double", "triple", "home_run"), | |
1, 0)) -> sc_ip2 | |
# only look at balls hit in the air and | |
# define a factor variable Hit | |
sc_ip3 <- filter(sc_ip2, launch_angle > 0) | |
sc_ip3$Hit <- as.factor(sc_ip3$hit) | |
# scatterplot of launch angles and exit velocities | |
ggplot(sc_ip3, | |
aes(launch_angle, launch_speed, color=Hit)) + | |
geom_point(size = 0.7, alpha = 0.1) + | |
ylim(25, 125) + | |
ggtitle("Scatterplot of Launch Angle | |
and Launch Speed for Balls in Air") + | |
theme( | |
plot.title = element_text( | |
colour = "blue", | |
size = 16, | |
hjust = 0.5 | |
) | |
) + | |
xlim(0, 40) + ylim(50, 115) | |
# focus on hits with a specific velocity | |
# look at the pattern of binned data | |
# write a function to do this for any speed | |
efit_model2 <- function(ev, width=1, delta=1){ | |
# width is for the binning of launch angle | |
# delta determines blur of launch speed | |
# only considering launch angles in (0, 30) | |
d <- filter(sc_ip3, | |
launch_speed > ev - delta / 2, | |
launch_speed < ev + delta / 2, | |
launch_angle < 30) | |
d$LA <- cut(d$launch_angle, | |
breaks = seq(0, 30, by=width)) | |
d %>% | |
group_by(LA) %>% | |
summarize(N = n(), | |
H = sum(hit), | |
Probability = H / N) -> S | |
S %>% mutate(Mid = seq(0, 30 - width, by=width) + | |
width / 2, | |
launch_speed = ev) | |
} | |
# run this function for a collection of exit velocities | |
map_df(c(75, 80, 85, 90), | |
efit_model2, width=2, delta = 2) -> out | |
out$Launch_Speed = paste("Launch Speed =", | |
out$launch_speed, "mph") | |
write_csv(out, "plotdata.csv") | |
map_df(c(95, 100, 105), | |
efit_model2, width=2, delta = 2) -> out | |
out$Launch_Speed = paste("Launch Speed =", | |
out$launch_speed, "mph") | |
write_csv(out, "plotdata2.csv") | |
##### graphing part | |
d <- read_csv("plotdata.csv") | |
d2 <- read_csv("plotdata2.csv") | |
ggplot(d, aes(Mid, Probability)) + | |
geom_point(color="red") + | |
geom_smooth(method="loess") + | |
facet_wrap(~ Launch_Speed, ncol=2) + | |
xlab("Launch Angle (degrees)") + | |
ylab("Probability(Hit)") + | |
theme(strip.text.x = element_text(size=16, color="red"), | |
text = element_text(size=16)) | |
ggplot(d2, aes(Mid, Probability)) + | |
geom_point(color="red") + | |
geom_smooth(method="loess") + | |
facet_wrap(~ Launch_Speed, ncol=2) + | |
xlab("Launch Angle (degrees)") + | |
ylab("Probability(Hit)") + | |
theme(strip.text.x = element_text(size=14, color="red"), | |
text = element_text(size=16)) | |
# graph the optimal angles | |
df <- data.frame(Launch_Speed = seq(75, 105, by = 5), | |
Optimal_Launch_Angle = c(20, 17, | |
15, 13, 12, 11, 10 )) | |
ggplot(df, aes(Launch_Speed, | |
Optimal_Launch_Angle)) + | |
geom_point(size = 3, color="red") + | |
ggtitle("Optimal Launch Angle") + | |
theme( | |
plot.title = element_text( | |
colour = "blue", | |
size = 18, | |
hjust = 0.5 | |
) | |
) + | |
theme(strip.text.x = element_text(size=16, color="red"), | |
text = element_text(size=16)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment