Spaces:
Runtime error
Runtime error
| library(shiny) | |
| library(dplyr) | |
| library(data.table) | |
| library(xgboost) | |
| library(caret) | |
| library(shinythemes) | |
| calculate_timstuff <- function(data, pitch_type) { | |
| data_matrix <- as.matrix(data) | |
| if (pitch_type == "Offspeed") { | |
| mod <- xgb.load('Off.model') | |
| prediction <- predict(mod, data_matrix) | |
| timstuff <- (50 - (prediction - -0.002239657) / 0.01043216 * 10) | |
| } else { | |
| mod <- xgb.load('FB.model') | |
| prediction <- predict(mod, data_matrix) | |
| timstuff <- (50 - (prediction - -0.0011801) / 0.007989927 * 10) | |
| } | |
| return(timstuff) | |
| } | |
| ui <- fluidPage( | |
| theme = shinytheme("flatly"), | |
| # Application title | |
| titlePanel("TimStuff Fastball/Offspeed Calculator"), | |
| # Sidebar with inputs | |
| sidebarLayout( | |
| sidebarPanel( | |
| width = 4, | |
| radioButtons("pitch", "Pitch Type", choices = c("Fastball", "Offspeed"), inline = TRUE), | |
| radioButtons("phand", "Hand", choices = c("R", "L"), inline = TRUE), | |
| numericInput("velo", "Velocity (mph)", value = 90, min = 70, max = 110, step = 1), | |
| numericInput("ivb", "Induced Vertical Break (in)", value = 16, min = -20, max = 30, step = 0.1), | |
| numericInput("hb", "Horizontal Break (in)", value = 6, min = -20, max = 20, step = 0.1), | |
| numericInput("spinrate", "Spin Rate (rpm)", value = 2300, min = 1000, max = 3500, step = 10), | |
| numericInput("ext", "Extension (ft)", value = 6, min = 5, max = 8, step = 0.1), | |
| numericInput("spinaxisdiff", "Spin Axis Difference (°)", value = 0, min = -180, max = 180, step = 1), | |
| numericInput("x0", "Horizontal Release Point (ft)", value = 0, min = -5, max = 5, step = 0.1), | |
| numericInput("z0", "Vertical Release Point (ft)", value = 5, min = 3, max = 8, step = 0.1), | |
| selectInput("feature_to_vary", "Select Feature to Vary:", | |
| choices = c("Velocity" = "start_speed", | |
| "Induced Vertical Break" = "IVB", | |
| "Horizontal Break" = "HB", | |
| "Spin Rate" = "spin_rate", | |
| "Extension" = "EAA", | |
| "Spin Axis Difference" = "SADiff", | |
| "Horizontal Release Point" = "x0", | |
| "Vertical Release Point" = "z0")) | |
| ), | |
| # Main panel with output | |
| mainPanel( | |
| width = 8, | |
| wellPanel( | |
| h3("Results"), | |
| verbatimTextOutput("stuff"), | |
| plotOutput("feature_impact", height = "400px") # Placeholder for future visualization | |
| ) | |
| ) | |
| ) | |
| ) | |
| server <- function(input, output) { | |
| observeEvent(input$pitch, { | |
| output$stuff <- renderText({ | |
| data <- data.frame( | |
| start_speed = input$velo, | |
| IVB = input$ivb, | |
| HB = ifelse(input$phand == "L", -input$hb, input$hb), | |
| EAA = input$ext / 6.3, | |
| x0 = ifelse(input$phand == "L", -input$x0, input$x0), | |
| z0 = input$z0, | |
| spin_rate = input$spinrate, | |
| SADiff = input$spinaxisdiff | |
| ) | |
| data <- as.matrix(data) | |
| if (input$pitch == "Offspeed") { | |
| mod <- xgb.load('Off.model') | |
| prediction <- predict(mod, data) | |
| TimStuff <- (50 - (prediction - -0.002239657) / 0.01043216 * 10) | |
| } else { | |
| mod <- xgb.load('FB.model') | |
| prediction <- predict(mod, data) | |
| TimStuff <- (50 - (prediction - -0.0011801) / 0.007989927 * 10) | |
| } | |
| paste("TimStuff:", round(TimStuff, 2), "\n20-80 Scale, 50 is Average, 1 SD is 10") | |
| }) | |
| # Add this new reactive expression | |
| # Add this new reactive expression | |
| feature_range <- reactive({ | |
| ranges <- list( | |
| start_speed = c(70, 110), | |
| IVB = c(-20, 30), | |
| HB = c(-20, 20), | |
| spin_rate = c(1000, 3500), | |
| EAA = c(5/6.3, 8/6.3), | |
| SADiff = c(-180, 180), | |
| x0 = c(-5, 5), | |
| z0 = c(3, 8) | |
| ) | |
| ranges[[input$feature_to_vary]] | |
| }) | |
| # Update the feature_impact plot | |
| output$feature_impact <- renderPlot({ | |
| # Create base data frame with current inputs | |
| base_data <- data.frame( | |
| start_speed = input$velo, | |
| IVB = input$ivb, | |
| HB = ifelse(input$phand == "L", -input$hb, input$hb), | |
| EAA = input$ext / 6.3, | |
| x0 = ifelse(input$phand == "L", -input$x0, input$x0), | |
| z0 = input$z0, | |
| spin_rate = input$spinrate, | |
| SADiff = input$spinaxisdiff | |
| ) | |
| # Generate sequence for the selected feature | |
| feature_seq <- seq(feature_range()[1], feature_range()[2], length.out = 100) | |
| # Calculate TimStuff for the sequence | |
| varied_data <- do.call(rbind, replicate(100, base_data, simplify = FALSE)) | |
| varied_data[[input$feature_to_vary]] <- feature_seq | |
| timstuff <- calculate_timstuff(varied_data, input$pitch) | |
| # Create plot data | |
| plot_data <- data.frame( | |
| Feature = names(base_data)[which(names(base_data) == input$feature_to_vary)], | |
| Value = feature_seq, | |
| TimStuff = timstuff | |
| ) | |
| # Create plot | |
| ggplot(plot_data, aes(x = Value, y = TimStuff)) + | |
| geom_line(color = "blue", size = 1) + | |
| geom_point(aes(x = base_data[[input$feature_to_vary]], | |
| y = calculate_timstuff(base_data, input$pitch)), | |
| color = "red", size = 3) + | |
| theme_minimal() + | |
| ylim(0,100) + | |
| labs(title = paste("Impact of", input$feature_to_vary, "on TimStuff"), | |
| x = input$feature_to_vary, y = "TimStuff") + | |
| theme(text = element_text(size = 14)) | |
| }) | |
| }) | |
| } | |
| # Run the application | |
| shinyApp(ui = ui, server = server) | |