Introduction

I want to analyze the impact of managers in post-SAF era. The impact I want to see incorporates the aspects of offensive, defensive, and consistency.

I have consolidated the data I previously collected from various sources into a single data frame.

The metrics I use are: - Offensive: Team Goal Minus Penalty Kick Per 90 - Defensive: 1 - Opponent Goal Minus Penalty Kick Per 90 - Consistency: Points Per Game

Preparation

Load Data and Library

library(tidyverse)
library(lubridate)
library(reactable)
library(car)
library(lmtest)
the_data <- readRDS("main_df_imputed.RDS")

Explore

The data is small, it has been processed and consolidated from various tables prior. Missing data also has been handled. Let’s explore the data.

the_data %>% reactable::reactable(resizable = T) 
  • the PPG value in this table is final PPG value, and it was not separate actual value for every season, but the actual final ppg valuation at the end of each manager’s term.
glimpse(the_data)
## Rows: 8
## Columns: 6
## $ season_end_year     <dbl> 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021
## $ staff_name          <fct> David Moyes, Louis van Gaal, Louis van Gaal, José ~
## $ ppg                 <dbl> 1.73, 1.81, 1.81, 1.97, 1.97, 1.79, 1.79, 1.79
## $ Team_G_minus_PK_Per <dbl> 1.53, 1.50, 1.13, 1.34, 1.74, 1.47, 1.45, 1.58
## $ Opp_G_minus_PK_Per  <dbl> 0.92885, 0.87000, 0.82000, 0.63000, 0.66000, 1.180~
## $ Rk                  <int> 7, 4, 5, 6, 2, 6, 3, 2
the_data <- 
  the_data %>% mutate(
    season_end_year = as_factor(season_end_year)
  )

Count of Seasons by Managers

t <- "Count of Seasons by Managers"
ts <- "*by Full Time Managers Post-SAF"
tx <- "Count of Seasons"
ty <- "Managers"

theme_setting <- 
  theme_minimal(base_size = 10) +
  theme(
    axis.title.y = element_text(margin = margin(0,15,0,0, unit = "pt")),
    axis.title.x = element_text(hjust = 0),
    title =
      element_text(
        size = rel(1.2),
        face = "plain"
        ),
    plot.title = 
      element_text(
        size = rel(1.5),
        face = "bold",
        margin = margin(t = 15, b = 15, unit = "pt")
      ),
    plot.margin = margin(20, 35, 20, 25, unit = "pt")
    )

the_data %>% 
  ggplot(aes(y = staff_name, fill = ..count.. ))+
  geom_bar(position = position_stack(),show.legend = FALSE)+
  geom_text(aes(label = ..count..),stat = "count", hjust = 4)+
  scale_x_discrete(expand = expansion(mult = c(0,0.25)))+
  scale_y_discrete(expand = expansion(mult = c(0.3,0.2)))+
  labs(title = t, x = tx, y = ty, caption = ts)+
  scale_fill_gradient(low = "grey", high = "lightslateblue")+
  theme_setting

So far, Ole Gunnar Solskjaer is the only managers that were given more than 2 seasons to handle Man Utd.

Count of Rank Achieved

t <- "Count of Ranks Achieved"
ts <- "*by Full Time Managers Post-SAF"
tx <- "Count of Seasons"
ty <- "Ranks"

theme_setting <- 
  theme_minimal(base_size = 10) +
  theme(
    axis.title.y = element_text(margin = margin(0,15,0,0, unit = "pt")),
    axis.title.x = element_text(hjust = 0),
    title =
      element_text(
        size = rel(1.2),
        face = "plain"
        ),
    plot.title = 
      element_text(
        size = rel(1.5),
        face = "bold",
        margin = margin(t = 15, b = 15, unit = "pt")
      ),
    plot.margin = margin(20, 35, 20, 25, unit = "pt")
    )

