Introduction

This tutorial investigates whether a strong first quarter is associated with winning an AFL match. Using 2023 AFL match data, I will calculate quarter-time scores, compare match outcomes, and use logistic regression to investigate the relationship.

1. Load the data

First, load the tidyverse package and import the CSV file. Make sure the CSV file is saved in your Team_A folder.

library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.5.3
## Warning: package 'ggplot2' was built under R version 4.5.3
## Warning: package 'tibble' was built under R version 4.5.3
## Warning: package 'tidyr' was built under R version 4.5.3
## Warning: package 'readr' was built under R version 4.5.3
## Warning: package 'purrr' was built under R version 4.5.3
## Warning: package 'dplyr' was built under R version 4.5.3
## Warning: package 'stringr' was built under R version 4.5.3
## Warning: package 'forcats' was built under R version 4.5.3
## Warning: package 'lubridate' was built under R version 4.5.3
afl <- read_csv("matches_2023 AFL.csv")

head(afl)
## # A tibble: 6 × 22
##   round_num venue     date                 year team_1_team_name team_1_q1_goals
##   <chr>     <chr>     <dttm>              <dbl> <chr>                      <dbl>
## 1 1         M.C.G.    2023-03-16 19:20:00  2023 Richmond                       1
## 2 1         M.C.G.    2023-03-17 19:40:00  2023 Geelong                        6
## 3 1         Docklands 2023-03-18 13:45:00  2023 North Melbourne                3
## 4 1         Adelaide… 2023-03-18 16:05:00  2023 Port Adelaide                  3
## 5 1         M.C.G.    2023-03-18 19:25:00  2023 Melbourne                      3
## 6 1         Carrara   2023-03-18 19:00:00  2023 Gold Coast                     2
## # ℹ 16 more variables: team_1_q1_behinds <dbl>, team_1_q2_goals <dbl>,
## #   team_1_q2_behinds <dbl>, team_1_q3_goals <dbl>, team_1_q3_behinds <dbl>,
## #   team_1_final_goals <dbl>, team_1_final_behinds <dbl>,
## #   team_2_team_name <chr>, team_2_q1_goals <dbl>, team_2_q1_behinds <dbl>,
## #   team_2_q2_goals <dbl>, team_2_q2_behinds <dbl>, team_2_q3_goals <dbl>,
## #   team_2_q3_behinds <dbl>, team_2_final_goals <dbl>,
## #   team_2_final_behinds <dbl>

2. Calculate match scores

In Australian rules football, a goal is worth six points and a behind is worth one point.

afl <- afl %>%
  mutate(
    team1_q1_points =
      team_1_q1_goals * 6 + team_1_q1_behinds,
    team2_q1_points =
      team_2_q1_goals * 6 + team_2_q1_behinds,
    team1_final_points =
      team_1_final_goals * 6 + team_1_final_behinds,
    team2_final_points =
      team_2_final_goals * 6 + team_2_final_behinds,
    q1_margin = team1_q1_points - team2_q1_points,
    final_margin = team1_final_points - team2_final_points
  )

3. Identify match outcomes

Team 1 is recorded as the winner when its final score is higher. Draws are excluded from the logistic regression.

afl <- afl %>%
  mutate(
    team1_win = case_when(
      final_margin > 0 ~ 1,
      final_margin < 0 ~ 0,
      TRUE ~ NA_real_
    )
  )

afl_model <- afl %>%
  filter(!is.na(team1_win))

4. Compare first-quarter performance

afl_model %>%
  mutate(
    q1_status = case_when(
      q1_margin > 0 ~ "Leading",
      q1_margin < 0 ~ "Trailing",
      TRUE ~ "Level"
    )
  ) %>%
  group_by(q1_status) %>%
  summarise(
    matches = n(),
    win_rate = mean(team1_win),
    .groups = "drop"
  )
## # A tibble: 3 × 3
##   q1_status matches win_rate
##   <chr>       <int>    <dbl>
## 1 Leading       117    0.718
## 2 Level           3    0.667
## 3 Trailing       94    0.404

The win rate represents the proportion of matches won by Team 1 within each first-quarter group.

5. Visualise match outcomes

ggplot(afl_model, aes(x = q1_margin, y = team1_win)) +
  geom_jitter(height = 0.05, width = 0, alpha = 0.5) +
  labs(
    title = "First-Quarter Margin and AFL Match Results",
    x = "Team 1's first-quarter points margin",
    y = "Team 1 won (1 = yes, 0 = no)"
  ) +
  theme_minimal()

6. Fit a logistic regression model

Logistic regression estimates the relationship between the first-quarter points margin and the probability of winning.

model <- glm(
  team1_win ~ q1_margin,
  data = afl_model,
  family = binomial
)

summary(model)
## 
## Call:
## glm(formula = team1_win ~ q1_margin, family = binomial, data = afl_model)
## 
## Coefficients:
##             Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  0.23782    0.15271   1.557    0.119    
## q1_margin    0.06232    0.01127   5.528 3.23e-08 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 291.24  on 213  degrees of freedom
## Residual deviance: 249.93  on 212  degrees of freedom
## AIC: 253.93
## 
## Number of Fisher Scoring iterations: 4

7. Calculate the odds ratio

exp(coef(model))
## (Intercept)   q1_margin 
##    1.268475    1.064302

The odds ratio for the first-quarter margin indicates how the odds of winning change with each additional point in the first-quarter margin.

8. Predict winning probabilities

new_margins <- tibble(
  q1_margin = seq(-30, 30, by = 5)
)

new_margins$predicted_probability <- predict(
  model,
  newdata = new_margins,
  type = "response"
)

new_margins
## # A tibble: 13 × 2
##    q1_margin predicted_probability
##        <dbl>                 <dbl>
##  1       -30                 0.164
##  2       -25                 0.211
##  3       -20                 0.267
##  4       -15                 0.332
##  5       -10                 0.405
##  6        -5                 0.482
##  7         0                 0.559
##  8         5                 0.634
##  9        10                 0.703
## 10        15                 0.764
## 11        20                 0.815
## 12        25                 0.858
## 13        30                 0.892
ggplot(
  new_margins,
  aes(x = q1_margin, y = predicted_probability)
) +
  geom_line() +
  labs(
    title = "Predicted Probability of Winning",
    x = "First-quarter points margin",
    y = "Predicted probability of Team 1 winning"
  ) +
  theme_minimal()

9. Results and interpretation

In this dataset, Team 1 won approximately 71.8% of non-drawn matches when leading at quarter time, compared with 40.4% when trailing.

The logistic regression coefficient for first-quarter margin was positive, indicating that a larger first-quarter lead was associated with higher odds of winning.

10. Limitations and conclusion

This analysis identifies an association, not proof that a strong first quarter causes a team to win. It uses one season of match data and only one predictor. Other factors, including team strength and match conditions, may also influence the final result.

The findings suggest that first-quarter performance is useful for understanding match outcomes, but it cannot explain every win or loss.