Spaces:
Running
Running
Update app.R
Browse files
app.R
CHANGED
|
@@ -40,8 +40,10 @@ pitch_colors <- c(
|
|
| 40 |
"Other" = "#D3D3D3"
|
| 41 |
)
|
| 42 |
|
| 43 |
-
# Function to convert date formats
|
| 44 |
-
|
|
|
|
|
|
|
| 45 |
if (is.na(date_string) || date_string == "") {
|
| 46 |
return(NA)
|
| 47 |
}
|
|
@@ -49,18 +51,38 @@ convert_date_format <- function(date_string) {
|
|
| 49 |
# Convert to character if not already
|
| 50 |
date_string <- as.character(date_string)
|
| 51 |
|
| 52 |
-
|
|
|
|
|
|
|
| 53 |
if (grepl("^\\d{4}-\\d{2}-\\d{2}$", date_string)) {
|
| 54 |
-
|
|
|
|
|
|
|
| 55 |
}
|
| 56 |
|
| 57 |
# Try to parse MM/DD/YYYY or M/D/YYYY format
|
| 58 |
-
if (grepl("^\\d{1,2}/\\d{1,2}/\\d{4}$", date_string)) {
|
| 59 |
parsed_date <- tryCatch({
|
| 60 |
as.Date(date_string, format = "%m/%d/%Y")
|
| 61 |
-
}, error = function(e)
|
| 62 |
-
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
return(format(parsed_date, "%Y-%m-%d"))
|
| 65 |
}
|
| 66 |
}
|
|
@@ -70,13 +92,13 @@ convert_date_format <- function(date_string) {
|
|
| 70 |
}
|
| 71 |
|
| 72 |
# Function to convert date columns in a dataframe
|
| 73 |
-
convert_date_columns <- function(df) {
|
| 74 |
# Common date column names in TrackMan data
|
| 75 |
date_columns <- c("Date", "GameDate", "UTCDate", "LocalDateTime")
|
| 76 |
|
| 77 |
for (col in date_columns) {
|
| 78 |
if (col %in% names(df)) {
|
| 79 |
-
df[[col]] <- sapply(df[[col]], convert_date_format, USE.NAMES = FALSE)
|
| 80 |
}
|
| 81 |
}
|
| 82 |
|
|
@@ -443,18 +465,23 @@ ui <- fluidPage(
|
|
| 443 |
h3("1. Upload TrackMan CSV"),
|
| 444 |
fileInput("file", "Choose CSV File", accept = c(".csv")),
|
| 445 |
fluidRow(
|
| 446 |
-
column(
|
| 447 |
checkboxInput("header", "Header", TRUE)
|
| 448 |
),
|
| 449 |
-
column(
|
| 450 |
radioButtons("sep", "Separator",
|
| 451 |
choices = c(Comma = ",", Semicolon = ";", Tab = "\t"),
|
| 452 |
selected = ",", inline = TRUE)
|
| 453 |
),
|
| 454 |
-
column(
|
| 455 |
radioButtons("quote", "Quote",
|
| 456 |
choices = c(None = "", "Double Quote" = '"', "Single Quote" = "'"),
|
| 457 |
selected = '"', inline = TRUE)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 458 |
)
|
| 459 |
),
|
| 460 |
verbatimTextOutput("csv_status")
|
|
@@ -645,6 +672,56 @@ server <- function(input, output, session) {
|
|
| 645 |
updateCheckboxGroupInput(session, "columns_to_remove", selected = spinaxis_cols)
|
| 646 |
})
|
| 647 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 648 |
# Process uploaded CSV file
|
| 649 |
observeEvent(input$file, {
|
| 650 |
req(input$file)
|
|
@@ -656,8 +733,8 @@ server <- function(input, output, session) {
|
|
| 656 |
quote = input$quote,
|
| 657 |
stringsAsFactors = FALSE)
|
| 658 |
|
| 659 |
-
# Auto-convert date formats
|
| 660 |
-
df <- convert_date_columns(df)
|
| 661 |
|
| 662 |
csv_data_raw(df)
|
| 663 |
|
|
@@ -744,13 +821,14 @@ server <- function(input, output, session) {
|
|
| 744 |
|
| 745 |
df <- csv_data_raw()
|
| 746 |
game_id <- if ("GameID" %in% names(df)) unique(df$GameID)[1] else "Unknown"
|
|
|
|
| 747 |
|
| 748 |
paste(
|
| 749 |
"✓ CSV loaded successfully!",
|
| 750 |
paste(" Game ID:", game_id),
|
| 751 |
paste(" Rows:", nrow(df)),
|
| 752 |
paste(" Columns:", ncol(df)),
|
| 753 |
-
"✓ Date
|
| 754 |
sep = "\n"
|
| 755 |
)
|
| 756 |
})
|
|
@@ -965,7 +1043,7 @@ server <- function(input, output, session) {
|
|
| 965 |
removed_cols_text,
|
| 966 |
bat_tracking_text,
|
| 967 |
"✓ Duplicates removed",
|
| 968 |
-
"✓
|
| 969 |
sep = "\n"
|
| 970 |
)
|
| 971 |
|
|
@@ -1378,7 +1456,7 @@ server <- function(input, output, session) {
|
|
| 1378 |
"TaggedPitchType column not available"
|
| 1379 |
}),
|
| 1380 |
bat_tracking_summary,
|
| 1381 |
-
"Date format: YYYY-MM-DD
|
| 1382 |
sep = "\n"
|
| 1383 |
)
|
| 1384 |
|
|
|
|
| 40 |
"Other" = "#D3D3D3"
|
| 41 |
)
|
| 42 |
|
| 43 |
+
# Function to convert date formats
|
| 44 |
+
# input_string: the date string to convert
|
| 45 |
+
# output_format: "yyyy" for YYYY-MM-DD or "mdyy" for M/D/YY
|
| 46 |
+
convert_date_format <- function(date_string, output_format = "yyyy") {
|
| 47 |
if (is.na(date_string) || date_string == "") {
|
| 48 |
return(NA)
|
| 49 |
}
|
|
|
|
| 51 |
# Convert to character if not already
|
| 52 |
date_string <- as.character(date_string)
|
| 53 |
|
| 54 |
+
parsed_date <- NULL
|
| 55 |
+
|
| 56 |
+
# Try to parse YYYY-MM-DD format
|
| 57 |
if (grepl("^\\d{4}-\\d{2}-\\d{2}$", date_string)) {
|
| 58 |
+
parsed_date <- tryCatch({
|
| 59 |
+
as.Date(date_string, format = "%Y-%m-%d")
|
| 60 |
+
}, error = function(e) NULL)
|
| 61 |
}
|
| 62 |
|
| 63 |
# Try to parse MM/DD/YYYY or M/D/YYYY format
|
| 64 |
+
if (is.null(parsed_date) && grepl("^\\d{1,2}/\\d{1,2}/\\d{4}$", date_string)) {
|
| 65 |
parsed_date <- tryCatch({
|
| 66 |
as.Date(date_string, format = "%m/%d/%Y")
|
| 67 |
+
}, error = function(e) NULL)
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
# Try to parse MM/DD/YY or M/D/YY format
|
| 71 |
+
if (is.null(parsed_date) && grepl("^\\d{1,2}/\\d{1,2}/\\d{2}$", date_string)) {
|
| 72 |
+
parsed_date <- tryCatch({
|
| 73 |
+
as.Date(date_string, format = "%m/%d/%y")
|
| 74 |
+
}, error = function(e) NULL)
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
# If we successfully parsed a date, format it according to output_format
|
| 78 |
+
if (!is.null(parsed_date) && !is.na(parsed_date)) {
|
| 79 |
+
if (output_format == "mdyy") {
|
| 80 |
+
# M/D/YY format (no leading zeros, 2-digit year)
|
| 81 |
+
return(format(parsed_date, "%m/%d/%y") %>%
|
| 82 |
+
gsub("^0", "", .) %>% # Remove leading zero from month
|
| 83 |
+
gsub("/0", "/", .)) # Remove leading zero from day
|
| 84 |
+
} else {
|
| 85 |
+
# YYYY-MM-DD format
|
| 86 |
return(format(parsed_date, "%Y-%m-%d"))
|
| 87 |
}
|
| 88 |
}
|
|
|
|
| 92 |
}
|
| 93 |
|
| 94 |
# Function to convert date columns in a dataframe
|
| 95 |
+
convert_date_columns <- function(df, output_format = "yyyy") {
|
| 96 |
# Common date column names in TrackMan data
|
| 97 |
date_columns <- c("Date", "GameDate", "UTCDate", "LocalDateTime")
|
| 98 |
|
| 99 |
for (col in date_columns) {
|
| 100 |
if (col %in% names(df)) {
|
| 101 |
+
df[[col]] <- sapply(df[[col]], function(x) convert_date_format(x, output_format), USE.NAMES = FALSE)
|
| 102 |
}
|
| 103 |
}
|
| 104 |
|
|
|
|
| 465 |
h3("1. Upload TrackMan CSV"),
|
| 466 |
fileInput("file", "Choose CSV File", accept = c(".csv")),
|
| 467 |
fluidRow(
|
| 468 |
+
column(3,
|
| 469 |
checkboxInput("header", "Header", TRUE)
|
| 470 |
),
|
| 471 |
+
column(3,
|
| 472 |
radioButtons("sep", "Separator",
|
| 473 |
choices = c(Comma = ",", Semicolon = ";", Tab = "\t"),
|
| 474 |
selected = ",", inline = TRUE)
|
| 475 |
),
|
| 476 |
+
column(3,
|
| 477 |
radioButtons("quote", "Quote",
|
| 478 |
choices = c(None = "", "Double Quote" = '"', "Single Quote" = "'"),
|
| 479 |
selected = '"', inline = TRUE)
|
| 480 |
+
),
|
| 481 |
+
column(3,
|
| 482 |
+
radioButtons("date_format", "Date Output Format",
|
| 483 |
+
choices = c("YYYY-MM-DD" = "yyyy", "M/D/YY" = "mdyy"),
|
| 484 |
+
selected = "yyyy")
|
| 485 |
)
|
| 486 |
),
|
| 487 |
verbatimTextOutput("csv_status")
|
|
|
|
| 672 |
updateCheckboxGroupInput(session, "columns_to_remove", selected = spinaxis_cols)
|
| 673 |
})
|
| 674 |
|
| 675 |
+
# Re-process data when date format changes
|
| 676 |
+
observeEvent(input$date_format, {
|
| 677 |
+
req(input$file) # Only run if a file has been uploaded
|
| 678 |
+
|
| 679 |
+
# Re-read and process the CSV with new date format
|
| 680 |
+
tryCatch({
|
| 681 |
+
df <- read.csv(input$file$datapath,
|
| 682 |
+
header = input$header,
|
| 683 |
+
sep = input$sep,
|
| 684 |
+
quote = input$quote,
|
| 685 |
+
stringsAsFactors = FALSE)
|
| 686 |
+
|
| 687 |
+
# Auto-convert date formats based on user selection
|
| 688 |
+
df <- convert_date_columns(df, input$date_format)
|
| 689 |
+
|
| 690 |
+
csv_data_raw(df)
|
| 691 |
+
|
| 692 |
+
# If we already have bat tracking data, try to merge
|
| 693 |
+
if (!is.null(bat_tracking_parsed()) && !is.null(bat_tracking_parsed()$data)) {
|
| 694 |
+
result <- merge_with_bat_tracking(df, bat_tracking_parsed()$data)
|
| 695 |
+
merge_result(result)
|
| 696 |
+
df <- result$data
|
| 697 |
+
}
|
| 698 |
+
|
| 699 |
+
# Process the data (remove columns)
|
| 700 |
+
selected_cols_to_remove <- input$columns_to_remove %||% character(0)
|
| 701 |
+
processed_df <- df
|
| 702 |
+
|
| 703 |
+
if (length(selected_cols_to_remove) > 0) {
|
| 704 |
+
columns_to_drop <- intersect(names(df), selected_cols_to_remove)
|
| 705 |
+
if (length(columns_to_drop) > 0) {
|
| 706 |
+
processed_df <- processed_df %>% select(-all_of(columns_to_drop))
|
| 707 |
+
}
|
| 708 |
+
}
|
| 709 |
+
|
| 710 |
+
processed_df <- processed_df %>% distinct()
|
| 711 |
+
|
| 712 |
+
processed_data(processed_df)
|
| 713 |
+
plot_data(processed_df)
|
| 714 |
+
|
| 715 |
+
showNotification(
|
| 716 |
+
paste("Date format updated to:", if (input$date_format == "mdyy") "M/D/YY" else "YYYY-MM-DD"),
|
| 717 |
+
type = "message", duration = 3
|
| 718 |
+
)
|
| 719 |
+
|
| 720 |
+
}, error = function(e) {
|
| 721 |
+
showNotification(paste("Error updating date format:", e$message), type = "error")
|
| 722 |
+
})
|
| 723 |
+
}, ignoreInit = TRUE)
|
| 724 |
+
|
| 725 |
# Process uploaded CSV file
|
| 726 |
observeEvent(input$file, {
|
| 727 |
req(input$file)
|
|
|
|
| 733 |
quote = input$quote,
|
| 734 |
stringsAsFactors = FALSE)
|
| 735 |
|
| 736 |
+
# Auto-convert date formats based on user selection
|
| 737 |
+
df <- convert_date_columns(df, input$date_format)
|
| 738 |
|
| 739 |
csv_data_raw(df)
|
| 740 |
|
|
|
|
| 821 |
|
| 822 |
df <- csv_data_raw()
|
| 823 |
game_id <- if ("GameID" %in% names(df)) unique(df$GameID)[1] else "Unknown"
|
| 824 |
+
date_fmt <- if (input$date_format == "mdyy") "M/D/YY" else "YYYY-MM-DD"
|
| 825 |
|
| 826 |
paste(
|
| 827 |
"✓ CSV loaded successfully!",
|
| 828 |
paste(" Game ID:", game_id),
|
| 829 |
paste(" Rows:", nrow(df)),
|
| 830 |
paste(" Columns:", ncol(df)),
|
| 831 |
+
paste("✓ Date format:", date_fmt),
|
| 832 |
sep = "\n"
|
| 833 |
)
|
| 834 |
})
|
|
|
|
| 1043 |
removed_cols_text,
|
| 1044 |
bat_tracking_text,
|
| 1045 |
"✓ Duplicates removed",
|
| 1046 |
+
paste("✓ Date format:", if (input$date_format == "mdyy") "M/D/YY" else "YYYY-MM-DD"),
|
| 1047 |
sep = "\n"
|
| 1048 |
)
|
| 1049 |
|
|
|
|
| 1456 |
"TaggedPitchType column not available"
|
| 1457 |
}),
|
| 1458 |
bat_tracking_summary,
|
| 1459 |
+
paste("Date format:", if (input$date_format == "mdyy") "M/D/YY" else "YYYY-MM-DD"),
|
| 1460 |
sep = "\n"
|
| 1461 |
)
|
| 1462 |
|