igroffman commited on
Commit
1a9e12a
Β·
verified Β·
1 Parent(s): 3b60a4b

Update app.R

Browse files
Files changed (1) hide show
  1. app.R +38 -20
app.R CHANGED
@@ -778,42 +778,60 @@ server <- function(input, output, session) {
778
  TaggedPitchType %in% c("OneSeamFastBall", "TwoSeamFastBall", "Sinker", "Two-Seam", "One-Seam") ~ "Sinker",
779
  TaggedPitchType %in% c("ChangeUp", "Changeup") ~ "Changeup",
780
  TRUE ~ TaggedPitchType
781
- )
782
- ) %>%
783
- mutate(
784
  # Create necessary indicator variables if they don't exist
785
- in_zone = if ("StrikeZoneIndicator" %in% names(.)) StrikeZoneIndicator else
786
- ifelse(!is.na(PlateLocSide) & !is.na(PlateLocHeight) &
787
- PlateLocSide >= -0.95 & PlateLocSide <= 0.95 &
788
- PlateLocHeight >= 1.6 & PlateLocHeight <= 3.5, 1, 0),
789
- is_swing = ifelse(!is.na(PitchCall) &
790
- PitchCall %in% c("StrikeSwinging", "FoulBall", "FoulBallNotFieldable", "FoulBallFieldable", "InPlay"), 1, 0),
791
- is_whiff = if ("WhiffIndicator" %in% names(.)) WhiffIndicator else
792
- ifelse(!is.na(PitchCall) & PitchCall == "StrikeSwinging", 1, 0),
793
- chase = if ("Chaseindicator" %in% names(.)) Chaseindicator else
794
- ifelse(!is.na(PitchCall) & !is.na(PlateLocSide) & !is.na(PlateLocHeight) &
795
- PitchCall %in% c("StrikeSwinging", "FoulBallNotFieldable", "FoulBall", "InPlay") &
796
- (PlateLocSide < -0.95 | PlateLocSide > 0.95 | PlateLocHeight < 1.6 | PlateLocHeight > 3.5), 1, 0)
 
 
 
 
 
 
 
 
 
 
 
797
  )
798
 
799
  # Calculate total pitches for usage percentage
800
  total_pitches <- nrow(movement_stats)
801
 
 
 
 
 
 
802
  summary_stats <- movement_stats %>%
803
  group_by(`Pitch Type` = pitch_group) %>%
804
  summarise(
805
  Count = n(),
806
  `Usage%` = sprintf("%.1f%%", (n() / total_pitches) * 100),
807
- `Ext.` = if ("Extension" %in% names(.)) sprintf("%.1f", mean(Extension, na.rm = TRUE)) else "β€”",
808
  `Avg Velo` = sprintf("%.1f mph", mean(RelSpeed, na.rm = TRUE)),
809
  `90th Velo` = sprintf("%.1f mph", quantile(RelSpeed, 0.9, na.rm = TRUE)),
810
  `Max Velo` = sprintf("%.1f mph", max(RelSpeed, na.rm = TRUE)),
811
  `Avg IVB` = sprintf("%.1f in", mean(InducedVertBreak, na.rm = TRUE)),
812
  `Avg HB` = sprintf("%.1f in", mean(HorzBreak, na.rm = TRUE)),
813
- `Avg Spin` = if ("SpinRate" %in% names(.)) sprintf("%.0f rpm", mean(SpinRate, na.rm = TRUE)) else "β€”",
814
- `Rel Height` = if ("RelHeight" %in% names(.)) sprintf("%.1f", mean(RelHeight, na.rm = TRUE)) else "β€”",
815
  `Zone%` = sprintf("%.1f%%", round(mean(in_zone, na.rm = TRUE) * 100, 1)),
816
- `Whiff%` = sprintf("%.1f%%", round(sum(is_whiff, na.rm = TRUE) / sum(is_swing, na.rm = TRUE) * 100, 1)),
 
 
 
 
817
  `Chase%` = sprintf("%.1f%%", round(mean(chase, na.rm = TRUE) * 100, 1)),
818
  .groups = "drop"
819
  ) %>%
@@ -959,5 +977,5 @@ server <- function(input, output, session) {
959
  }
960
  )
961
  }
962
-
963
  shinyApp(ui = ui, server = server)
 
