Update app.R
Browse files
app.R
CHANGED
|
@@ -48,7 +48,7 @@ download_private_csv <- function(repo_id, filename) {
|
|
| 48 |
t <- download_private_csv("TimStats/Passwords", "demo.csv")
|
| 49 |
pass <- t[1,1]
|
| 50 |
|
| 51 |
-
|
| 52 |
|
| 53 |
# Helper functions
|
| 54 |
download_and_process_image <- function(url) {
|
|
@@ -408,58 +408,21 @@ transform_statcast_data <- function(df,
|
|
| 408 |
return(df)
|
| 409 |
}
|
| 410 |
|
| 411 |
-
|
| 412 |
-
#game <- transform_statcast_data(game) %>% mutate(SADiff = calculate_SADiff(pfxx, pfxz, SpinAxis))
|
| 413 |
-
|
| 414 |
-
# Filter and handle fastball calculations with error checking
|
| 415 |
-
# Get primary pitch info directly within the function
|
| 416 |
-
primary_pitch1 <- game %>%
|
| 417 |
-
filter(pitch_name == "Sinker" | pitch_name == "Fastball" | pitch_name == "Cutter" |
|
| 418 |
-
pitch_name == "FourSeamFastBall" | pitch_name == "OneSeamFastBall" | pitch_name == "TwoSeamFastBall") %>%
|
| 419 |
-
group_by(`Pitcher Name`) %>%
|
| 420 |
-
count(pitch_name) %>%
|
| 421 |
-
summarise(max = max(n))
|
| 422 |
-
|
| 423 |
-
primary_pitch2 <- game %>%
|
| 424 |
-
filter(pitch_name == "Sinker" | pitch_name == "Fastball" | pitch_name == "Cutter" |
|
| 425 |
-
pitch_name == "FourSeamFastBall" | pitch_name == "OneSeamFastBall" | pitch_name == "TwoSeamFastBall") %>%
|
| 426 |
-
group_by(`Pitcher Name`, pitch_name) %>%
|
| 427 |
-
count(pitch_name)
|
| 428 |
-
|
| 429 |
-
primary_pitch <- left_join(primary_pitch1, primary_pitch2, by = c('Pitcher Name')) %>%
|
| 430 |
-
filter(max == n) %>%
|
| 431 |
-
select(`Pitcher Name`, pitch_name) %>%
|
| 432 |
-
filter(pitch_name != "Undefined" & pitch_name != "Other") %>%
|
| 433 |
-
mutate(Primary = pitch_name) %>%
|
| 434 |
-
select(-pitch_name)
|
| 435 |
-
|
| 436 |
-
game <- left_join(game, primary_pitch, by = c('Pitcher Name'))
|
| 437 |
-
|
| 438 |
-
# Calculate primary pitch averages
|
| 439 |
-
primary_avgs <- game %>%
|
| 440 |
-
filter(pitch_name == Primary) %>%
|
| 441 |
-
group_by(`Pitcher Name`) %>%
|
| 442 |
-
summarise(
|
| 443 |
-
Primary_Velo = mean(start_speed, na.rm = TRUE),
|
| 444 |
-
Primary_IVB = mean(IVB, na.rm = TRUE),
|
| 445 |
-
Primary_HB = mean(HB, na.rm = TRUE)
|
| 446 |
-
)
|
| 447 |
-
|
| 448 |
-
# Join averages and calculate differences
|
| 449 |
game <- game %>%
|
| 450 |
-
left_join(primary_avgs, by = c('Pitcher Name')) %>%
|
| 451 |
mutate(
|
| 452 |
-
|
| 453 |
-
|
| 454 |
-
|
| 455 |
-
|
|
|
|
| 456 |
)
|
| 457 |
-
|
| 458 |
-
feature_vars <- c("start_speed", "IVB", "HB", "spin_rate",
|
| 459 |
-
"z0", "x0", "extension", "velo_diff", "IVB_diff", "HB_diff")
|
| 460 |
complete_rows <- complete.cases(game[, feature_vars])
|
| 461 |
game_complete <- game[complete_rows, ]
|
| 462 |
game_na <- game[!complete_rows, ]
|
|
|
|
| 463 |
game_na <- if(any(!complete_rows)) {
|
| 464 |
na_rows <- game[!complete_rows, ]
|
| 465 |
na_rows$TimStuff <- NA
|
|
@@ -471,156 +434,23 @@ calculatetimstuffall <- function(game) {
|
|
| 471 |
empty_df
|
| 472 |
}
|
| 473 |
|
| 474 |
-
|
| 475 |
-
|
| 476 |
-
|
| 477 |
-
|
| 478 |
-
game_complete$spin_rate <- round(game_complete$spin_rate, 1)
|
| 479 |
-
game_complete$z0 <- round(game_complete$z0, 1)
|
| 480 |
-
game_complete$x0 <- abs(round(game_complete$x0, 1))
|
| 481 |
-
game_complete$extension <- round(game_complete$extension, 1)
|
| 482 |
-
game_complete$velo_diff <- round(game_complete$velo_diff, 1)
|
| 483 |
-
game_complete$IVB_diff <- round(game_complete$IVB_diff, 1)
|
| 484 |
-
game_complete$HB_diff <- round(game_complete$HB_diff, 1)
|
| 485 |
-
|
| 486 |
-
# Split right-handed and left-handed pitchers
|
| 487 |
-
rhp <- game_complete %>% filter(phand == "R")
|
| 488 |
-
lhp <- game_complete %>% filter(phand == "L")
|
| 489 |
-
|
| 490 |
-
# Process right-handed pitchers by pitch type
|
| 491 |
-
if(nrow(rhp) > 0) {
|
| 492 |
-
# Split by pitch type
|
| 493 |
-
rhp_ff <- rhp %>% filter(pitch_name %in% c("Fastball","FourSeamFastBall"))
|
| 494 |
-
rhp_si <- rhp %>% filter(pitch_name %in% c("OneSeamFastBall","Sinker","TwoSeamFastBall"))
|
| 495 |
-
rhp_ct <- rhp %>% filter(pitch_name == "Cutter")
|
| 496 |
-
rhp_sl <- rhp %>% filter(pitch_name %in% c("Slider","Sweeper"))
|
| 497 |
-
rhp_cb <- rhp %>% filter(pitch_name == "Curveball")
|
| 498 |
-
rhp_ch_spl <- rhp %>% filter(pitch_name %in% c("Changeup", "ChangeUp","Splitter","Knuckleball"))
|
| 499 |
-
|
| 500 |
-
# Apply models for each pitch type with appropriate scaling
|
| 501 |
-
if(nrow(rhp_ff) > 0) {
|
| 502 |
-
rhp_ff$TimStuff <- scale_TimStuff(
|
| 503 |
-
predict(FF_model, as.matrix(cbind(
|
| 504 |
-
rhp_ff$start_speed, rhp_ff$IVB, rhp_ff$HB,
|
| 505 |
-
rhp_ff$z0, rhp_ff$x0, rhp_ff$extension))),
|
| 506 |
-
0.07666808, 0.02507584)
|
| 507 |
-
}
|
| 508 |
-
|
| 509 |
-
if(nrow(rhp_si) > 0) {
|
| 510 |
-
rhp_si$TimStuff <- scale_TimStuff(
|
| 511 |
-
predict(SI_model, as.matrix(cbind(
|
| 512 |
-
rhp_si$start_speed, rhp_si$IVB, rhp_si$HB,
|
| 513 |
-
rhp_si$z0, rhp_si$x0, rhp_si$extension))),
|
| 514 |
-
0.09427338, 0.01524531)
|
| 515 |
-
}
|
| 516 |
-
|
| 517 |
-
if(nrow(rhp_ct) > 0) {
|
| 518 |
-
rhp_ct$TimStuff <- scale_TimStuff(
|
| 519 |
-
predict(CT_model, as.matrix(cbind(
|
| 520 |
-
rhp_ct$start_speed, rhp_ct$IVB, rhp_ct$HB,
|
| 521 |
-
rhp_ct$z0, rhp_ct$x0, rhp_ct$extension))),
|
| 522 |
-
0.01484248, 0.0001241943)
|
| 523 |
-
}
|
| 524 |
-
|
| 525 |
-
if(nrow(rhp_sl) > 0) {
|
| 526 |
-
rhp_sl$TimStuff <- scale_TimStuff(
|
| 527 |
-
predict(SL_model, as.matrix(cbind(
|
| 528 |
-
rhp_sl$start_speed, rhp_sl$IVB, rhp_sl$HB,
|
| 529 |
-
rhp_sl$spin_rate, rhp_sl$z0, rhp_sl$x0, rhp_sl$extension))),
|
| 530 |
-
0.06669426, 0.01006894)
|
| 531 |
-
}
|
| 532 |
-
|
| 533 |
-
if(nrow(rhp_cb) > 0) {
|
| 534 |
-
rhp_cb$TimStuff <- scale_TimStuff(
|
| 535 |
-
predict(CB_model, as.matrix(cbind(
|
| 536 |
-
rhp_cb$start_speed, rhp_cb$IVB, rhp_cb$HB,
|
| 537 |
-
rhp_cb$spin_rate, rhp_cb$z0, rhp_cb$x0, rhp_cb$extension))),
|
| 538 |
-
0.07480712, 0.01038754)
|
| 539 |
-
}
|
| 540 |
-
|
| 541 |
-
if(nrow(rhp_ch_spl) > 0) {
|
| 542 |
-
rhp_ch_spl$TimStuff <- scale_TimStuff(
|
| 543 |
-
predict(CH_SPL_model, as.matrix(cbind(
|
| 544 |
-
rhp_ch_spl$start_speed, rhp_ch_spl$IVB, rhp_ch_spl$HB,
|
| 545 |
-
rhp_ch_spl$z0, rhp_ch_spl$x0, rhp_ch_spl$extension,
|
| 546 |
-
rhp_ch_spl$velo_diff, rhp_ch_spl$IVB_diff, rhp_ch_spl$HB_diff))),
|
| 547 |
-
0.09255855, 0.01739746)
|
| 548 |
-
}
|
| 549 |
-
|
| 550 |
-
# Combine all RHP pitch types
|
| 551 |
-
rhp <- rbind(rhp_ff, rhp_si, rhp_ct, rhp_sl, rhp_cb, rhp_ch_spl)
|
| 552 |
-
print("Rhp")
|
| 553 |
-
print(rhp)
|
| 554 |
}
|
| 555 |
|
| 556 |
-
|
| 557 |
-
|
| 558 |
-
|
| 559 |
-
|
| 560 |
-
|
| 561 |
-
|
| 562 |
-
|
| 563 |
-
|
| 564 |
-
lhp_ch_spl <- lhp %>% filter(pitch_name %in% c("Changeup", "ChangeUp","Splitter","Knuckleball"))
|
| 565 |
-
|
| 566 |
-
# Apply models for each pitch type with appropriate scaling
|
| 567 |
-
if(nrow(lhp_ff) > 0) {
|
| 568 |
-
lhp_ff$TimStuff <- scale_TimStuff(
|
| 569 |
-
predict(FF_model, as.matrix(cbind(
|
| 570 |
-
lhp_ff$start_speed, lhp_ff$IVB, lhp_ff$HB,
|
| 571 |
-
lhp_ff$z0, lhp_ff$x0, lhp_ff$extension))),
|
| 572 |
-
0.07666808, 0.02507584)
|
| 573 |
-
}
|
| 574 |
-
|
| 575 |
-
if(nrow(lhp_si) > 0) {
|
| 576 |
-
lhp_si$TimStuff <- scale_TimStuff(
|
| 577 |
-
predict(SI_model, as.matrix(cbind(
|
| 578 |
-
lhp_si$start_speed, lhp_si$IVB, lhp_si$HB,
|
| 579 |
-
lhp_si$z0, lhp_si$x0, lhp_si$extension))),
|
| 580 |
-
0.09427338, 0.01524531)
|
| 581 |
-
}
|
| 582 |
-
|
| 583 |
-
if(nrow(lhp_ct) > 0) {
|
| 584 |
-
lhp_ct$TimStuff <- scale_TimStuff(
|
| 585 |
-
predict(CT_model, as.matrix(cbind(
|
| 586 |
-
lhp_ct$start_speed, lhp_ct$IVB, lhp_ct$HB,
|
| 587 |
-
lhp_ct$z0, lhp_ct$x0, lhp_ct$extension))),
|
| 588 |
-
0.01484248, 0.0001241943)
|
| 589 |
-
}
|
| 590 |
-
|
| 591 |
-
if(nrow(lhp_sl) > 0) {
|
| 592 |
-
lhp_sl$TimStuff <- scale_TimStuff(
|
| 593 |
-
predict(SL_model, as.matrix(cbind(
|
| 594 |
-
lhp_sl$start_speed, lhp_sl$IVB, lhp_sl$HB,
|
| 595 |
-
lhp_sl$spin_rate, lhp_sl$z0, lhp_sl$x0, lhp_sl$extension))),
|
| 596 |
-
0.06669426, 0.01006894)
|
| 597 |
-
}
|
| 598 |
-
|
| 599 |
-
if(nrow(lhp_cb) > 0) {
|
| 600 |
-
lhp_cb$TimStuff <- scale_TimStuff(
|
| 601 |
-
predict(CB_model, as.matrix(cbind(
|
| 602 |
-
lhp_cb$start_speed, lhp_cb$IVB, lhp_cb$HB,
|
| 603 |
-
lhp_cb$spin_rate, lhp_cb$z0, lhp_cb$x0, lhp_cb$extension))),
|
| 604 |
-
0.07480712, 0.01038754)
|
| 605 |
-
}
|
| 606 |
-
|
| 607 |
-
if(nrow(lhp_ch_spl) > 0) {
|
| 608 |
-
lhp_ch_spl$TimStuff <- scale_TimStuff(
|
| 609 |
-
predict(CH_SPL_model, as.matrix(cbind(
|
| 610 |
-
lhp_ch_spl$start_speed, lhp_ch_spl$IVB, lhp_ch_spl$HB,
|
| 611 |
-
lhp_ch_spl$z0, lhp_ch_spl$x0, lhp_ch_spl$extension,
|
| 612 |
-
lhp_ch_spl$velo_diff, lhp_ch_spl$IVB_diff, lhp_ch_spl$HB_diff))),
|
| 613 |
-
0.09255855, 0.01739746)
|
| 614 |
-
}
|
| 615 |
-
|
| 616 |
-
# Combine all LHP pitch types
|
| 617 |
-
lhp <- rbind(lhp_ff, lhp_si, lhp_ct, lhp_sl, lhp_cb, lhp_ch_spl)
|
| 618 |
}
|
| 619 |
|
| 620 |
-
|
| 621 |
-
game_complete <- rbind(rhp, lhp, game_na)
|
| 622 |
-
|
| 623 |
-
return(game_complete)
|
| 624 |
}
|
| 625 |
summary_table <- function(game) {
|
| 626 |
game <- calculatetimstuffall(game)
|
|
|
|
| 48 |
t <- download_private_csv("TimStats/Passwords", "demo.csv")
|
| 49 |
pass <- t[1,1]
|
| 50 |
|
| 51 |
+
model <- xgb.load('TimStuff2.model')
|
| 52 |
|
| 53 |
# Helper functions
|
| 54 |
download_and_process_image <- function(url) {
|
|
|
|
| 408 |
return(df)
|
| 409 |
}
|
| 410 |
|
| 411 |
+
calculate_timstuff <- function(game) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 412 |
game <- game %>%
|
|
|
|
| 413 |
mutate(
|
| 414 |
+
VAA = calculate_VAA(vz0, ay, az, vy0, 50),
|
| 415 |
+
EAA = calculate_EAA(extension),
|
| 416 |
+
SADiff = calculate_SADiff(pfxX, pfxZ, spinDirection),
|
| 417 |
+
Pitch = pitch_name,
|
| 418 |
+
ishandL = ifelse(phand == "L", 1, 0)
|
| 419 |
)
|
| 420 |
+
|
| 421 |
+
feature_vars <- c("ishandL", "start_speed", "IVB", "HB", "EAA", "x0", "z0", "spin_rate", "SADiff")
|
|
|
|
| 422 |
complete_rows <- complete.cases(game[, feature_vars])
|
| 423 |
game_complete <- game[complete_rows, ]
|
| 424 |
game_na <- game[!complete_rows, ]
|
| 425 |
+
|
| 426 |
game_na <- if(any(!complete_rows)) {
|
| 427 |
na_rows <- game[!complete_rows, ]
|
| 428 |
na_rows$TimStuff <- NA
|
|
|
|
| 434 |
empty_df
|
| 435 |
}
|
| 436 |
|
| 437 |
+
if(nrow(game_complete) > 0) {
|
| 438 |
+
pred_matrix <- as.matrix(game_complete[, feature_vars])
|
| 439 |
+
predictions <- predict(model, pred_matrix)
|
| 440 |
+
game_complete$TimStuff <- scale_TimStuff(predictions, -0.002620635, 0.006021368)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 441 |
}
|
| 442 |
|
| 443 |
+
if(nrow(game_complete) > 0 && nrow(game_na) > 0) {
|
| 444 |
+
game_result <- rbind(game_complete, game_na)
|
| 445 |
+
} else if(nrow(game_complete) > 0) {
|
| 446 |
+
game_result <- game_complete
|
| 447 |
+
} else if(nrow(game_na) > 0) {
|
| 448 |
+
game_result <- game_na
|
| 449 |
+
} else {
|
| 450 |
+
game_result <- game
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 451 |
}
|
| 452 |
|
| 453 |
+
return(game_result)
|
|
|
|
|
|
|
|
|
|
| 454 |
}
|
| 455 |
summary_table <- function(game) {
|
| 456 |
game <- calculatetimstuffall(game)
|