the_data %>% 
  ggplot(aes(y = factor(Rk) %>% fct_rev(), fill = ..count.. ))+
  geom_bar(position = position_stack(),show.legend = FALSE)+
  geom_text(aes(label = ..count..),stat = "count", hjust = 4)+
  scale_x_discrete(expand = expansion(mult = c(0.,0.15)))+
  scale_y_discrete(expand = expansion(mult = c(0.3,0.2)))+
  labs(title = t, x = tx, y = ty, caption = ts)+
  scale_fill_gradient(low = "grey", high = "lightslateblue")+
  theme_setting

After SAF’s departure, Man Utd never reached the first rank, only managed to reach second place twice.

Managers Timeline

t <- "Managers Timeline and Ranks"
ts <- "*by Full Time Managers Post-SAF"
tx <- "Seasons"
ty <- "Ranks"
tm <- "Managers"

theme_setting <- 
  theme(text = element_text(size = 10))+
  theme(
    axis.title.y = element_text(margin = margin(0,15,0,0, unit = "pt")),
    axis.title.x = element_text(hjust = 0, margin = margin(t=10)),
    title =
      element_text(
        size = rel(1.2),
        face = "plain"
        ),
    plot.title = 
      element_text(
        size = rel(1.5),
        face = "bold",
        margin = margin(t = 15, b = 15, unit = "pt")
      ),
    plot.margin = margin(20, 35, 20, 25, unit = "pt")
    )+
  theme(panel.background = element_blank())

the_data %>% 
  ggplot(
    aes(
      x = season_end_year,
      y = desc(Rk),
      col = staff_name
      )
  )+
  labs(title = t, x = tx, y = ty, caption = ts)+
  geom_line(aes(group = staff_name))+
  geom_point(size = 3)+
  scale_color_manual(
    values = c("lightblue", "slateblue", "purple", "darkblue")
  )+
  theme(
    legend.position = c(0.015,1),
    legend.justification = c(0,0.7),
    legend.background = element_blank(),
    legend.text = element_text(size = 7),
    legend.title = element_text(size = 8)
    )+
  guides(
      col = guide_legend(
        title = NULL,
        keywidth = 0.05,      # Adjust the width of the legend key
        keyheight = 0.05,     # Adjust the height of the legend key
        nrow = 3,            # Set the number of rows in the legend
        byrow = TRUE         # Arrange items by row
      )
  )+
  theme_setting

Mourinho and Ole managed to have reached the second place, the rest fell short. The general outlook seems improving bit by bit, but not as good as the fans would love to see.

Manager’s Points Per Game.

t <- "Points Per Game Comparison by Manager"
ts <- "*by Full Time Managers Post-SAF"
tx <- "PPG"
ty <- "Managers"
avg_avgppg <- the_data %>% summarise(mean(ppg)) %>% pull()

theme_setting <- 
  theme_minimal(base_size = 10)+
  theme(
    axis.title.y = element_text(margin = margin(0,15,0,0, unit = "pt")),
    axis.title.x = element_text(hjust = 0),
    title =
      element_text(
        size = rel(1.2),
        face = "plain"
        ),
    plot.title = 
      element_text(
        size = rel(1.35),
        face = "bold",
        margin = margin(t = 15, b = 15, unit = "pt"),
        hjust = 2
      ),
    plot.margin = margin(20, 50, 20, 25, unit = "pt")
    )

the_data %>% 
  ggplot(aes(x = ppg, y = reorder(staff_name, ppg))) +
  geom_point(size = 4.5, color = "darkblue") +
  geom_point(size = 2, color = "lightslateblue") +
  geom_vline(
    xintercept = avg_avgppg,
    col = "slateblue",
    size = 1,
    linetype = "dashed"
  )+
  annotate(
    geom = "text", 
    angle = 90,
    x = avg_avgppg + 0.006,
    y = "Louis van Gaal",
    label = paste("Average: ", avg_avgppg),
    alpha = 0.4
    )+
  labs(title = t, x = tx, y = ty, caption = ts)+
  theme_setting

Mourinho consistency is above the average.

Team Goal Minus Penalty Kick Per 90 by Manager

t <- "Team Goal Minus Penalty Kick Per 90 by Manager"
ts <- "*by Full Time Managers Post-SAF"
tx <- "Season End Year"
ty <- "Team GMP9"

