Building a Small-Sided Games (SSG) Pitch Dimensions Calculator App
This application is designed to help sports scientists, coaches, and practitioners optimize theArea perPlayer (ApP)and calculate the ideal pitch dimensions for training and matches.
More Resources Available My Website. The full Area per Player article is available here.
Here is the link to the ApP Calculator.
Building a Small-Sided Games (SSG) Pitch Dimensions Calculator App for Sport Scientists
Welcome to this tutorial on how to replicate a small-sided games (SSG) pitch dimensions calculator app using R Shiny. This application is designed to help sports scientists, coaches, and practitioners optimize the Area per Player (ApP) and calculate the ideal pitch dimensions for training and matches.
In this tutorial, we will learn how to use R to build a simple, interactive web application using the Shiny framework. We'll walk through each part of the code and explain its purpose. Additionally, we will discuss how the app is tied to the research of Andrea Riboli et al. (2020), who explored how the ApP in small-sided games can affect the performance and physiological demands of players.
Research Context:
In soccer, small-sided games (SSGs) are a common training method to replicate the conditions of a real match, improving players' technical skills, fitness, and tactical understanding. The Area per Player (ApP) is a critical variable in designing SSGs. Research by Riboli et al. (2020) showed that adjusting ApP can influence players' physical exertion, including their high speed running, acceleration, deceleration, and overall distance covered.
By the end of this tutorial, we will have built an interactive Shiny app that allows us to:
- Input the number of players and the pitch dimensions to calculate the Area per Player.
- Calculate the required pitch dimensions based on a specified area per player.
This tutorial is targeted at beginner R programmers with a focus on sport science, and we will explain every line of code to help us understand the key concepts.
Step 1: Setting Up Our R Environment
To start, we'll need to install some R packages that will enable us to build this app. The Shiny framework allows us to create interactive web applications in R, and the shinydashboard package provides an easy way to create structured, dashboard-style interfaces.
Installing Required Packages
Before we begin coding, we need to install the necessary packages by running the following commands in our R console:
install.packages("shiny") # Core package for building Shiny apps
install.packages("shinydashboard") # Dashboard layout for Shiny apps
install.packages("shinythemes") # Pre-built themes for Shiny apps
After installation, we can load these packages into our R script:
library(shiny)
library(shinydashboard)
library(shinythemes)
What Does Each Package Do?
shiny
: The core package that powers the app's interactivity. It allows us to interact with inputs (e.g., text boxes, sliders) and display outputs (e.g., calculated results) dynamically.shinydashboard
: Provides a simple layout to create dashboards with a header, sidebar, and body. It's especially useful for organizing content in Shiny apps.shinythemes
: Offers pre-designed themes that make our Shiny app look polished and professional without needing to write custom CSS.
Step 2: Defining the Core Calculation Functions
The app will need two main calculation functions:
calculate_pitch_area_per_player
: This function will calculate the area available for each player based on the number of players and pitch dimensions (length and width).pitch_dimensions
: This function will calculate the required pitch dimensions (length and width) to achieve a specific area per player.
2.1 Function to Calculate Area per Player
This function takes the total number of players, pitch length, and pitch width as inputs.
It calculates the total pitch area (length × width) and divides it by the number of players to determine how much area each player will have.
calculate_pitch_area_per_player <- function(total_players, pitch_length, pitch_width) {
# Calculate the total pitch area
pitch_area <- pitch_length * pitch_width
# Calculate area per player by dividing the total pitch area by the number of players
area_per_player <- pitch_area / total_players
return(list(
area_per_player = round(area_per_player, 0), # Round the result for better presentation
pitch_area = round(pitch_area, 0) # Round the total pitch area
))
}
Breakdown of the Function
- Input Parameters:
total_players
: The total number of players on the pitch.pitch_length
: The length of the pitch in meters.pitch_width
: The width of the pitch in meters.
- Steps:
- Calculate the total pitch area by multiplying the pitch length by the pitch width.
- Calculate the area per player by dividing the total pitch area by the number of players.
- Return the results as a list, where the values are rounded for clarity.
2.2 Function to Calculate Pitch Dimensions from Area per Player
This second function works in reverse.
Given the area per player and the total number of players, it calculates the required pitch length and width.
pitch_dimensions <- function(area_per_player, num_players) {
# Define the ratio of pitch width to length (standard in soccer fields)
width_length_ratio = 0.647 # This is based on typical soccer field proportions
# Calculate the total pitch area required to achieve the specified area per player
pitch_area_m2 <- area_per_player * num_players
# Calculate the length and width of the pitch based on the ratio
pitch_length_m <- sqrt(pitch_area_m2 / width_length_ratio)
pitch_width_m <- pitch_area_m2 / pitch_length_m
return(list(
pitch_length_m = round(pitch_length_m, 0), # Round for clarity
pitch_width_m = round(pitch_width_m, 0),
pitch_area_m2 = round(pitch_area_m2, 0)
))
}
Breakdown of the Function
- Input Parameters:
area_per_player
: The area each player will have in square meters.num_players
: The number of players on the pitch.
- Steps:
- Calculate the total pitch area required to achieve the specified area per player by multiplying the area per player by the number of players.
- Using the predefined ratio of width to length (based on soccer field proportions), calculate the pitch dimensions.
- Return the results (pitch length, width, and total area).
Step 3: Building the User Interface (UI)
Now that we have the functions that will perform the necessary calculations, we can build the User Interface (UI) of the app.
The UI will include:
- Input fields for the number of players and pitch dimensions.
- Dropdown menus for selecting the type of calculation.
- Output boxes to display the results of the calculations.
3.1 The UI Layout with shinydashboard
The UI will be built using the shinydashboard package, which allows us to create a clean and organized layout with a header, sidebar, and main body.
ui <- dashboardPage(
dashboardHeader(title = "Small Sided Games Pitch Dimensions Calculator"),
dashboardSidebar(
sidebarMenu(
menuItem("Calculator", tabName = "calculator", icon = icon("calculator")),
menuItem("SSG Mind Map Download", tabName = "images", icon = icon("image")),
menuItem("How to Guide", tabName = "guide", icon = icon("info-circle"))
)
),
dashboardBody(
theme = shinytheme("united"), # Apply a theme for better aesthetics
tabItems(
tabItem(tabName = "calculator",
fluidRow(
column(width = 12, box(
title = "Input Parameters", status = "primary", solidHeader = TRUE,
numericInput("total_players", "Total Players:", value = 22), # Default value
numericInput("pitch_length", "Pitch Length (m):", value = 110),
numericInput("pitch_width", "Pitch Width (m):", value = 65)
))
),
fluidRow(
valueBoxOutput("area_per_player_box"),
valueBoxOutput("pitch_area_box")
)
)
)
)
)
Breakdown of the UI Code
dashboardPage()
: The main function for creating the layout. It has three parts: the header, sidebar, and body.dashboardHeader()
: The top header of the page, where we can add the title or logo.dashboardSidebar()
: The sidebar containing navigation items (such as links to different sections of the app).dashboardBody()
: The main content area where we will place the input fields, buttons, and output boxes.
- Input Fields:
numericInput()
: Creates a numeric input field where users can enter values for the number of players and the pitch dimensions.
- Output Boxes:
valueBoxOutput()
: Displays calculated values in a visually distinct box (e.g., showing the area per player and pitch area).
Step 4: Building the Server Logic
The server function defines the behavior of the app.
It specifies how the app responds to user inputs and updates the output dynamically.
4.1 Server Logic for Calculating Results
The server code listens for changes in the input fields and updates the outputs accordingly.
server <- function(input, output) {
# Create a reactive expression that listens to changes in inputs
results <- reactive({
# Check which function to use based on user selection
if (input$function_choice == "calculate_pitch_area_per_player") {
calculate_pitch_area_per_player(input$total_players, input$pitch_length, input$pitch_width)
} else if (input$function_choice == "pitch_dimensions") {
pitch_dimensions(input$area_per_player, input$num_players)
} else {
NULL # Return NULL if no valid choice
}
})
# Render output values
output$area_per_player_box <- renderValueBox({
res <- results() # Get the calculated results
valueBox(
value = res$area_per_player, # Display the area per player
subtitle = "Area per Player (m²/player)",
icon = icon("running"),
color = "purple"
)
})
output$pitch_area_box <- renderValueBox({
res <- results() # Get the calculated results
valueBox(
value = res$pitch_area, # Display the total pitch area
subtitle = "Pitch Area (m²)",
icon = icon("street-view"),
color = "purple"
)
})
}
Breakdown of Server Logic
reactive()
: This function creates a reactive expression that updates automatically whenever its inputs change (e.g., when the number of players or pitch dimensions are modified).renderValueBox()
: These functions display the results of the calculations in value boxes.
When the input values change, the app automatically re-renders the outputs based on the new calculations.
Step 5: Running the Shiny App
Now that we've defined both the UI and server components, we can run the app using the shinyApp()
function:
shinyApp(ui = ui, server = server)
Running this function will launch the Shiny app in our default web browser.
We'll be able to interact with it by entering different values for the number of players and pitch dimensions.
Step 6: Enhancing the App and Adding Research Context
Incorporating research context is essential to providing users with a deeper understanding of the calculations and their practical implications.
As mentioned earlier, the Area per Player (ApP) is critical for replicating match demands in small-sided games.
You can add text, references, and explanations to your app to explain the underlying research.
For instance, the following HTML code can be added to our app's UI to provide users with a link to the study by Andrea Riboli et al. (2020).
HTML(
"<p>For more information on the concept of Area per Player, check out the research by Riboli et al. (2020):
<a href='https://doi.org/10.1371/journal.pone.0229194'>Area per Player in Small-Sided Games</a></p>"
)
This provides context to users and helps them understand why the calculations are important for their training purposes.
Sign Up below for the full r script for the shiny app!!