TimStats commited on
Commit
2fdd1b2
·
verified ·
1 Parent(s): 34a7e32

Update app.R

Browse files
Files changed (1) hide show
  1. app.R +124 -83
app.R CHANGED
@@ -3,112 +3,153 @@ library(dplyr)
3
  library(data.table)
4
  library(xgboost)
5
  library(caret)
6
- # Define UI for application that draws a histogram
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  ui <- fluidPage(
 
8
 
9
  # Application title
10
  titlePanel("TimStuff Fastball/Offspeed Calculator"),
11
 
12
- # Sidebar with a slider input for number of bins
13
  sidebarLayout(
14
  sidebarPanel(
15
- selectInput("pitch","Pitch Type",c("Fastball","Offspeed")),
16
- selectInput("phand",
17
- "Hand",
18
- c("R","L")),
19
- numericInput("velo",
20
- "Velocity /mph",90),
21
- numericInput("ivb",
22
- "Induced Vertical Break (IVB) /in.",16),
23
- numericInput("hb",
24
- "Horizontal Break (HB) /in. (Pitcher's Perspective)",6),
25
- numericInput("spinrate",
26
- "Spin Rate /rpm",2300),
27
- numericInput("ext",
28
- "Extension /ft",6),
29
- numericInput("spinaxisdiff",
30
- "Spin Axis Difference (-180 - 180) /degrees",0),
31
- numericInput("x0","Horizntal Release Point /ft. (Batter's Perspective)",0),
32
- numericInput("z0","Vertical Release Point /ft. (Batter's Perspective)", 0),
33
-
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  ),
36
 
37
- # Show a plot of the generated distribution
38
  mainPanel(
39
- verbatimTextOutput("stuff")
40
-
 
 
 
 
41
  )
42
  )
43
  )
44
 
45
- # Define server logic required to draw a histogram
46
  server <- function(input, output) {
47
- observeEvent(input$pitch,{
48
- if(input$pitch == "Offspeed"){
49
- output$stuff <- renderText({
50
- data <- as.data.frame(5)
51
- setnames(data,"5","start_speed")
52
- data$start_speed <- input$velo
53
- data$IVB <- input$ivb
54
- if(input$phand == "L"){
55
- data$HB <- input$hb * -1
56
- }
57
- else{
58
- data$HB <- input$hb
59
- }
60
- data$EAA <- input$ext / 6.3
61
- if(input$phand == "L"){
62
- data$x0 <- input$x0 * -1
63
- }
64
- else{
65
- data$x0 <- input$x0
66
- }
67
- data$z0 <- input$z0
68
- data$spin_rate <- input$spinrate
69
- data$SADiff <- input$spinaxisdiff
70
-
71
- data <- as.matrix(data)
72
- OffMod <- xgb.load('Off.model')
73
- prediction <-predict(OffMod,data)
74
- TimStuff <- (50 - (prediction - -0.002239657)/ 0.01043216 * 10)
75
 
76
- return(paste("TimStuff: ",TimStuff, "20-80 Scale, 50 is Average 1 SD is 10",sep = "\n"))
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  })
78
- }
79
- if(input$pitch == "Fastball"){
80
- output$stuff <- renderText({
81
- data <- as.data.frame(5)
82
- setnames(data,"5","start_speed")
83
- data$start_speed <- input$velo
84
- data$IVB <- input$ivb
85
- if(input$phand == "L"){
86
- data$HB <- input$hb * -1
87
- }
88
- else{
89
- data$HB <- input$hb
90
- }
91
- data$EAA <- input$ext / 6.3
92
- if(input$phand == "L"){
93
- data$x0 <- input$x0 * -1
94
- }
95
- else{
96
- data$x0 <- input$x0
97
- }
98
- data$z0 <- input$z0
99
- data$spin_rate <- input$spinrate
100
- data$SADiff <- input$spinaxisdiff
101
 
102
- data <- as.matrix(data)
103
- FBMod <- xgb.load('FB.model')
104
- prediction <-predict(FBMod,data)
105
- TimStuff <- (50 - (prediction - -0.0011801)/ 0.007989927 * 10)
 
 
106
 
107
- return(paste("TimStuff: ",TimStuff, "20-80 Scale, 50 is Average 1 SD is 10",sep = "\n"))
 
 
 
 
 
 
 
 
 
 
108
  })
109
- }
110
  })
111
  }
112
 
113
  # Run the application
114
  shinyApp(ui = ui, server = server)
 
 
3
  library(data.table)
4
  library(xgboost)
5
  library(caret)
