What Factor is the most Important in Determining Success in the Premier League
Author
Hamza Nuru
What factor is the most important in determining success in the English Premier League?
Success in the Premier League is associated with having world-class player, a strong squad depth, and effective tactics. In this project will discover how these factors contribute to success in the English Premier League.
I anazlyed data for the 2024/2025 Premier League season, by combining individual player statistics with match results to find a relationship between performance and league points.
This project involved combining multiple variables to create new ones, and they are listed as follows:
Star-player Dependence: (Team, player names, goals, assists) how much of the goals were scored by the top 3 goalscorers.
Squad depth: (Team, players, minutes) how many players have played over 900 minutes.
Attacking Score: (shots on target, successful final third passes, assists, carries ending with shots) Score to observe the tactics
Defense Score: (Tackles, interceptions, blocks, possession won,) score to observe the tactics.
Hypothesis: Star players, squad depth and tactics will determine number og league points ofr teams in the premier league.
We start off by loading the libraries necessary, as well as the datasets.
library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.2.1 ✔ readr 2.2.0
✔ forcats 1.0.1 ✔ stringr 1.6.0
✔ ggplot2 4.0.3 ✔ tibble 3.3.1
✔ lubridate 1.9.5 ✔ tidyr 1.3.2
✔ purrr 1.2.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(plotly)
Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':
last_plot
The following object is masked from 'package:stats':
filter
The following object is masked from 'package:graphics':
layout
library(ggplot2)library(dplyr)library(ggimage)
obtained from Football-Data.co.uk
matches <- readr::read_csv("season-2425.csv")
Rows: 380 Columns: 22
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (5): HomeTeam, AwayTeam, FTR, HTR, Referee
dbl (16): FTHG, FTAG, HTHG, HTAG, HS, AS, HST, AST, HF, AF, HC, AC, HY, AY,...
date (1): Date
ℹ 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.
head(matches)
# A tibble: 6 × 22
Date HomeTeam AwayTeam FTHG FTAG FTR HTHG HTAG HTR Referee HS
<date> <chr> <chr> <dbl> <dbl> <chr> <dbl> <dbl> <chr> <chr> <dbl>
1 2024-08-16 Man Uni… Fulham 1 0 H 0 0 D R Jones 14
2 2024-08-17 Ipswich Liverpo… 0 2 A 0 0 D T Robi… 7
3 2024-08-17 Arsenal Wolves 2 0 H 1 0 H J Gill… 18
4 2024-08-17 Everton Brighton 0 3 A 0 1 A S Hoop… 9
5 2024-08-17 Newcast… Southam… 1 0 H 1 0 H C Paws… 3
6 2024-08-17 Nott'm … Bournem… 1 1 D 1 0 H M Oliv… 14
# ℹ 11 more variables: AS <dbl>, HST <dbl>, AST <dbl>, HF <dbl>, AF <dbl>,
# HC <dbl>, AC <dbl>, HY <dbl>, AY <dbl>, HR <dbl>, AR <dbl>
Obtained from: Ahmed Gaballah, sources obtained from Premier League official statistics, Opta/StatsPerform and Fbref.
Rows: 562 Columns: 57
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (11): Player Name, Club, Nationality, Position, Conversion %, Passes%, C...
dbl (46): Appearances, Minutes, Goals, Assists, Shots, Shots On Target, Big ...
ℹ 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.
head(players)
# A tibble: 6 × 57
`Player Name` Club Nationality Position Appearances Minutes Goals Assists
<chr> <chr> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 Ben White Arsenal England DEF 17 1198 0 2
2 Bukayo Saka Arsenal England MID 25 1735 6 10
3 David Raya Arsenal Spain GKP 38 3420 0 0
4 Declan Rice Arsenal England MID 35 2833 4 7
5 Ethan Nwaneri Arsenal England MID 26 889 4 0
6 Gabriel Jesus Arsenal Brazil FWD 17 603 3 0
# ℹ 49 more variables: Shots <dbl>, `Shots On Target` <dbl>,
# `Conversion %` <chr>, `Big Chances Missed` <dbl>, `Hit Woodwork` <dbl>,
# Offsides <dbl>, Touches <dbl>, Passes <dbl>, `Successful Passes` <dbl>,
# `Passes%` <chr>, Crosses <dbl>, `Successful Crosses` <dbl>,
# `Crosses %` <chr>, `fThird Passes` <dbl>, `Successful fThird Passes` <dbl>,
# `fThird Passes %` <chr>, `Through Balls` <dbl>, Carries <dbl>,
# `Progressive Carries` <dbl>, `Carries Ended with Goal` <dbl>, …
Then, we sort the clubs, from the two datasets, and make sure they are named the same way.
This chunk is important as the player dataset has a variable called club, and it has to be renamed to Team to match the variable with the matches datasets.
players <- players %>%rename(Team = Club)
Here, we make sure the values of the variables are named consistently.
Now, that we have cleaned and combined our datasets, we will start calculating star player dependence and squad depth variable.
On this chunk, we are adding a new variable called “GA”, which is the sum of goals and assists., then displaying the 5 players with the most contribution. These are our star players.
# A tibble: 20 × 6
Team TotalGoals Top3Goals StarDependence SquadDepth TotalPlayers
<chr> <dbl> <dbl> <dbl> <int> <int>
1 Arsenal 67 25 37.3 16 25
2 Aston Villa 61 31 50.8 16 27
3 Bournemouth 24 13 54.2 15 29
4 Brentford 54 44 81.5 14 28
5 Brighton & Hove … 63 30 47.6 17 30
6 Chelsea 63 32 50.8 16 28
7 Crystal Palace 51 30 58.8 15 26
8 Everton 41 21 51.2 18 26
9 Fulham 41 23 56.1 16 26
10 Ipswich Town 23 10 43.5 17 30
11 Leicester City 28 18 64.3 17 31
12 Liverpool 72 45 62.5 15 24
13 Manchester City 71 36 50.7 18 31
14 Manchester United 38 22 57.9 16 30
15 Newcastle United 66 40 60.6 15 23
16 Nottingham Forest 57 33 57.9 13 23
17 Southampton 23 9 39.1 16 34
18 Tottenham Hotspur 50 25 50 19 31
19 West Ham United 31 18 58.1 16 28
20 Wolverhampton Wa… 39 22 56.4 16 32
Now, we will be calculating wins, losses, and league points of the teams.
We start of by calculating the results of teams from home. FTR stands for Full-Time Result, with H indicating the home team winning, D for Draw, and A for away team winning.
# A tibble: 20 × 6
Team Wins Draws Losses Points WinPercentage
<chr> <int> <int> <int> <dbl> <dbl>
1 Liverpool 25 9 4 84 65.8
2 Arsenal 20 14 4 74 52.6
3 Manchester City 21 8 9 71 55.3
4 Chelsea 20 9 9 69 52.6
5 Aston Villa 19 9 10 66 50
6 Newcastle United 20 6 12 66 52.6
7 Nottingham Forest 19 8 11 65 50
8 Brighton & Hove Albion 16 13 9 61 42.1
9 Bournemouth 15 11 12 56 39.5
10 Brentford 16 8 14 56 42.1
11 Fulham 15 9 14 54 39.5
12 Crystal Palace 13 14 11 53 34.2
13 Everton 11 15 12 48 28.9
14 West Ham United 11 10 17 43 28.9
15 Manchester United 11 9 18 42 28.9
16 Wolverhampton Wanderers 12 6 20 42 31.6
17 Tottenham Hotspur 11 5 22 38 28.9
18 Leicester City 6 7 25 25 15.8
19 Ipswich Town 4 10 24 22 10.5
20 Southampton 2 6 30 12 5.26
Now, We combine team results with player statistics. This will finally allow us to view the players contribution to their teams, so factors like Star Dependence and squad Depth can be feasible to study.
Now, we are going to visualize our star players’ contributions to their teams. with an interactive scatterplot that displays team name, star dependence, and league points.
For this visualization, I’m using the crests of the teams to show their star dependence. I went out of my way to do this to use team crests as points. I used a folder full of png pictures in my file path, and named them the same name as the team names to identify which on was which
Do teams with greater squad depth earn more league points?
Players who have played more than 900 minutes of football will be automatically part of the players usual squad. The higher the number, the bigger the depth. The more players available, the less injuries, and the better the performance.
Below is an interactive graph showing squad depth, as well as star dependence.
Now that we have reviewed squad depth, we move on to tactics.
We will try to figure out if attacking or defensive tactics are prefferable to win more matches.
From the players data set, we will use the following variables: Attacking Variables: Shots On Targetm Succesful fThird Passes, Carries Ended with Shot, Assists.
Defensive Variables: Interceptions, Tackles, Blocks, Possession won
Call:
lm(formula = Points ~ StarDependence + SquadDepth + AttackScore +
DefenseScore, data = premier_league)
Residuals:
Min 1Q Median 3Q Max
-41.399 -7.423 -1.170 12.731 30.252
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 125.73719 77.92494 1.614 0.127
StarDependence -0.03529 0.49679 -0.071 0.944
SquadDepth -4.45267 4.00240 -1.112 0.283
AttackScore 10.48135 6.72827 1.558 0.140
DefenseScore 1.21760 7.78917 0.156 0.878
Residual standard error: 18.33 on 15 degrees of freedom
Multiple R-squared: 0.2316, Adjusted R-squared: 0.02674
F-statistic: 1.131 on 4 and 15 DF, p-value: 0.3794
Regression Coefficients
Star Dependence: Almost no relationship with league points
Squad depth: players with 900 minute threshold earned fewer points, evidence is weak though.
Attacking Performance: Strongest coefficient,one unit increase corresponds to 10 points.
Defense: Small positive relationship.
Results and Interpretaion
The model produced an R-squared value of 0.2316, meaning 23.16 of the value in league points was explained by the four predictors. However, adjusted R-squared was 0.0267, suggesting that the model explains very variation.
Attacking performance had the strongest postitive coefficient(10.48), suggesting teams with more attacking tactic tended to earn more points compared to the other variables. Squad depth had a negative coefficient, (-4.45), while star dependence (-0.035) and defensive ativity(1.22) showed relatively small estimated coefficients.
The overall model was not statistically significant, as we had a p-value of 0.3794
Overall, while there are heavy associations with these factors, the findings suggest otherwise. Thes findings suggest that these variables alone are not reliable to explain success in the premier league during the 2024/2025 season.
Challenges Encountered
Combining the two datasets was the first hurdle. Although both datasets contained the same teams, several clubs had different names, for example “Manchester City” vs “Man City”. I used recode to standardize the team names, then I finally combined them with left_join
Another challenge was calculating the league results. The match dataset used “H” “A” and “D” to represent results, and when calculating i kept on getting the wrong league standings, and in the end, I figured it was a typo in the way I renamed one of the clubs.
A limitation to the attacking and defensive performance scores was that, the variables used to determine the scores were broad, so deciding which variables I should use was hard. I could’ve added more, but there were statistics measured on different scales.
Another limitaiton was the image plots, as they had background, as opposed to having just the crest. I discovered later that I can only use png files and not vector files.
The interpretation was also challenging because the model didn’t identify any statistically significant predictors. Although attack heavy tactics showed a positive relationship, the model explained only a little amount of variation.
Future Research Notes
In the future, I would expand the analysis to multiple league seasons instead of one.
I would also like to include additional variables such as player injuries, expected goals (xG), transfer spending, and so much more.
I would also study how football stat developers develop and find their stats, and what factors they consider. Some examples of these include OptaAnalyst, and the xG philosophy
Finally, I would strive to improve my regression model by testing different and more accurate combinations of variables.