Rhiannah’s Quatro

Quarto

Quarto enables you to weave together content and executable code into a finished document. To learn more about Quarto see https://quarto.org.

Running Code

When you click the Render button a document will be generated that includes both content and the output of embedded code. You can embed code like this:

You can add options to executable code like this

setwd("~/Library/CloudStorage/OneDrive-Personal/Teesside University/Semester 2/R Studio/Work Area/Assessment")

The echo: false option disables the printing of code (only output is displayed).

  data <- read_csv("Assessment Data.csv")
Rows: 210 Columns: 26
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (1): Date
dbl (25): ID, Altitude_code, GD, Replication, TimeinEnvironment, Altitude, D...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
    view(data)
 data <- clean_names(data)
    view(data)
colnames(data)
 [1] "id"                 "date"               "altitude_code"     
 [4] "gd"                 "replication"        "timein_environment"
 [7] "altitude"           "duration"           "distance"          
[10] "distancemin"        "high_speed_running" "hs_rmin"           
[13] "player_load"        "playerloadmin"      "hr_zone3time"      
[16] "hr_zone4time"       "hr_zone5time"       "hr_zone6time"      
[19] "h_rzone_trimp"      "soreness_1"         "mood_1"            
[22] "nutrition_1"        "rpe_leg"            "rpe_breathe"       
[25] "rpe_tech"           "rpe_session"       
   data$id <- as.factor(data$id)  
   #data$date <- as.Date(data$date,format="%m-%d-%Y") #date being an issue
   data$altitude_code<- as.factor(data$altitude_code)
   data$gd<- as.factor(data$gd)
   data$replication<- as.factor(data$replication)
   
   view(data)
   data <- data %>%           #renamed altitude levels for clarity
     mutate(altitude_code = recode(altitude_code, 
                              `1` = "Sea", 
                              `2` = "Low", 
                              `3` = "Medium"))
   view(data)
data <- data %>%           #renamed game day for clarity
     mutate(gd = recode(gd, 
                                   `0` = "MD", 
                                   `1` = "MD-1", 
                                   `2` = "MD-2"))
   view(data)
#wrangle
   data <- data %>%     #removed heart rate data as was very sparse with lots of missing values
     select(-c(hr_zone3time, hr_zone4time, hr_zone5time, hr_zone6time, h_rzone_trimp))
   view(data)
#FINAL DASHBOARD!!!!! - NEED TI CHANGE TEXT IN SUMMARY FINDINGS
# UI ----
ui <- dashboardPage(
  dashboardHeader(title = "Matchday Altitude Dashboard"),
  dashboardSidebar(
    sidebarMenu(
      menuItem("Boxplot Analysis", tabName = "boxplot", icon = icon("chart-bar")),
      menuItem("Lollipop Graph", tabName = "lollipop", icon = icon("chart-line"))
    )
  ),
  
  dashboardBody(
    tabItems(
      
      # 📌 Boxplot Tab ----
      tabItem(tabName = "boxplot",
              selectInput("view_option", "View Option:", 
                          choices = c("Single Metric", "Both Metrics"), 
                          selected = "Single Metric"),
              
              selectInput("metric", "Select Metric:", 
                          choices = c("HSR per min" = "hsr", "Soreness" = "soreness"), 
                          selected = "hsr"),
              
              fluidRow(
                box(plotOutput("altitude_plot"), title = "Altitude Impact on Mean Score", width = 12)
              ),
              
              # Conditional Summary Box (Only for Both Metrics)
              conditionalPanel(
                condition = "input.view_option == 'Both Metrics'",
                box(
                  title = "Summary of Findings",
                  width = 12,
                  textOutput("summary_text")
                )
              )
      ),
      
      # 📌 Lollipop Graph Tab ----
      tabItem(tabName = "lollipop",
              selectInput("view_option_lollipop", "View Option:", 
                          choices = c("Single Metric", "Both Metrics"), 
                          selected = "Single Metric"),
              
              selectInput("lollipop_metric", "Select Metric:", 
                          choices = c("HSR per min" = "hsr", "Soreness" = "soreness"), 
                          selected = "hsr"),
              
              # Single Metric Lollipop Plot
              conditionalPanel(
                condition = "input.view_option_lollipop == 'Single Metric'",
                box(plotOutput("lollipop_plot"), title = "Individual Differences at Altitude", width = 12)
              ),
              
              # Both Metrics Lollipop Plots Side by Side
              conditionalPanel(
                condition = "input.view_option_lollipop == 'Both Metrics'",
                fluidRow(
                  box(plotOutput("lollipop_plot_hsr"), title = "HSR per min", width = 6),
                  box(plotOutput("lollipop_plot_soreness"), title = "Soreness", width = 6)
                ),
                # Conditional Summary Box for Lollipop Graph
                box(
                  title = "Summary of Findings",
                  width = 12,
                  textOutput("summary_text_lollipop")
                )
              )
      )
    )
  )
)