6
+ library(shinythemes)
7
+ calculate_timstuff <- function(data, pitch_type) {
8
+ data_matrix <- as.matrix(data)
9
+ if (pitch_type == "Offspeed") {
10
+ mod <- xgb.load('Off.model')
11
+ prediction <- predict(mod, data_matrix)
12
+ timstuff <- (50 - (prediction - -0.002239657) / 0.01043216 * 10)
13
+ } else {
14
+ mod <- xgb.load('FB.model')
15
+ prediction <- predict(mod, data_matrix)
16
+ timstuff <- (50 - (prediction - -0.0011801) / 0.007989927 * 10)
17
+ }
18
+ return(timstuff)
19
+ }
20
  ui <- fluidPage(
21
+ theme = shinytheme("flatly"),
22
 
23
  # Application title
24
  titlePanel("TimStuff Fastball/Offspeed Calculator"),
25
 
26
+ # Sidebar with inputs
27
  sidebarLayout(
28
  sidebarPanel(
29
+ width = 4,
30
+ radioButtons("pitch", "Pitch Type", choices = c("Fastball", "Offspeed"), inline = TRUE),
31
+ radioButtons("phand", "Hand", choices = c("R", "L"), inline = TRUE),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ numericInput("velo", "Velocity (mph)", value = 90, min = 70, max = 110, step = 1),
34
+ numericInput("ivb", "Induced Vertical Break (in)", value = 16, min = -20, max = 30, step = 0.1),
35
+ numericInput("hb", "Horizontal Break (in)", value = 6, min = -20, max = 20, step = 0.1),
36
+ numericInput("spinrate", "Spin Rate (rpm)", value = 2300, min = 1000, max = 3500, step = 10),
37
+ numericInput("ext", "Extension (ft)", value = 6, min = 5, max = 8, step = 0.1),
38
+ numericInput("spinaxisdiff", "Spin Axis Difference (°)", value = 0, min = -180, max = 180, step = 1),
39
+ numericInput("x0", "Horizontal Release Point (ft)", value = 0, min = -5, max = 5, step = 0.1),
40
+ numericInput("z0", "Vertical Release Point (ft)", value = 5, min = 3, max = 8, step = 0.1),
41
+ selectInput("feature_to_vary", "Select Feature to Vary:",
42
+ choices = c("Velocity" = "start_speed",
43
+ "Induced Vertical Break" = "IVB",
44
+ "Horizontal Break" = "HB",
45
+ "Spin Rate" = "spin_rate",
46
+ "Extension" = "EAA",
47
+ "Spin Axis Difference" = "SADiff",
48
+ "Horizontal Release Point" = "x0",
49
+ "Vertical Release Point" = "z0"))
50
  ),
51
 
52
+ # Main panel with output
53
  mainPanel(
54
+ width = 8,
55
+ wellPanel(
56
+ h3("Results"),
57
+ verbatimTextOutput("stuff"),
58
+ plotOutput("feature_impact", height = "400px") # Placeholder for future visualization
59
+ )
60
  )
61
  )
62
  )
63
 
 
64
  server <- function(input, output) {
65
+ observeEvent(input$pitch, {
66
+ output$stuff <- renderText({
67
+ data <- data.frame(
68
+ start_speed = input$velo,
69
+ IVB = input$ivb,
70
+ HB = ifelse(input$phand == "L", -input$hb, input$hb),
71
+ EAA = input$ext / 6.3,
72
+ x0 = ifelse(input$phand == "L", -input$x0, input$x0),
73
+ z0 = input$z0,
74
+ spin_rate = input$spinrate,
75
+ SADiff = input$spinaxisdiff
76
+ )
77
+
78
+ data <- as.matrix(data)
79
+
80
+ if (input$pitch == "Offspeed") {
81
+ mod <- xgb.load('Off.model')
82
+ prediction <- predict(mod, data)
83
+ TimStuff <- (50 - (prediction - -0.002239657) / 0.01043216 * 10)
84
+ } else {
85
+ mod <- xgb.load('FB.model')
86
+ prediction <- predict(mod, data)
87
+ TimStuff <- (50 - (prediction - -0.0011801) / 0.007989927 * 10)
88
+ }
89
+
90
+ paste("TimStuff:", round(TimStuff, 2), "\n20-80 Scale, 50 is Average, 1 SD is 10")
91
+ })
 
92
 
93
+ # Add this new reactive expression
94
+ # Add this new reactive expression
95
+ feature_range <- reactive({
96
+ ranges <- list(
97
+ start_speed = c(70, 110),
98
+ IVB = c(-20, 30),
99
+ HB = c(-20, 20),
100
+ spin_rate = c(1000, 3500),
101
+ EAA = c(5/6.3, 8/6.3),
102
+ SADiff = c(-180, 180),
103
+ x0 = c(-5, 5),
104
+ z0 = c(3, 8)
105
+ )
106
+ ranges[[input$feature_to_vary]]
107
  })
108
+
109
+ # Update the feature_impact plot
110
+ output$feature_impact <- renderPlot({
111
+ # Create base data frame with current inputs
112
+ base_data <- data.frame(
113
+ start_speed = input$velo,
114
+ IVB = input$ivb,
115
+ HB = ifelse(input$phand == "L", -input$hb, input$hb),
116
+ EAA = input$ext / 6.3,
117
+ x0 = ifelse(input$phand == "L", -input$x0, input$x0),
118
+ z0 = input$z0,
119
+ spin_rate = input$spinrate,
120
+ SADiff = input$spinaxisdiff
121
+ )
122
+
123
+ # Generate sequence for the selected feature
124
+ feature_seq <- seq(feature_range()[1], feature_range()[2], length.out = 100)
125
+
126
+ # Calculate TimStuff for the sequence
127
+ varied_data <- do.call(rbind, replicate(100, base_data, simplify = FALSE))
128
+ varied_data[[input$feature_to_vary]] <- feature_seq
129
+ timstuff <- calculate_timstuff(varied_data, input$pitch)
 
130
 
131
+ # Create plot data
132
+ plot_data <- data.frame(
133
+ Feature = names(base_data)[which(names(base_data) == input$feature_to_vary)],
134
+ Value = feature_seq,
135
+ TimStuff = timstuff
136
+ )
137
 
138
+ # Create plot
139
+ ggplot(plot_data, aes(x = Value, y = TimStuff)) +
140
+ geom_line(color = "blue", size = 1) +
141
+ geom_point(aes(x = base_data[[input$feature_to_vary]],
142
+ y = calculate_timstuff(base_data, input$pitch)),
143
+ color = "red", size = 3) +
144
+ theme_minimal() +
145
+ ylim(0,100) +
146
+ labs(title = paste("Impact of", input$feature_to_vary, "on TimStuff"),
147
+ x = input$feature_to_vary, y = "TimStuff") +
148
+ theme(text = element_text(size = 14))
149
  })
 
150
  })
151
  }
152
 
153
  # Run the application
154
  shinyApp(ui = ui, server = server)
155
+