Here I would like to explore the effect of different variables on the performance of different countries in the group stage of the World Cup (2026)!
First I gathered some data from various sources including fotmob and sofascore, and read it into R:
# Libraries
library(tidyverse)
library(ggimage)
# Set wd
data <- read.csv('Group-Stage.csv')
# View data
knitr::kable(head(data))
# Edit data
data$xGDiff <- data$xG - data$xGA
| Team | Points | GoalDiff | xG | xGA | Population | StartingValue | GDP | Code |
|---|---|---|---|---|---|---|---|---|
| Algeria | 4 | -2 | 3.9 | 3.4 | 47.4 | 181.3 | 5.364 | dz |
| Argentina | 9 | 7 | 5.7 | 1.6 | 46.7 | 407.4 | 14.187 | ar |
| Australia | 4 | 0 | 2.1 | 2.7 | 28.2 | 53.2 | 67.129 | hm |
| Austria | 4 | 0 | 3.7 | 4.5 | 9.2 | 112.9 | 56.142 | at |
| Belgium | 5 | 4 | 6.8 | 1.9 | 11.8 | 248.8 | 55.049 | be |
| Bosnia | 4 | -1 | 1.9 | 4.1 | 3.1 | 93.2 | 8.639 | ba |
Next I wanted to plot some of this data to investigate it:
# Plot: GDP
ggplot(data=data, aes(y=xGDiff, x=log10(GDP)))+
geom_point()+
geom_smooth(method=lm, se=FALSE, colour='black', linetype='dotted', size=0.75) +
geom_image(data=data, aes(y=xGDiff, x=log10(GDP), image=Image))+
theme+
labs(title='Effect of GDP on xG Difference', x='Log10 GDP per capita ($)', y='xG - xGA')
# Plot: population
ggplot(data, aes(y=xGDiff, x=log10(Population)))+
geom_point()+
geom_smooth(method=lm, se=FALSE, colour='black', linetype='dotted', size=0.75) +
geom_image(data=data, aes(y=xGDiff, x=log10(Population), image=Image))+
theme+
labs(title='Effect of Population on xG Difference', x='Log10 Population (Millions)', y='xG - xGA')
# Plot: starting value
ggplot(data, aes(y=xGDiff, x=StartingValue))+
geom_point()+
geom_smooth(method=lm, se=FALSE, colour='black', linetype='dotted', size=0.75) +
geom_image(data=data, aes(y=xGDiff, x=StartingValue, image=Image))+
theme+
labs(title='Effect of Starting XI Value on xG Difference', x='Starting XI Value (Millions)', y='xG - xGA')
From these plots I can see that country population, GDP per capita and the market value of the starting XI all positively affect how each country performed in the group stages of the world cup. I can also quantify this using a linear regression model for each variable:
# Linear regression model
model <- lm(xGDiff ~ GDP+Population+StartingValue, data=data)
knitr::kable(head(summary(model)$coefficients))
# Linear regression model for each variable alone
summary(lm(xGDiff ~ GDP, data=data))$r.squared
summary(lm(xGDiff ~ Population, data=data))$r.squared
summary(lm(xGDiff ~ StartingValue, data=data))$r.squared
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | -2.7769163 | 0.6434115 | -4.3159260 | 0.0000887 |
| GDP | 0.0048872 | 0.0142379 | 0.3432515 | 0.7330440 |
| Population | 0.0123690 | 0.0060656 | 2.0392130 | 0.0474630 |
| StartingValue | 0.0097039 | 0.0018155 | 5.3449376 | 0.0000031 |
## [1] 0.04071865
## [1] 0.110686
## [1] 0.4326861
From this analysis (and the graphs) I can see that the market value of the starting XI has the largest effect on performance in the group stages: in the combined model it has a very small p-value (indicating that it is unlikely to observe a relationship between the predictor and outcome due to chance), and alone it explains ~43% of the variance in xG difference. Meanwhile, GDP and Population explain ~4% and ~11% of the variance in xG difference.
There are also some points of interest: Canada, Switzerland and Mexico have performed very well in the group stages despite having a relatively low starting XI market value, meanwhile Sweden, Croatia and Portugal have done a little worse than might be expected. Also, although France has by far the highest value team (€912.3M), they did not perform as well as several countries including Switzerland (€162.8M), Belgium (€248.8M) and Canada (€98.7M). However it is important to note that group difficulty will influence these metrics.
It is also interesting to look at the relationships between GDP, population and starting value:
# Plots
ggplot(data=data, aes(y=StartingValue, x=log10(Population)))+
geom_point()+
geom_smooth(method=lm, se=FALSE, colour='black', linetype='dotted', size=0.75) +
geom_image(data=data, aes(y=StartingValue, x=log10(Population), image=Image))+
theme+
labs(title='Effect of Population on Starting XI Value')
summary(lm(StartingValue ~ Population, data=data))$r.squared
## [1] 0.03078913
Population only explains ~3% of the variance in starting XI market value, with some very populuous countries having a relatively low market value (such as the USA, Japan and Mexico) and less populous countries having a much higher value (such as Uruguay, Croatia and Norway). This may be due to the presence of one very highly valued player in some of these countries, such as Erling Haaland for Norway or Federico Valverde for Uruguay.