# Server ----
server <- function(input, output) {
  
  # Convert data to long format for boxplot
  soreness_1_long <- soreness_1 %>%
    pivot_longer(cols = c(mean_hs_rmin, mean_soreness_1), names_to = "Metric", values_to = "Value") %>%
    mutate(Metric = recode(Metric, mean_hs_rmin = "HSR (m/min)", mean_soreness_1 = "Soreness (1-10)"))
  
  output$altitude_plot <- renderPlot({
    if (input$view_option == "Single Metric") {
      metric_column <- ifelse(input$metric == "hsr", "mean_hs_rmin", "mean_soreness_1")
      metric_label <- ifelse(input$metric == "hsr", "Matchday Mean High-Speed Running (m/min)", "Matchday Mean Soreness")
      
      ggplot(soreness_1, aes(x = altitude_code, y = .data[[metric_column]], fill = altitude_code)) +
        geom_boxplot(outlier.shape = NA) +  
        geom_point(color = "red", size = 2, alpha = 0.8, position = position_nudge(x = 0)) +  
        scale_fill_manual(values = c(Sea = "#011925", Low = "#418cdd", Medium = "#c3a871")) +
        theme_classic() +
        labs(
          x = "Altitude Category",
          y = metric_label,  
          fill = "Altitude Level",
          title = paste("Impact of Altitude on", metric_label)
        )
    } else {
      ggplot(soreness_1_long, aes(x = altitude_code, y = Value, fill = altitude_code)) +
        geom_boxplot(outlier.shape = NA) +  
        geom_point(color = "red", size = 2, alpha = 0.8, position = position_nudge(x = 0)) +  
        facet_wrap(~ Metric, scales = "free") +
        scale_fill_manual(values = c(Sea = "#011925", Low = "#418cdd", Medium = "#c3a871")) +
        theme_classic() +
        labs(
          x = "Altitude Category",
          y = "",  
          fill = "Altitude Level",
          title = "Impact of Altitude on HSR and Soreness"
        )
    }
  })
  
  # Compute individual differences for Lollipop Graph
  individual_differences <- soreness_1 %>%
    group_by(id) %>%
    summarize(
      hsr_diff = mean(mean_hs_rmin[altitude_code != "Sea"], na.rm = TRUE) - mean(mean_hs_rmin[altitude_code == "Sea"], na.rm = TRUE),
      soreness_diff = mean(mean_soreness_1[altitude_code != "Sea"], na.rm = TRUE) - mean(mean_soreness_1[altitude_code == "Sea"], na.rm = TRUE)
    ) %>%
    pivot_longer(cols = c(hsr_diff, soreness_diff), names_to = "Metric", values_to = "Difference") %>%
    mutate(Metric = recode(Metric, hsr_diff = "HSR per min", soreness_diff = "Soreness"))
  
  render_lollipop <- function(metric_label) {
    plot_data <- individual_differences %>%
      filter(Metric == metric_label, !is.na(Difference))
    
    ggplot(plot_data, aes(x = Difference, y = reorder(id, Difference))) +
      geom_rect(aes(xmin = -1, xmax = 1, ymin = -Inf, ymax = Inf), fill = "gray80", alpha = 0.3) +
      geom_segment(aes(xend = 0, yend = id), color = "black") +
      geom_point(size = 4, color = "red") +
      geom_vline(xintercept = 0, linetype = "dashed", color = "black") +
      theme_minimal() +
      labs(x = "Difference from Sea Level", y = "Player ID", title = paste("Individual Differences in", metric_label, "at Altitude"))
  }
  
  # Render Single Lollipop Graph
  output$lollipop_plot <- renderPlot({
    render_lollipop(ifelse(input$lollipop_metric == "hsr", "HSR per min", "Soreness"))
  })
  
  # Render Both Lollipop Graphs Side by Side
  output$lollipop_plot_hsr <- renderPlot({ render_lollipop("HSR per min") })
  output$lollipop_plot_soreness <- renderPlot({ render_lollipop("Soreness") })
  
  # Create summary text for findings (Boxplot)
  output$summary_text <- renderText({
    if (input$view_option == "Both Metrics") {
      return("The analysis of HSR per min and Soreness across different altitude categories shows notable differences in performance and discomfort. Specific trends are observed in each metric when considering various altitudes.")
    } else {
      metric_label <- ifelse(input$metric == "hsr", "HSR per min", "Soreness")
      return(paste("The analysis for", metric_label, "at different altitudes suggests the impact of altitude on the metric. Further detailed analysis is required to draw conclusions on the impact at different altitude levels."))
    }
  })
  
  # Create summary text for findings (Lollipop)
  output$summary_text_lollipop <- renderText({
    if (input$view_option_lollipop == "Both Metrics") {
      return("The individual differences in HSR per min and Soreness across altitude categories show varying impacts on player performance and discomfort. The analysis reveals significant variations in both metrics at different altitudes, which could suggest changes in physiological responses under different altitude conditions.")
    } else {
      metric_label <- ifelse(input$lollipop_metric == "hsr", "HSR per min", "Soreness")
      return(paste("The analysis of", metric_label, "individual differences at different altitudes suggests significant changes in performance and discomfort. Further exploration may be needed to assess the implications of these changes at different altitudes."))
    }
  })
}

# Run App ----
shinyApp(ui = ui, server = server)

Shiny applications not supported in static R Markdown documents