Spaces:
Running
Running
Update app.R
Browse files
app.R
CHANGED
|
@@ -1131,7 +1131,6 @@ app_ui <- fluidPage(
|
|
| 1131 |
)
|
| 1132 |
),
|
| 1133 |
|
| 1134 |
-
# Download Tab
|
| 1135 |
tabPanel(
|
| 1136 |
"Download",
|
| 1137 |
fluidRow(
|
|
@@ -1139,6 +1138,33 @@ app_ui <- fluidPage(
|
|
| 1139 |
h3("Download Processed Data"),
|
| 1140 |
|
| 1141 |
div(class = "download-option-box",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1142 |
fluidRow(
|
| 1143 |
column(5,
|
| 1144 |
textInput("download_filename", "File Name (without extension):",
|
|
@@ -2441,60 +2467,76 @@ server <- function(input, output, session) {
|
|
| 2441 |
sep = "\n"
|
| 2442 |
)
|
| 2443 |
})
|
| 2444 |
-
|
| 2445 |
-
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 2446 |
-
# Helper: merge catcher notes into data for download
|
| 2447 |
-
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 2448 |
-
|
| 2449 |
build_download_data <- function() {
|
| 2450 |
df <- processed_data()
|
| 2451 |
if (is.null(df)) return(NULL)
|
| 2452 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2453 |
notes <- catcher_notes_list()
|
| 2454 |
|
| 2455 |
if (nrow(notes) == 0) return(df)
|
| 2456 |
|
| 2457 |
-
# Initialize
|
| 2458 |
-
if (!"
|
| 2459 |
-
df$
|
| 2460 |
}
|
| 2461 |
|
| 2462 |
-
# For each note,
|
| 2463 |
-
# If multiple notes match the same row, concatenate with " | "
|
| 2464 |
for (i in seq_len(nrow(notes))) {
|
| 2465 |
row_idx <- notes$MatchedRow[i]
|
| 2466 |
result <- notes$Result[i]
|
| 2467 |
|
| 2468 |
if (!is.na(row_idx) && row_idx >= 1 && row_idx <= nrow(df)) {
|
| 2469 |
-
existing <- df$
|
| 2470 |
if (is.na(existing) || existing == "") {
|
| 2471 |
-
df$
|
| 2472 |
} else {
|
| 2473 |
-
df$
|
| 2474 |
}
|
| 2475 |
}
|
| 2476 |
}
|
| 2477 |
|
| 2478 |
-
#
|
| 2479 |
unmatched <- notes %>% filter(is.na(MatchedRow))
|
| 2480 |
if (nrow(unmatched) > 0) {
|
| 2481 |
unmatched_texts <- paste0(
|
| 2482 |
unmatched$Result, " (", unmatched$Catcher, "/", unmatched$Batter,
|
| 2483 |
" Inn", unmatched$Inning, " ", unmatched$Balls, "-", unmatched$Strikes, ")"
|
| 2484 |
)
|
| 2485 |
-
# Put unmatched notes in the last row's CatcherNotes with a prefix
|
| 2486 |
last_row <- nrow(df)
|
| 2487 |
-
existing <- df$
|
| 2488 |
unmatched_str <- paste0("[UNMATCHED] ", paste(unmatched_texts, collapse = "; "))
|
| 2489 |
if (is.na(existing) || existing == "") {
|
| 2490 |
-
df$
|
| 2491 |
} else {
|
| 2492 |
-
df$
|
| 2493 |
}
|
| 2494 |
}
|
| 2495 |
|
| 2496 |
return(df)
|
| 2497 |
}
|
|
|
|
| 2498 |
|
| 2499 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 2500 |
# End Catcher Notes
|
|
|
|
| 1131 |
)
|
| 1132 |
),
|
| 1133 |
|
|
|
|
| 1134 |
tabPanel(
|
| 1135 |
"Download",
|
| 1136 |
fluidRow(
|
|
|
|
| 1138 |
h3("Download Processed Data"),
|
| 1139 |
|
| 1140 |
div(class = "download-option-box",
|
| 1141 |
+
h4("Processing Mode", style = "color: darkcyan; margin-top: 0;"),
|
| 1142 |
+
radioButtons("download_mode", NULL,
|
| 1143 |
+
choices = c(
|
| 1144 |
+
"Raw Edited CSV (as-is)" = "raw",
|
| 1145 |
+
"Full Processing (clean + indicators + Stuff+)" = "full"
|
| 1146 |
+
),
|
| 1147 |
+
selected = "raw", inline = TRUE),
|
| 1148 |
+
conditionalPanel(
|
| 1149 |
+
condition = "input.download_mode == 'full'",
|
| 1150 |
+
div(style = "background: #d4edda; border-left: 4px solid #28a745; padding: 12px; border-radius: 0 8px 8px 0; margin: 10px 0;",
|
| 1151 |
+
p(style = "margin: 0; color: #155724; font-size: 13px;",
|
| 1152 |
+
tags$b("Full Processing will:"),
|
| 1153 |
+
"Normalize names & pitch types, convert PlateLocHeight/Side to inches, ",
|
| 1154 |
+
"add swing/whiff/chase/zone flags, compute wOBA/SLG/OBP indicators, ",
|
| 1155 |
+
"join run values, predict Stuff+, and trim to ~140 columns.")
|
| 1156 |
+
)
|
| 1157 |
+
),
|
| 1158 |
+
conditionalPanel(
|
| 1159 |
+
condition = "input.download_mode == 'raw'",
|
| 1160 |
+
div(style = "background: #e8f4f8; border-left: 4px solid darkcyan; padding: 12px; border-radius: 0 8px 8px 0; margin: 10px 0;",
|
| 1161 |
+
p(style = "margin: 0; color: #006F71; font-size: 13px;",
|
| 1162 |
+
tags$b("Raw Edited:"),
|
| 1163 |
+
"Downloads your current data with any pitch retags, column removals, ",
|
| 1164 |
+
"bat tracking merges, and catcher notes applied β no additional processing.")
|
| 1165 |
+
)
|
| 1166 |
+
),
|
| 1167 |
+
hr(),
|
| 1168 |
fluidRow(
|
| 1169 |
column(5,
|
| 1170 |
textInput("download_filename", "File Name (without extension):",
|
|
|
|
| 2467 |
sep = "\n"
|
| 2468 |
)
|
| 2469 |
})
|
| 2470 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2471 |
build_download_data <- function() {
|
| 2472 |
df <- processed_data()
|
| 2473 |
if (is.null(df)) return(NULL)
|
| 2474 |
|
| 2475 |
+
# ββ Full processing mode: clean + stuff+ ββ
|
| 2476 |
+
if (!is.null(input$download_mode) && input$download_mode == "full") {
|
| 2477 |
+
df <- tryCatch({
|
| 2478 |
+
showNotification("Running clean_college_data()...", type = "message", duration = 2)
|
| 2479 |
+
cleaned <- clean_college_data(df)
|
| 2480 |
+
|
| 2481 |
+
showNotification("Predicting Stuff+...", type = "message", duration = 2)
|
| 2482 |
+
cleaned <- predict_stuffplus(cleaned)
|
| 2483 |
+
|
| 2484 |
+
showNotification(
|
| 2485 |
+
paste0("Full processing complete: ", nrow(cleaned), " rows Γ ", ncol(cleaned), " columns"),
|
| 2486 |
+
type = "message", duration = 4
|
| 2487 |
+
)
|
| 2488 |
+
cleaned
|
| 2489 |
+
}, error = function(e) {
|
| 2490 |
+
showNotification(paste("Processing error:", e$message), type = "error", duration = 8)
|
| 2491 |
+
processed_data()
|
| 2492 |
+
})
|
| 2493 |
+
}
|
| 2494 |
+
|
| 2495 |
+
# ββ Merge catcher notes into existing Notes column ββ
|
| 2496 |
notes <- catcher_notes_list()
|
| 2497 |
|
| 2498 |
if (nrow(notes) == 0) return(df)
|
| 2499 |
|
| 2500 |
+
# Initialize Notes column if not present
|
| 2501 |
+
if (!"Notes" %in% names(df)) {
|
| 2502 |
+
df$Notes <- NA_character_
|
| 2503 |
}
|
| 2504 |
|
| 2505 |
+
# For each note, append the result into the matched row's Notes
|
|
|
|
| 2506 |
for (i in seq_len(nrow(notes))) {
|
| 2507 |
row_idx <- notes$MatchedRow[i]
|
| 2508 |
result <- notes$Result[i]
|
| 2509 |
|
| 2510 |
if (!is.na(row_idx) && row_idx >= 1 && row_idx <= nrow(df)) {
|
| 2511 |
+
existing <- df$Notes[row_idx]
|
| 2512 |
if (is.na(existing) || existing == "") {
|
| 2513 |
+
df$Notes[row_idx] <- result
|
| 2514 |
} else {
|
| 2515 |
+
df$Notes[row_idx] <- paste(existing, result, sep = " | ")
|
| 2516 |
}
|
| 2517 |
}
|
| 2518 |
}
|
| 2519 |
|
| 2520 |
+
# Append unmatched notes to last row
|
| 2521 |
unmatched <- notes %>% filter(is.na(MatchedRow))
|
| 2522 |
if (nrow(unmatched) > 0) {
|
| 2523 |
unmatched_texts <- paste0(
|
| 2524 |
unmatched$Result, " (", unmatched$Catcher, "/", unmatched$Batter,
|
| 2525 |
" Inn", unmatched$Inning, " ", unmatched$Balls, "-", unmatched$Strikes, ")"
|
| 2526 |
)
|
|
|
|
| 2527 |
last_row <- nrow(df)
|
| 2528 |
+
existing <- df$Notes[last_row]
|
| 2529 |
unmatched_str <- paste0("[UNMATCHED] ", paste(unmatched_texts, collapse = "; "))
|
| 2530 |
if (is.na(existing) || existing == "") {
|
| 2531 |
+
df$Notes[last_row] <- unmatched_str
|
| 2532 |
} else {
|
| 2533 |
+
df$Notes[last_row] <- paste(existing, unmatched_str, sep = " | ")
|
| 2534 |
}
|
| 2535 |
}
|
| 2536 |
|
| 2537 |
return(df)
|
| 2538 |
}
|
| 2539 |
+
|
| 2540 |
|
| 2541 |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 2542 |
# End Catcher Notes
|