Hi all,
I have some code written for a little app i'm looking to make some improvements to.
I want the user to be able to use the selectInput dropdown to select which period names are selected and the function applied to. The user can then change the total duration column and it'll multiply the rest of the columns (except m.min, acc.TD, acc.HSR and acc.Speed) by total duration. Ultimately, i'd love a 2nd table under the existing one that is a summary of all columns (sum of each).
I've attached a sample dataset and my existing code below. Any help would be greatly appreciated!
# Load required libraries
library(shiny)
library(shinydashboard)
library(tidyverse)
library(knitr)
library(ggimage)
library(DT)
library(kableExtra)
library(shinythemes)
library(reactablefmtr)
# Data Preparation ----
database <- read_csv("Dataset.csv") %>% na.omit() %>% filter(`Player Availability` == "Main Training") # Import unclean dataset
database$`Time Spend Between 85-95% Max HR` <- as.numeric(database$`Time Spend Between 85-95% Max HR`)/60
database$`Time Spend Above 95% Max HR` <- as.numeric(database$`Time Spend Above 95% Max HR`)/60
database$`Total Duration` <- as.numeric(database$`Total Duration`)/60
database <- database %>% select(`Period Name`, `Total Distance`,`Total Duration`,`Meterage Per Minute`, `Distance 19-23kmph`, `Distance 23-25kmph`, `Distance 25-45kmph`, Accel, Decel, `Time Spend Above 95% Max HR`, `Time Spend Between 85-95% Max HR`)
database <- database %>% group_by(`Period Name`) %>% summarise(across(where(is.numeric), ~ mean(.x, na.rm = TRUE)))
database <- database %>% mutate(`Total Distance` = `Total Distance`/`Total Duration`,
M.Min = `Meterage Per Minute`,
`HSR > 19kmph` = (`Distance 19-23kmph` + `Distance 23-25kmph` + `Distance 25-45kmph`)/`Total Duration`,
`Total 25+kmph` = (`Distance 25-45kmph`/ `Total Duration`),
Accel = Accel/`Total Duration`,
Decel = Decel/`Total Duration`,
Time.Above.85 = (`Time Spend Above 95% Max HR` + `Time Spend Between 85-95% Max HR`)/`Total Duration`)
database <- database %>% mutate(`Total Duration` = 1)
database1 <- database %>% select(`Period Name`,`Total Duration`,`Total Distance`, `M.Min`, `HSR > 19kmph`, `Total 25+kmph`, Accel, Decel,Time.Above.85)
# Select only relevant information
database1 <- database1 %>% mutate_at(3:6, round,0) %>% mutate_at(7:9, round,2) %>% mutate(Acc.TD = cumsum(`Total Distance`),
Acc.HSR = cumsum(`HSR > 19kmph`),
Acc.Speed = cumsum(`Total 25+kmph`))
database1 <- database1 %>% select(`Period Name`, `Total Duration`, M.Min, `Total Distance`, Acc.TD, `HSR > 19kmph`, Acc.HSR, `Total 25+kmph`, Acc.Speed, Accel, Decel, Time.Above.85)
### Module
modFunction <- function(input, output, session, data, reset) {
v <- reactiveValues(data = data)
proxy = dataTableProxy("mod_table")
observeEvent(input$mod_table_cell_edit, {
info = input$mod_table_cell_edit
i = info$row
j = info$col
k = info$value
isolate(
if (j %in% match("Total Duration", names(v$data))) {
# Filter numeric columns (excluding "Total Duration") for multiplication
numeric_cols <- names(v$data)[sapply(v$data, is.numeric) & names(v$data) != "Total Duration"]
# Multiply each numeric column in the current row by the new Total Duration value
for (col in numeric_cols) {
v$data[i, col] <- v$data[i, col] * k
}
# Update the edited Total Duration cell
v$data[i, j] <- k
}
)
# Update the cumulative sum column when a cell is edited
if (j == which(names(v$data) == "Total Distance")) {
v$data$Cumulative_Distance[i] <- cumsum(v$data$`Total Distance`[1:i])
}
replaceData(proxy, v$data, resetPaging = FALSE)
})
### Reset Table
observeEvent(reset(), {
v$data <- data
})
output$mod_table <- DT::renderDataTable({
datatable(v$data, editable = list(target = 'cell', disable = list(cols = which(!names(v$data) %in% "Total Duration"))))
})
return(v)
}
modFunctionUI <- function(id) {
ns <- NS(id)
DT::dataTableOutput((ns("mod_table")))
}
shinyApp(
dashboardPage(
dashboardHeader(title = "Drill Wizard"),
dashboardSidebar(
width = 200, # Adjust sidebar width here
selectInput("selected_rows", "Select Drills:", choices = database1$`Period Name`, multiple = TRUE)),
dashboardBody(
modFunctionUI("editable"),
div(DTOutput("table_output"), style = "margin-bottom: 100px; margin-top: 20px;text-align: center;"),
div(DTOutput("summary_table_output"), style = "margin-top: 20px;text-align: center;"),
),
# Set the shinytheme to "cosmo"
shinytheme("cosmo")
),
server = function(input, output) {
demodata<-database1
edited <- callModule(modFunction,"editable", demodata,
reset = reactive(input$reset))
data_df_final <- reactiveValues()
observe(
{data_df_final$data <- edited$data}
)
observe(print(data_df_final$data))
}
)