778
  TaggedPitchType %in% c("OneSeamFastBall", "TwoSeamFastBall", "Sinker", "Two-Seam", "One-Seam") ~ "Sinker",
779
  TaggedPitchType %in% c("ChangeUp", "Changeup") ~ "Changeup",
780
  TRUE ~ TaggedPitchType
781
+ ),
 
 
782
  # Create necessary indicator variables if they don't exist
783
+ in_zone = case_when(
784
+ "StrikeZoneIndicator" %in% names(.) ~ StrikeZoneIndicator,
785
+ !is.na(PlateLocSide) & !is.na(PlateLocHeight) &
786
+ PlateLocSide >= -0.95 & PlateLocSide <= 0.95 &
787
+ PlateLocHeight >= 1.6 & PlateLocHeight <= 3.5 ~ 1,
788
+ TRUE ~ 0
789
+ ),
790
+ is_swing = case_when(
791
+ !is.na(PitchCall) & PitchCall %in% c("StrikeSwinging", "FoulBall", "FoulBallNotFieldable", "FoulBallFieldable", "InPlay") ~ 1,
792
+ TRUE ~ 0
793
+ ),
794
+ is_whiff = case_when(
795
+ "WhiffIndicator" %in% names(.) ~ WhiffIndicator,
796
+ !is.na(PitchCall) & PitchCall == "StrikeSwinging" ~ 1,
797
+ TRUE ~ 0
798
+ ),
799
+ chase = case_when(
800
+ "Chaseindicator" %in% names(.) ~ Chaseindicator,
801
+ !is.na(PitchCall) & !is.na(PlateLocSide) & !is.na(PlateLocHeight) &
802
+ PitchCall %in% c("StrikeSwinging", "FoulBallNotFieldable", "FoulBall", "InPlay") &
803
+ (PlateLocSide < -0.95 | PlateLocSide > 0.95 | PlateLocHeight < 1.6 | PlateLocHeight > 3.5) ~ 1,
804
+ TRUE ~ 0
805
+ )
806
  )
807
 
808
  # Calculate total pitches for usage percentage
809
  total_pitches <- nrow(movement_stats)
810
 
811
+ # Check if required columns exist
812
+ has_extension <- "Extension" %in% names(movement_stats)
813
+ has_spinrate <- "SpinRate" %in% names(movement_stats)
814
+ has_relheight <- "RelHeight" %in% names(movement_stats)
815
+
816
  summary_stats <- movement_stats %>%
817
  group_by(`Pitch Type` = pitch_group) %>%
818
  summarise(
819
  Count = n(),
820
  `Usage%` = sprintf("%.1f%%", (n() / total_pitches) * 100),
821
+ `Ext.` = if (has_extension) sprintf("%.1f", mean(Extension, na.rm = TRUE)) else "β€”",
822
  `Avg Velo` = sprintf("%.1f mph", mean(RelSpeed, na.rm = TRUE)),
823
  `90th Velo` = sprintf("%.1f mph", quantile(RelSpeed, 0.9, na.rm = TRUE)),
824
  `Max Velo` = sprintf("%.1f mph", max(RelSpeed, na.rm = TRUE)),
825
  `Avg IVB` = sprintf("%.1f in", mean(InducedVertBreak, na.rm = TRUE)),
826
  `Avg HB` = sprintf("%.1f in", mean(HorzBreak, na.rm = TRUE)),
827
+ `Avg Spin` = if (has_spinrate) sprintf("%.0f rpm", mean(SpinRate, na.rm = TRUE)) else "β€”",
828
+ `Rel Height` = if (has_relheight) sprintf("%.1f", mean(RelHeight, na.rm = TRUE)) else "β€”",
829
  `Zone%` = sprintf("%.1f%%", round(mean(in_zone, na.rm = TRUE) * 100, 1)),
830
+ `Whiff%` = if(sum(is_swing, na.rm = TRUE) > 0) {
831
+ sprintf("%.1f%%", round(sum(is_whiff, na.rm = TRUE) / sum(is_swing, na.rm = TRUE) * 100, 1))
832
+ } else {
833
+ "β€”"
834
+ },
835
  `Chase%` = sprintf("%.1f%%", round(mean(chase, na.rm = TRUE) * 100, 1)),
836
  .groups = "drop"
837
  ) %>%
 
977
  }
978
  )
979
  }
980
+ # Run the app
981
  shinyApp(ui = ui, server = server)