theme_setting <- 
  theme_minimal(base_size = 10)+
  theme(
    axis.title.y = element_text(margin = margin(0,15,0,0, unit = "pt")),
    axis.title.x = element_text(hjust = 0, margin = margin(t = 10, unit = "pt")),
    title =
      element_text(
        size = rel(1.2),
        face = "plain"
        ),
    plot.title = 
      element_text(
        size = rel(1.35),
        face = "bold",
        margin = margin(t = 15, b = 15, unit = "pt"),
        hjust = 0
      ),
    plot.margin = margin(20, 50, 20, 25, unit = "pt")
    )

the_data %>% 
  ggplot()+
  geom_col(aes(x = season_end_year, y=Team_G_minus_PK_Per,fill = staff_name))+
  scale_fill_manual(
    values = c(
      "David Moyes" = "lightblue",
      "Louis van Gaal" = "slateblue",
      "José Mourinho" = "purple",
      "Ole Gunnar Solskjaer" = "darkblue"
      ))+
  theme_setting+
  theme(
    legend.position = c(0.010,1),
    legend.justification = c(0,0.7),
    legend.background = element_blank(),
    legend.text = element_text(size = 7),
    legend.title = element_text(size = 8)
    )+
  guides(
      fill = guide_legend(
        title = NULL,
        keywidth = 0.05,      # Adjust the width of the legend key
        keyheight = 0.05,
        byrow = T,
        nrow = 2,
        override.aes = list(size = 3)
      )
  )+
  labs(title = t, x = tx, y = ty, caption = ts)

Mourinho’s team managed to reach highest offensive capacity.

Opponent Goal Minus Penalty Kick Per 90 by Manager

t <- "Opponent Goal Minus Penalty Kick Per 90 by Manager"
ts <- "*by Full Time Managers Post-SAF"
tx <- "Season End Year"
ty <- "Team GMP9"

theme_setting <- 
  theme_minimal(base_size = 10)+
  theme(
    axis.title.y = element_text(margin = margin(0,15,0,0, unit = "pt")),
    axis.title.x = element_text(hjust = 0, margin = margin(t = 10, unit = "pt")),
    title =
      element_text(
        size = rel(1.2),
        face = "plain"
        ),
    plot.title = 
      element_text(
        size = rel(1.35),
        face = "bold",
        margin = margin(t = 15, b = 15, unit = "pt"),
        hjust = 0.8
      ),
    plot.margin = margin(20, 55, 20, 25, unit = "pt")
    )

the_data %>% 
  ggplot()+
  geom_col(aes(x = season_end_year, y=Opp_G_minus_PK_Per,fill = staff_name))+
  scale_fill_manual(
    values = c(
      "David Moyes" = "lightblue",
      "Louis van Gaal" = "slateblue",
      "José Mourinho" = "purple",
      "Ole Gunnar Solskjaer" = "darkblue"
      ))+
  theme_setting+
  theme(
    legend.position = c(0.010,1),
    legend.justification = c(0,0.7),
    legend.background = element_blank(),
    legend.text = element_text(size = 7),
    legend.title = element_text(size = 8)
    )+
  guides(
      fill = guide_legend(
        title = NULL,
        keywidth = 0.05,      # Adjust the width of the legend key
        keyheight = 0.05,
        byrow = T,
        nrow = 2,
        override.aes = list(size = 3)
      )
  )+
  labs(title = t, x = tx, y = ty, caption = ts)

Ole had reached the best defensive solidity in 2019 season end year.

Managers Impact Comparison

I’m using Team Goal Minus Penalty Kick Per 90 (let’s call it GMP9) as a metric to evaluate team’s offensive capacity. I use the inverse of Opponent GMP9 as to evaluate defensive prowess. I added the summed up PPG of each manager’s career as a factor as well to indicate their consistency.

t <- "Managers Impact on Team Performance"
ts <- "*by Full Time Managers Post-SAF"
tx <- "Offensive"
ty <- "Defensive"
avg_avgoff <- the_data %>% 
  summarise(avg_off = mean(Team_G_minus_PK_Per)) %>% pull()
