library(shiny) library(gt) library(dplyr) library(shinyjs) library(shinyauthr) library(httr) library(bslib) download_private_csv <- function(repo_id, filename) { url <- paste0("https://huggingface.co/datasets/", repo_id, "/resolve/main/", filename) response <- GET(url, add_headers(Authorization = paste("Bearer", Sys.getenv("GETCSV")))) if (status_code(response) == 200) { content <- content(response, "text") con <- textConnection(content) # Try different read options data <- read.csv(con, header = TRUE, check.names = FALSE, # This prevents R from modifying column names fileEncoding = "UTF-8", stringsAsFactors = FALSE) close(con) return(data) } else { stop("Failed to download dataset") } } Beam <- download_private_csv("TimStats/CollegePriv", "College24.csv") TMP <- download_private_csv("TimStats/CollegePriv", "TMP.csv") TMB <- download_private_csv("TimStats/CollegePriv", "TMB.csv") test <- Beam %>% select(Date,PitchofPA,Pitcher,PitcherId,PitcherThrows,PitcherTeam,Batter,BatterId, BatterSide,BatterTeam,Inning,`Top/Bottom`,Outs,Balls,Strikes,TaggedPitchType, AutoPitchType,PitchCall,TaggedHitType,KorBB,PlayResult,OutsOnPlay,RunsScored, RelSpeed,VertRelAngle,HorzRelAngle,SpinRate,SpinAxis,Tilt,RelHeight,RelSide, Extension,InducedVertBreak,HorzBreak,PlateLocHeight,PlateLocSide,VertApprAngle, HorzApprAngle,ExitSpeed,Angle,Direction,Distance,pfxx,pfxz,x0,z0,vx0,vy0,vz0, ax0,ay0,az0,Level,League,ContactPositionX,ContactPositionY,ContactPositionZ, SpinAxis3dTransverseAngle,SpinAxis3dLongitudinalAngle,SpinAxis3dTilt, SpinAxis3dSpinEfficiency,SpinAxis3dSeamOrientationRotationX, SpinAxis3dSeamOrientationRotationY,SpinAxis3dSeamOrientationRotationZ) test <- test %>% mutate("Hit" = case_when(PlayResult %in% c("Single","Double","Triple","HomeRun") ~ TRUE,TRUE ~ FALSE), "CallStrike" = case_when(PitchCall %in% c("StrikeCalled") ~ TRUE, TRUE ~ FALSE), "Whiff" = case_when(PitchCall %in% c("StrikeSwinging") ~ TRUE, TRUE ~ FALSE), "CSW" = CallStrike + Whiff, "Contact" = case_when(PitchCall %in% c("FoulBall","FoulBallNotFieldable","InPlay") ~ TRUE, TRUE ~ FALSE), "GB" = case_when(TaggedHitType %in% c('GroundBall') ~ TRUE, TRUE ~ FALSE), "LD" = case_when(TaggedHitType %in% c('LineDrive') ~ TRUE, TRUE ~ FALSE), "FB" = case_when(TaggedHitType %in% c ("FlyBall") ~ TRUE, TRUE ~ FALSE), "PopU" = case_when(TaggedHitType %in% c ("Popup") ~ TRUE, TRUE ~ FALSE), "Swing" = Whiff + Contact, "BBE" = GB + LD + FB + PopU, "HardHit" = ifelse(ExitSpeed >= 95,TRUE,FALSE), "Ball" = case_when(PitchCall %in% c("BallCalled","BallinDirt") ~ TRUE, TRUE ~ FALSE), "Single" = case_when(PlayResult %in% c("Single") ~ TRUE, TRUE ~ FALSE), "Double" = case_when(PlayResult %in% c("Double") ~ TRUE, TRUE ~ FALSE), "Triple" = case_when(PlayResult %in% c("Triple") ~ TRUE, TRUE ~ FALSE), "HR" = case_when(PlayResult %in% c("HomeRun") ~ TRUE, TRUE ~ FALSE), "Sac" = case_when(PlayResult %in% c("Sacrifice") ~ TRUE, TRUE ~ FALSE), "HBP" = case_when(PitchCall %in% c("HitByPitch") ~ TRUE, TRUE ~ FALSE), "Error" = case_when(PlayResult %in% c("Error") ~ TRUE, TRUE ~ FALSE), "FC"= case_when(PlayResult %in% c("FieldersChoice") ~ TRUE, TRUE ~ FALSE), "Out" = case_when(PlayResult %in% c ("Out") ~ TRUE, TRUE ~ FALSE), "BIP" = Single + Double + Triple + HR + Sac + Error + Out + FC, "Count" = paste0(Balls,"-",Strikes), "BSituation" = ifelse(Balls > Strikes,"Ahead",NA), "BSituation" = ifelse(Balls < Strikes,"Behind",BSituation), "BSituation" = ifelse(Balls == Strikes,"Even",BSituation), "PSituation" = ifelse(Balls < Strikes,"Ahead",NA), "PSituation" = ifelse(Balls > Strikes,"Behind",PSituation), "PSituation" = ifelse(Balls == Strikes,"Even",PSituation), "Strikeout" = ifelse(KorBB == "Strikeout",TRUE,FALSE), "Walk" = ifelse(KorBB == "Walk",TRUE,FALSE), "Zone" = case_when(between(PlateLocSide,-.825,.825) & between(PlateLocHeight,1.45,3.45) ~ TRUE, TRUE ~ FALSE), "AB" = Strikeout + BIP - Sac, "PA" = Strikeout + BIP + Walk + HBP ) test <- test %>% left_join(TMB, by = c(BatterTeam = "team_abbr")) %>% left_join(TMP, by = c(PitcherTeam = "team_abbr")) %>% mutate(PitcherAndTeam = paste0(Pitcher," - ",PTeamName)) %>% mutate(BatterAndTeam = paste0(Batter," - ",BTeamName)) gt_theme_tim <- function(gt_object,...) { stopifnot(`'gt_object' must be a 'gt_tbl', have you accidentally passed raw data?` = "gt_tbl" %in% class(gt_object)) table_id <- subset(gt_object[['_options']], parameter == 'table_id')$value[[1]] if (is.na(table_id)) { table_id <- gt::random_id() opt_position <- which("table_id" %in% gt_object[["_options"]][["parameter"]])[[1]] gt_object[["_options"]][["value"]][[opt_position]] <- table_id } gt_object %>% # cell body gt::tab_style( locations = gt::cells_body(), style = gt::cell_text(font = "Arial", size = px(14)) ) %>% # col. headers gt::tab_style( locations = gt::cells_column_labels(), style = gt::cell_text(weight = 'bold', font = "Arial", size = px(14)) ) %>% # group rows gt::tab_style( locations = gt::cells_row_groups(), style = list( gt::cell_text(font = "Arial", weight = 650, size = px(14), color = "#FFFDF5"), gt::cell_fill(color = "#000000") ) ) %>% # footnote gt::tab_style( locations = gt::cells_footnotes(), style = gt::cell_text(font = "Arial", size = px(12)) ) %>% # title gt::tab_style( locations = gt::cells_title('title'), style = gt::cell_text(weight = 'bold', font = "Arial", size = px(18)) ) %>% # subtitle gt::tab_style( locations = gt::cells_title('subtitle'), style = gt::cell_text(font = "Arial", size = px(14)) ) %>% # caption gt::tab_style( locations = gt::cells_source_notes(), style = gt::cell_text(font = "Arial", size = px(12)) ) %>% # spanner gt::tab_style( locations = gt::cells_column_spanners(), style = gt::cell_text(font = "Arial", weight = 650, size = px(8)) ) %>% gt::tab_options( data_row.padding = 1, table_body.hlines.color = "transparent", column_labels.border.top.color = 'black', column_labels.border.top.width = px(1), column_labels.border.bottom.style = 'none', #column_labels.background.color = "orange", row_group.border.top.style = "none", row_group.border.top.color = "black", row_group.border.bottom.width = px(1), row_group.border.bottom.color = "black", row_group.border.bottom.style = 'solid', row_group.padding = px(1.5), heading.align = 'center', heading.border.bottom.style = "none", table_body.border.top.style = "none", table_body.border.bottom.color = "white", table.border.bottom.style = 'none', table.border.top.style = 'none', source_notes.border.lr.style = "none", ... ) %>% gt::opt_row_striping() } user_base <- tibble::tibble( user = c(Sys.getenv("Username")), password = (c(Sys.getenv("Password"))), permissions = c("admin"), name = c("User One") ) # Define UI for application that draws a histogram ui <- fluidPage( tags$head( tags$style( HTML(" .shiny-output-error { visibility: hidden; } .shiny-output-error:before { visibility: hidden; } ") ) ), div(class = "pull-right", shinyauthr::logoutUI(id = "logout")), shinyauthr::loginUI(id = "login"), div( id = "bar", titlePanel("TimMedia"), sidebarLayout( sidebarPanel( uiOutput("dynamicSelect"), # Replace selectInput with uiOutput dateRangeInput("date","Date Range:",start = "2024-01-01"), imageOutput("teamLogo", height = "150px"), width = 3 ), mainPanel( tabsetPanel(id = "tabs", # Add id here tabPanel("Pitcher Splits", gt_output("CountFilterP"), gt_output("PitchFilterP"), gt_output("PitchSideFilterP"), gt_output("InningFilterP"), gt_output("SideFilterP") ), tabPanel("Batter Splits", gt_output("CountFilterB"), gt_output("PitchFilterB"), gt_output("PitchSideFilterB"), gt_output("InningFilterB"), gt_output("SideFilterB") ) ), width = 9 ) ) ) %>% shinyjs::hidden() ) # Then in the server, add these new reactive elements: server <- function(input, output, session) { options(shiny.sanitize.errors = TRUE) # Add this reactive element playerType <- reactive({ if(input$tabs == "Pitcher Splits") { list( choices = unique(test$PitcherAndTeam), selected = NULL, logo_column = "PTeamLogo", filter_column = "PitcherAndTeam" ) } else { list( choices = unique(test$BatterAndTeam), selected = NULL, logo_column = "BTeamLogo", filter_column = "BatterAndTeam" ) } }) # Create dynamic select input output$dynamicSelect <- renderUI({ selectInput("player", "Select Player", choices = playerType()$choices) }) # Modify the team logo render output$teamLogo <- renderImage({ req(input$player) selected_logo <- test %>% filter(!!sym(playerType()$filter_column) == input$player) %>% slice(1) %>% pull(!!sym(playerType()$logo_column)) temp_file <- tempfile(fileext = ".png") download.file(selected_logo, temp_file, mode = "wb") list( src = temp_file, contentType = "image/png", width = "150px", height = "150px", alt = "Team Logo", deleteFile = TRUE, style = "display: block; margin: auto;" ) }, deleteFile = TRUE) credentials <- shinyauthr::loginServer( id = "login", data = user_base, user_col = user, pwd_col = password, sodium_hashed = FALSE, log_out = reactive(logout_init()) ) # Logout to hide logout_init <- shinyauthr::logoutServer( id = "logout", active = reactive(credentials()$user_auth) ) observe({ if (credentials()$user_auth) { shinyjs::show(id = "bar") } else { shinyjs::hide(id = "bar") } }) output$CountFilterP <- render_gt({ t <- test %>% filter(PitcherAndTeam == input$player) %>% group_by(Count) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE))%>% ungroup() tt <- test %>% mutate(Count = PSituation) %>% filter(PitcherAndTeam == input$player) %>% group_by(Count) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE)) %>% ungroup() test <- rbind(tt,t) test %>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`,decimals = 1) %>% cols_width(Count:Pitches ~ px(70), everything() ~ px(85)) %>% cols_align(align = "center") %>% fmt_number(columns = AVG:SLG,decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% #gt_theme_savant() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$PitchFilterP <- render_gt({ test %>% filter(PitcherAndTeam == input$player) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% group_by(AutoPitchType) %>% summarise( Pitches = n(), # BBE = sum(BBE,na.rm = TRUE), "Usage%" = n() / nrow(.), # Added Usage% calculation "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW, na.rm = TRUE), "Zone%" = mean(Zone, na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE], na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE], na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE], na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE], na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE], na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE], .9, na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE], na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`), NA, `Max EV`), "GB%" = mean(GB[BBE == TRUE], na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE], na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE], na.rm = TRUE), "AVG" = round(sum(Hit, na.rm = TRUE) / sum(AB, na.rm = TRUE), digits = 3), "OBP" = round((sum(Hit, na.rm = TRUE) + sum(Walk, na.rm = TRUE) + sum(HBP, na.rm = TRUE)) / sum(PA, na.rm = TRUE), digits = 3), "SLG" = (round(sum(Single, na.rm = TRUE) + sum(Double, na.rm = TRUE) * 2 + sum(Triple, na.rm = TRUE) * 3 + sum(HR, na.rm = TRUE))) / sum(AB, na.rm = TRUE) ) %>% ungroup() %>% arrange(desc(Pitches)) %>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`, decimals = 1) %>% cols_label(AutoPitchType = "Type") %>% cols_width( AutoPitchType ~ px(100), Pitches ~ px(70), everything() ~ px(85) ) %>% cols_align(align = "center") %>% fmt_number(columns = AVG:SLG, decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$PitchSideFilterP <- render_gt({ test %>% filter(PitcherAndTeam == input$player) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% group_by(BatterSide) %>% mutate(total_side = n()) %>% ungroup() %>% group_by(AutoPitchType, BatterSide) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Usage%" = (n() / first(total_side)), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW, na.rm = TRUE), "Zone%" = mean(Zone, na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE], na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE], na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE], na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE], na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE], na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE], .9, na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE], na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`), NA, `Max EV`), "GB%" = mean(GB[BBE == TRUE], na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE], na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE], na.rm = TRUE), "AVG" = round(sum(Hit, na.rm = TRUE) / sum(AB, na.rm = TRUE), digits = 3), "OBP" = round((sum(Hit, na.rm = TRUE) + sum(Walk, na.rm = TRUE) + sum(HBP, na.rm = TRUE)) / sum(PA, na.rm = TRUE), digits = 3), "SLG" = (round(sum(Single, na.rm = TRUE) + sum(Double, na.rm = TRUE) * 2 + sum(Triple, na.rm = TRUE) * 3 + sum(HR, na.rm = TRUE))) / sum(AB, na.rm = TRUE) ) %>% ungroup() %>% arrange(desc(BatterSide),desc(Pitches)) %>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`, decimals = 1) %>% cols_label(AutoPitchType = "Type", BatterSide = "Side") %>% cols_width( AutoPitchType ~ px(100), Pitches ~ px(70), BatterSide ~ px(70), everything() ~ px(85) ) %>% cols_align(align = "center") %>% fmt_number(columns = AVG:SLG, decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$InningFilterP <- render_gt({ test %>% filter(PitcherAndTeam == input$player) %>% group_by(Inning) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE))%>% ungroup()%>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`,decimals = 1) %>% cols_width(Inning:Pitches ~ px(70), everything() ~ px(85)) %>% cols_align(align = "center") %>% fmt_number(columns = AVG:SLG,decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% #gt_theme_savant() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$SideFilterP <- render_gt({ test1 <- test %>% filter(PitcherAndTeam == input$player) %>% group_by(BatterSide) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE))%>% ungroup() test2 <- test %>% mutate(BatterSide = "Both") %>% filter(PitcherAndTeam == input$player) %>% group_by(BatterSide) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE))%>% ungroup() test <- rbind(test1,test2) test %>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`,decimals = 1) %>% cols_width(BatterSide:Pitches ~ px(70), everything() ~ px(85)) %>% cols_align(align = "center") %>% cols_label(BatterSide = "Side") %>% fmt_number(columns = AVG:SLG,decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% #gt_theme_savant() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$slashlineP <- render_gt({ test %>% filter(PitcherAndTeam == input$player) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), `1B` = sum(Single,na.rm = TRUE), `2B` = sum(Double,na.rm = TRUE), `3B` = sum(Triple,na.rm = TRUE), HR = sum(HR,na.rm = TRUE), SO = sum(Strikeout,na.rm = TRUE), BB = sum(Walk,na.rm = TRUE), Whiffs = sum(Whiff,na.rm = TRUE), `Hard Hits` = sum(HardHit,na.rm = TRUE) )%>% ungroup()%>% gt() %>% gt_theme_tim() %>% cols_align(align = "center") %>% # gt_theme_savant() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$CountFilterB <- render_gt({ t <- test %>% filter(BatterAndTeam == input$player) %>% group_by(Count) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE))%>% ungroup() tt <- test %>% mutate(Count = BSituation) %>% filter(BatterAndTeam == input$player) %>% group_by(Count) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE))%>% ungroup() test <- rbind(tt,t) test %>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`,decimals = 1) %>% cols_width(Count:Pitches ~ px(70), everything() ~ px(85)) %>% cols_align(align = "center") %>% fmt_number(columns = AVG:SLG,decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% #gt_theme_savant() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$PitchFilterB <- render_gt({ test %>% filter(BatterAndTeam == input$player) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% group_by(AutoPitchType) %>% summarise( Pitches = n(), # BBE = sum(BBE,na.rm = TRUE), "Pitch%" = n() / nrow(.), # Added Pitch% calculation "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW, na.rm = TRUE), "Zone%" = mean(Zone, na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE], na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE], na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE], na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE], na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE], na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE], .9, na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE], na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`), NA, `Max EV`), "GB%" = mean(GB[BBE == TRUE], na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE], na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE], na.rm = TRUE), "AVG" = round(sum(Hit, na.rm = TRUE) / sum(AB, na.rm = TRUE), digits = 3), "OBP" = round((sum(Hit, na.rm = TRUE) + sum(Walk, na.rm = TRUE) + sum(HBP, na.rm = TRUE)) / sum(PA, na.rm = TRUE), digits = 3), "SLG" = (round(sum(Single, na.rm = TRUE) + sum(Double, na.rm = TRUE) * 2 + sum(Triple, na.rm = TRUE) * 3 + sum(HR, na.rm = TRUE))) / sum(AB, na.rm = TRUE) ) %>% ungroup() %>% arrange(desc(Pitches)) %>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`, decimals = 1) %>% cols_label(AutoPitchType = "Type") %>% cols_width( AutoPitchType ~ px(100), Pitches ~ px(70), everything() ~ px(85) ) %>% cols_align(align = "center") %>% fmt_number(columns = AVG:SLG, decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$PitchSideFilterB <- render_gt({ test %>% filter(BatterAndTeam == input$player) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% group_by(PitcherThrows) %>% mutate(total_side = n()) %>% ungroup() %>% group_by(AutoPitchType, PitcherThrows) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Pitch%" = (n() / first(total_side)), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW, na.rm = TRUE), "Zone%" = mean(Zone, na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE], na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE], na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE], na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE], na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE], na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE], .9, na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE], na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`), NA, `Max EV`), "GB%" = mean(GB[BBE == TRUE], na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE], na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE], na.rm = TRUE), "AVG" = round(sum(Hit, na.rm = TRUE) / sum(AB, na.rm = TRUE), digits = 3), "OBP" = round((sum(Hit, na.rm = TRUE) + sum(Walk, na.rm = TRUE) + sum(HBP, na.rm = TRUE)) / sum(PA, na.rm = TRUE), digits = 3), "SLG" = (round(sum(Single, na.rm = TRUE) + sum(Double, na.rm = TRUE) * 2 + sum(Triple, na.rm = TRUE) * 3 + sum(HR, na.rm = TRUE))) / sum(AB, na.rm = TRUE) ) %>% ungroup() %>% arrange(desc(PitcherThrows),desc(Pitches)) %>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`, decimals = 1) %>% cols_label(AutoPitchType = "Type", PitcherThrows = "Hand") %>% cols_width( AutoPitchType ~ px(100), Pitches ~ px(70), PitcherThrows ~ px(70), everything() ~ px(85) ) %>% cols_align(align = "center") %>% fmt_number(columns = AVG:SLG, decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$InningFilterB <- render_gt({ test %>% filter(BatterAndTeam == input$player) %>% group_by(Inning) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE))%>% ungroup()%>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`,decimals = 1) %>% cols_width(Inning:Pitches ~ px(70), everything() ~ px(85)) %>% cols_align(align = "center") %>% fmt_number(columns = AVG:SLG,decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% #gt_theme_savant() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$SideFilterB <- render_gt({ test1 <- test %>% filter(BatterAndTeam == input$player) %>% group_by(PitcherThrows) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE))%>% ungroup() test2 <- test %>% mutate(PitcherThrows = "Both") %>% filter(BatterAndTeam == input$player) %>% group_by(PitcherThrows) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), #BBE = sum(BBE,na.rm = TRUE), "Swings" = sum(Swing,na.rm = TRUE), "Whiff%" = mean(Whiff[Swing == TRUE],na.rm = TRUE), "SwStr%" = mean(Whiff,na.rm = TRUE), "CSW%" = mean(CSW,na.rm = TRUE), "Zone%" = mean(Zone,na.rm = TRUE), "ZCon%" = mean(Contact[Zone == TRUE & Swing == TRUE],na.rm = TRUE), "ZSwing%" = mean(Swing[Zone == TRUE],na.rm = TRUE), "OCon%" = mean(Contact[Zone == FALSE & Swing == TRUE],na.rm = TRUE), "OSwing%" = mean(Swing[Zone == FALSE],na.rm = TRUE), "Avg EV" = mean(ExitSpeed[BBE == TRUE],na.rm = TRUE), "EV90" = quantile(ExitSpeed[BBE == TRUE],.9,na.rm = TRUE), "Max EV" = max(ExitSpeed[BBE == TRUE],na.rm = TRUE), "Max EV" = ifelse(is.infinite(`Max EV`),NA,`Max EV`), "GB%" = mean(GB[BBE == TRUE],na.rm = TRUE), "LD%" = mean(LD[BBE == TRUE],na.rm = TRUE), "FB%" = mean(FB[BBE == TRUE],na.rm = TRUE), "AVG" = round(sum(Hit,na.rm = TRUE) / sum(AB,na.rm = TRUE),digits = 3), "OBP" = round((sum(Hit,na.rm = TRUE) + sum(Walk,na.rm = TRUE) + sum(HBP,na.rm = TRUE))/ sum(PA,na.rm = TRUE),digits = 3), "SLG" = (round(sum(Single,na.rm = TRUE) + sum(Double,na.rm = TRUE) * 2 + sum(Triple,na.rm = TRUE) * 3 + sum(HR,na.rm = TRUE)))/sum(AB,na.rm = TRUE))%>% ungroup() test <- rbind(test1,test2) test %>% gt() %>% gt_theme_tim() %>% fmt_number(columns = `Avg EV`:`Max EV`,decimals = 1) %>% cols_width(PitcherThrows:Pitches ~ px(70), everything() ~ px(85)) %>% cols_align(align = "center") %>% cols_label(PitcherThrows = "Hand") %>% fmt_number(columns = AVG:SLG,decimals = 3) %>% fmt_percent(columns = ends_with("%")) %>% sub_missing() %>% #gt_theme_savant() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) output$slashlineB <- render_gt({ test %>% filter(BatterAndTeam == input$player) %>% filter(between(as.Date(Date),input$date[1],input$date[2])) %>% summarise( Pitches = n(), `1B` = sum(Single,na.rm = TRUE), `2B` = sum(Double,na.rm = TRUE), `3B` = sum(Triple,na.rm = TRUE), HR = sum(HR,na.rm = TRUE), SO = sum(Strikeout,na.rm = TRUE), BB = sum(Walk,na.rm = TRUE), Whiffs = sum(Whiff,na.rm = TRUE), `Hard Hits` = sum(HardHit,na.rm = TRUE) )%>% ungroup()%>% gt() %>% gt_theme_tim() %>% cols_align(align = "center") %>% # gt_theme_savant() %>% opt_interactive( use_compact_mode = TRUE, use_pagination = FALSE ) }) } # Run the application shinyApp(ui = ui, server = server)