TimStats commited on
Commit
444a13f
·
verified ·
1 Parent(s): ebbfe35

Update app.R

Browse files
Files changed (1) hide show
  1. app.R +77 -45
app.R CHANGED
@@ -163,15 +163,86 @@ scale_TimStuff <- function(raw_score, model_mean, model_sd) {
163
  result <- 50 - (scaled_score * 10)
164
  return(result)
165
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
166
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  summary_table <- function(game) {
168
  rows <- nrow(game)
 
 
169
  sumtable <- game %>%
170
- mutate(
171
- VAA = calculate_VAA(vz0, ay,az, vy0, y0),
172
- EAA = calculate_EAA(extension),
173
- SADiff = calculate_SADiff(pfxX, pfxZ,spinDirection)
174
- ) %>%
175
  mutate(team_fielding_id = ifelse(description == "Called Strike" |
176
  description == "Swinging Strike" |
177
  description == "Swinging Strike (Blocked)", 1, 0)) %>%
@@ -186,45 +257,6 @@ summary_table <- function(game) {
186
  mutate(is_strike_swinging = ifelse(is_strike_swinging == TRUE, 1, 0)) %>%
187
  mutate(Pitch = pitch_name) %>%
188
  rowwise() %>%
189
- mutate(TimStuff = if (phand == 'L') {
190
- case_when(
191
- Pitch %in% c("Four-Seam Fastball", "Sinker", "Cutter", "Fastball") ~
192
- ifelse(any(is.na(c(start_speed, IVB, -HB, EAA, -x0, z0, spin_rate, SADiff))),
193
- NA_real_,
194
- scale_TimStuff(predict(FB, matrix(c(start_speed, IVB, -HB, EAA, -x0, z0, spin_rate, SADiff), nrow = 1, ncol = 8)),
195
- -0.0011801, 0.007989927)),
196
- Pitch %in% c("Changeup", "Splitter", "Screwball", "Forkball") ~
197
- ifelse(any(is.na(c(start_speed, IVB, -HB, EAA, -x0, z0, spin_rate, SADiff))),
198
- NA_real_,
199
- scale_TimStuff(predict(Off, matrix(c(start_speed, IVB, -HB, EAA, -x0, z0, spin_rate, SADiff), nrow = 1, ncol = 8)),
200
- -0.002239657, 0.01043216)),
201
- Pitch %in% c("Slider", "Slurve", "Sweeper", "Curveball", "Knuckle Curve", "Slow Curve", "Knuckleball") ~
202
- ifelse(any(is.na(c(start_speed, IVB, -HB, EAA, -x0, z0, spin_rate, SADiff))),
203
- NA_real_,
204
- scale_TimStuff(predict(Break, matrix(c(start_speed, IVB, -HB, EAA, -x0, z0, spin_rate, SADiff), nrow = 1, ncol = 8)),
205
- -0.004822031, 0.007912765)),
206
- TRUE ~ NA_real_
207
- )
208
- } else {
209
- case_when(
210
- Pitch %in% c("Four-Seam Fastball", "Sinker", "Cutter", "Fastball") ~
211
- ifelse(any(is.na(c(start_speed, IVB, HB, EAA, x0, z0, spin_rate, SADiff))),
212
- NA_real_,
213
- scale_TimStuff(predict(FB, matrix(c(start_speed, IVB, HB, EAA, x0, z0, spin_rate, SADiff), nrow = 1, ncol = 8)),
214
- -0.0011801, 0.007989927)),
215
- Pitch %in% c("Changeup", "Splitter", "Screwball", "Forkball") ~
216
- ifelse(any(is.na(c(start_speed, IVB, HB, EAA, x0, z0, spin_rate, SADiff))),
217
- NA_real_,
218
- scale_TimStuff(predict(Off, matrix(c(start_speed, IVB, HB, EAA, x0, z0, spin_rate, SADiff), nrow = 1, ncol = 8)),
219
- -0.002239657, 0.01043216)),
220
- Pitch %in% c("Slider", "Slurve", "Sweeper", "Curveball", "Knuckle Curve", "Slow Curve", "Knuckleball") ~
221
- ifelse(any(is.na(c(start_speed, IVB, HB, EAA, x0, z0, spin_rate, SADiff))),
222
- NA_real_,
223
- scale_TimStuff(predict(Break, matrix(c(start_speed, IVB, HB, EAA, x0, z0, spin_rate, SADiff), nrow = 1, ncol = 8)),
224
- -0.004822031, 0.007912765)),
225
- TRUE ~ NA_real_
226
- )
227
- }) %>%
228
  group_by(Pitch) %>%
229
  summarize(
230
  Pitches = n(),
@@ -237,7 +269,7 @@ summary_table <- function(game) {
237
  'VAA' = round(mean(VAA, na.rm = TRUE), digits = 1),
238
  'CSW%' = round(sum(team_fielding_id, na.rm = TRUE) / sum(!is.na(team_fielding_id)) * 100, digits = 1),
239
  'Whiff%' = round(sum(is_strike_swinging, na.rm = TRUE) / sum(swing, na.rm = TRUE) * 100, digits = 1),
240
- 'TimStuff' = round(mean(TimStuff, na.rm = TRUE), digits = 0)
241
  ) %>%
242
  arrange(-Pitches)
243
 
 
163
  result <- 50 - (scaled_score * 10)
164
  return(result)
165
  }
166
+ calculate_primary <- function(data){
167
+ data <- data %>%
168
+ # Group by pitch_name, Pitcher Name, Pitcher Id, and date
169
+ group_by(pitch_name, `Pitcher Name`, `Pitcher ID`, date) %>%
170
+
171
+ # Count occurrences and calculate average start_speed, IVB, and HB for each group
172
+ mutate(
173
+ pitch_count = n(),
174
+ avg_start_speed = mean(start_speed, na.rm = TRUE),
175
+ avg_IVB = mean(IVB, na.rm = TRUE),
176
+ avg_HB = mean(HB, na.rm = TRUE)
177
+ ) %>%
178
+
179
+ ungroup() %>%
180
+ # Group by Pitcher Name, Pitcher Id, and date
181
+ group_by(`Pitcher Name`, `Pitcher ID`, date) %>%
182
+
183
+ # Add a column to identify the highest occurrence
184
+ mutate(
185
+ is_highest_occurrence = case_when(
186
+ pitch_count == max(pitch_count) ~ 1,
187
+ TRUE ~ 0
188
+ )
189
+ ) %>%
190
+
191
+ # If there's a tie, use avg_start_speed as a tiebreaker
192
+ mutate(
193
+ is_highest_occurrence = case_when(
194
+ is_highest_occurrence == 1 & pitch_count == max(pitch_count[is_highest_occurrence == 1]) &
195
+ avg_start_speed == max(avg_start_speed[is_highest_occurrence == 1]) ~ 1,
196
+ TRUE ~ 0
197
+ )
198
+ ) %>%
199
+
200
+ # Calculate primary pitch metrics
201
+ mutate(
202
+ primary_speed = avg_start_speed[is_highest_occurrence == 1][1],
203
+ primary_IVB = avg_IVB[is_highest_occurrence == 1][1],
204
+ primary_HB = avg_HB[is_highest_occurrence == 1][1]
205
+ ) %>%
206
+
207
+ # Ungroup to remove grouping structure
208
+ ungroup()
209
+ }
210
 
211
+ calculate_timstuff <- function(game) {
212
+ game <- calculate_primary(game)
213
+ game <- game %>%
214
+ mutate(VAA = calculate_VAA(vz0, ay, az, vy0, y0),
215
+ EAA = calculate_EAA(extension),
216
+ SADiff = calculate_SADiff(pfxX, pfxZ, spinDirection),
217
+ team_fielding_id = ifelse(description %in% c("Called Strike", "Swinging Strike", "Swinging Strike (Blocked)"), 1, 0),
218
+ swing = ifelse(description %in% c("Foul", "Foul Pitchout", "In play, no out", "In play, out(s)", "In play, run(s)", "Swinging Strike", "Swinging Strike (Blocked)", "Foul Tip"), 1, 0),
219
+ is_strike_swinging = ifelse(is_strike_swinging, 1, 0),
220
+ Pitch = pitch_name,
221
+ ishandL = ifelse(phand == "L",1,0))
222
+ # game <- calculate_primary(game)
223
+
224
+ feature_vars <- c("ishandL","start_speed", "IVB", "HB", "EAA", "x0", "z0", "spin_rate","SADiff","primary_speed","primary_IVB","primary_HB")
225
+ complete_rows <- complete.cases(game[, feature_vars])
226
+ game_complete <- game[complete_rows, ]
227
+ game_na <- game[!complete_rows,]
228
+ game_na$TimStuff <- NA
229
+
230
+ rhp <- game_complete
231
+
232
+ # rhp <- game_complete[game_complete$ishandL == 0]
233
+ #
234
+ # lhp$TimStuff <- scale_TimStuff(predict(model, as.matrix(cbind(lhp$ishandL,lhp$start_speed, lhp$IVB, lhp$HB, lhp$EAA, lhp$x0, lhp$z0, lhp$spin_rate, lhp$SADiff,lhp$primary_speed,lhp$primary_IVB,lhp$primary_HB))), -0.00249975, 0.007566558)
235
+
236
+ rhp$TimStuff <- scale_TimStuff(predict(model, as.matrix(cbind(rhp$ishandL,rhp$start_speed, rhp$IVB, rhp$HB, rhp$EAA, rhp$x0, rhp$z0, rhp$spin_rate, rhp$SADiff,rhp$primary_speed,rhp$primary_IVB,rhp$primary_HB))), -0.00249975, 0.007566558)
237
+
238
+ game_complete <- rbind(rhp,game_na)
239
+ return(game_complete)
240
+ }
241
  summary_table <- function(game) {
242
  rows <- nrow(game)
243
+ game <- calculate_primary(game)
244
+ game <- calculate_TimStuff(game)
245
  sumtable <- game %>%
 
 
 
 
 
246
  mutate(team_fielding_id = ifelse(description == "Called Strike" |
247
  description == "Swinging Strike" |
248
  description == "Swinging Strike (Blocked)", 1, 0)) %>%
 
257
  mutate(is_strike_swinging = ifelse(is_strike_swinging == TRUE, 1, 0)) %>%
258
  mutate(Pitch = pitch_name) %>%
259
  rowwise() %>%
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
260
  group_by(Pitch) %>%
261
  summarize(
262
  Pitches = n(),
 
269
  'VAA' = round(mean(VAA, na.rm = TRUE), digits = 1),
270
  'CSW%' = round(sum(team_fielding_id, na.rm = TRUE) / sum(!is.na(team_fielding_id)) * 100, digits = 1),
271
  'Whiff%' = round(sum(is_strike_swinging, na.rm = TRUE) / sum(swing, na.rm = TRUE) * 100, digits = 1),
272
+ 'TimStuff+' = round(mean(TimStuff, na.rm = TRUE), digits = 0)
273
  ) %>%
274
  arrange(-Pitches)
275