avg_avgdef <- the_data %>% 
  summarise(avg_def = mean(1 - Opp_G_minus_PK_Per)) %>% pull()
avg_avgcon <- the_data %>% 
  summarise(avg_con = mean(ppg)) %>% pull()

the_data %>% 
  group_by(staff_name) %>% 
  summarise(
    avg_off = mean(Team_G_minus_PK_Per),
    avg_def = mean(1 - Opp_G_minus_PK_Per),
    avg_con = mean(ppg)
            ) %>% 
  ggplot() + 
  geom_point( 
    aes(
      x = avg_off, 
      y = avg_def,
      size = avg_con * 10,
      col = staff_name,
    ),
    show.legend = FALSE)+
  labs(title = t, x = tx, y = ty, caption = ts)+
  geom_text(
    aes(
      label = staff_name,
      x = avg_off, 
      y = avg_def),
    nudge_y = ,
    nudge_x = -0.035,
    size = 2.3
  )+
  geom_vline(
    xintercept = avg_avgoff,
    linetype = "dotted",
    size = 0.1
  )+
  geom_hline(
    yintercept = avg_avgdef,
    linetype = "dotted",
    size = 0.1
  )+
  geom_point(
    inherit.aes = FALSE,
    aes(
      x = avg_avgoff,
      y = avg_avgdef,
      size = avg_avgcon * 10
    ),
    show.legend = FALSE
  )+
  annotate(
    geom = "text",
    x = avg_avgoff - 0.007,
    y = avg_avgdef + 0.06,
    angle = 90,
    label = "average",
    alpha = 0.4
  )+
  xlim(c(1.2,1.6))+
  ylim(c(-0.07,0.5))

Analysis

Is the difference between Louis van Gaal, Ole GUnnar Solskjaer, David Moyes, and Jose Mourinho significant?

the_metric <- 
the_data %>% 
  transmute(
    manager = staff_name,
    metric = (Team_G_minus_PK_Per * (1 - Opp_G_minus_PK_Per)) * ppg
  ) %>% arrange(desc(metric)) 

the_metric  
##                manager     metric
## 1        José Mourinho  1.1654520
## 2        José Mourinho  0.9767260
## 3 Ole Gunnar Solskjaer  0.4152800
## 4       Louis van Gaal  0.3681540
## 5       Louis van Gaal  0.3529500
## 6          David Moyes  0.1883269
## 7 Ole Gunnar Solskjaer  0.0000000
## 8 Ole Gunnar Solskjaer -0.4736340

ANOVA

Check Assumptions

Homogeneity of Variance

leveneTest(metric ~ manager, data = the_metric)
## Levene's Test for Homogeneity of Variance (center = median)
##       Df F value Pr(>F)
## group  3  1.3196 0.3847
##        4

There is not enough evidence to reject the null hypothesis that the variance across the group are homogenous.

Normality of Residuals

res_aov <-  aov(metric ~ manager, data = the_metric)
aov_residuals <- residuals(object = res_aov)
plot(res_aov, 2)

shapiro.test(x = aov_residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  aov_residuals
## W = 0.87833, p-value = 0.1815

There is not enough evidence to suggest that the residuals are not normal.

Independence

This is where things fail. Each manager depends on previous management, and many players are playing for several managers. Anthony Martial for example, he was bought in Louis van Gaal era, and is still playing for Erik Ten Hag now. So we can’t use ANOVA because there is a lack of independence between managers.

Kruskal-Wallis Test

This is a nonparametric approach to determine whether or not there is a significant difference between the metrics by the managers. This approach is recommended when statistical assumptions requirement for ANOVA are not fulfilled.

  • Null Hypothesis: There is a difference of metric
  • Alternative Hypothesis:
kruskal.test(metric ~ manager, data = the_metric)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  metric by manager
## Kruskal-Wallis chi-squared = 4.5, df = 3, p-value = 0.2123

The p-value is higher than 0.05, this means that there is not enough evidence to suggest that there is significant different between managers on the metric I chose to represent their impact to team’s performance in offense, defense, and consistency.

In short, they’re all shit.

Or not shit.

Or they’re all good, but there’s something much sinister going on beneath?