Interactive: Hypothesis testing flowchart

Author

Ellie Trace

Summary
Interactive hypothesis testing flowchart for use in the guide on hypothesis testing.
#| '!! shinylive warning !!': |
#|   shinylive does not work in self-contained HTML documents.
#|   Please set `embed-resources: false` in your metadata.
#| standalone: true
#| viewerHeight: 340
library(shiny)
library(bslib)

# Define the decision tree structure (removed don't know options)
decision_tree <- list(
  question = "Are you comparing means in your hypothesis test μ?",
  yes = list(
    question = "Do you have one sample or two? Click yes for one, no for two.",
    yes = list(
      question = "Brilliant, one sample. Do you know the population standard deviation σ?",
      yes = list(
        result = "You should use a Z-test."
      ),
      no = list(
        question = "Ok, so you don't know σ. Is your sample size n > 30?",
          yes = list(
            result = "You should use a Z-test."
          ),
          no = list(
            result = "You should use a t-test."
          )
        )
      ),
    no = list(
      question = "Ok, so you have two samples. Are they independent or are they paired? Click yes for independent, no for paired.",
      yes = list(
        question = "Ok, your two samples are independent. Do you know the population standard deviation σ for both samples?",
      yes = list(
        result = "You should use a Z-test."
      ),
      no = list(
        question = "Ok, so you don't know σ for both samples. Is your sample size n > 30?",
          yes = list(
            result = "You should use a two-sample Z-test."
          ),
          no = list(
            result = "You should use a two-sample t-test."
          )
        )
      ),
      no = list(
        result = "You should use a paired t-test."
      )
    )
  ),
  no = list(
    question = "Are you testing for variance?",
    yes = list(
      result = "You should use an F-test for variance."
      ),
    no = list(
      question = "Are you testing for goodness of fit?",
      yes = list(
        result = "You should use a chi-squared test for goodness of fit."
      ),
      no = list(
        question = "Are you testing for independence?",
          yes = list(
            result = "You should use a chi-squared test for independence."
          ),
          no = list(
            result = "Unfortunately this is not covered in the interactive figure; please start again."
          )
        )
      )
    )
  )

# Define button color hex codes
button_colors <- list(
  yes = "#3F6BB6",        # Green
  no = "#DB4315",         # Red
  back = "#9E9E9E",       # Gray
  start_over = "#FFCB00", # syellow
  result_bg = "#C0D6FF",  # Light green background for results
  result_border = "#3F6BB6", # Slightly darker green border for results
  result_text = "#000000"  # Dark green text for results
)


ui <- page_fluid(
  # Add some custom CSS to style buttons with hex colors
  tags$head(
    tags$style(HTML(
      paste0(
        ".yes-btn { background-color: ", button_colors$yes, "; border-color: ", button_colors$yes, "; color: white; }",
        ".no-btn { background-color: ", button_colors$no, "; border-color: ", button_colors$no, "; color: white; }",
        ".back-btn { background-color: ", button_colors$back, "; border-color: ", button_colors$back, "; color: white; }",
        ".start-over-btn { background-color: ", button_colors$start_over, "; border-color: ", button_colors$start_over, "; color: white; }",
        ".result-box { background-color: ", button_colors$result_bg, "; border-color: ", button_colors$result_border, "; color: ", button_colors$result_text, "; border: 1px solid; padding: 15px; border-radius: 5px; }"
      )
    ))
  ),
  card(
    card_header(
      h2("Hypothesis testing interactive flowchart", class = "text-center")
    ),
    card_body(
      uiOutput("question_ui"),
      uiOutput("result_ui"),
      div(
        class = "d-flex justify-content-between mt-4",
        actionButton("back_btn", "Back", icon = icon("arrow-left"), class = "back-btn"),
        actionButton("start_over_btn", "Start Over", icon = icon("refresh"), class = "start-over-btn")
      )
    )
  )
)

server <- function(input, output, session) {
  # Keep track of the path through the decision tree
  path_history <- reactiveVal(list())
  
  # Current node in the decision tree
  current_node <- reactiveVal(decision_tree)
  
  # Update the UI based on the current node
  output$question_ui <- renderUI({
    node <- current_node()
    if (is.null(node) || !hasName(node, "question")) {
      return(NULL)
    }
    
    div(
      h4(node$question, class = "mb-4"),
      div(
        class = "d-flex justify-content-center gap-2",
        actionButton("yes_btn", "Yes", class = "yes-btn"),
        actionButton("no_btn", "No", class = "no-btn")
      )
    )
  })
  
  output$result_ui <- renderUI({
    node <- current_node()
    if (is.null(node) || !hasName(node, "result")) {
      return(NULL)
    }
    
    div(
      class = "result-box", # Using custom class instead of alert-success
      h4("Recommendation:", class = "mb-3"),
      p(node$result)
    )
  })
  
  # Navigate to the next node based on user choice
  observeEvent(input$yes_btn, {
    node <- current_node()
    if (!is.null(node$yes)) {
      path_history(c(path_history(), list(node)))
      current_node(node$yes)
    }
  })
  
  observeEvent(input$no_btn, {
    node <- current_node()
    if (!is.null(node$no)) {
      path_history(c(path_history(), list(node)))
      current_node(node$no)
    }
  })
  
  # Go back to the previous question
  observeEvent(input$back_btn, {
    history <- path_history()
    if (length(history) > 0) {
      # Set current node to the last node in history
      current_node(history[[length(history)]])
      # Remove the last node from history
      path_history(history[-length(history)])
    }
  })
  
  # Start over - reset to the root of the decision tree
  observeEvent(input$start_over_btn, {
    current_node(decision_tree)
    path_history(list())
  })
}

shinyApp(ui = ui, server = server)

Further reading

This interactive element appears in Guide: Introduction to hypothesis testing. Please click this link to go to the guide.

Version history

v1.0: initial version created 12/24 by Ellie Trace as part of a University of St Andrews VIP project.

  • v1.1: updated to R Shiny interface by tdhc 04/25.

This work is licensed under CC BY-NC-SA 4.0.

Mailing List



Feedback

Your feedback is appreciated and useful. Feel free to leave a comment here,
but please be specific with any issues you encounter so we can help to resolve them
(for example, what page it occured on, what you tried, and so on).