Introdução
Este post apresenta uma análise exploratória dos dados da fase de grupos da Copa do Mundo FIFA 2026, com foco nas pontuações ELO de cada seleção participante.
O ranking ELO é um sistema de classificação adaptado do xadrez para o futebol, que estima a força relativa de cada seleção com base no histórico de resultados ponderado por adversário, local do jogo e importância da partida. Quanto maior o ELO, mais forte é considerada a seleção.
A Copa do Mundo 2026 é disputada por 48 seleções divididas em 12 grupos (A a L), com 4 times por grupo, totalizando 72 partidas na fase de grupos.
Carregamento de Pacotes e Dados
Carregamos os pacotes necessários para a análise e importamos os dados diretamente do arquivo Excel.
library(tidyverse)
theme_set(theme_bw())
library(readxl)
library(janitor)
A função clean_names() do pacote janitor padroniza os nomes das colunas para o formato snake_case, removendo acentos, espaços e caracteres especiais, o que facilita a manipulação posterior.
fifa <-
read_excel(path = "~/Downloads/Copa_Mundo_2026_Fase_Grupos_ELO.xlsx", sheet = "Sheet1") |>
clean_names()
glimpse(fifa)
## Rows: 96
## Columns: 29
## $ partida <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,…
## $ data <dttm> 2026-06-11, 2026-06-12, 2026-06-12, 2026-06-13, 2…
## $ grupo <chr> "A", "A", "B", "D", "B", "C", "C", "D", "E", "F", …
## $ time_1 <chr> "México", "Coreia do Sul", "Canadá", "EUA", "Catar…
## $ elo_time_1 <dbl> 1687, 1592, 1559, 1671, 1450, 1766, 1293, 1579, 17…
## $ time_2 <chr> "África do Sul", "República Tcheca", "Bósnia e Her…
## $ elo_time_2 <dbl> 1428, 1506, 1387, 1505, 1650, 1755, 1503, 1606, 12…
## $ probabilidade_elo <dbl> 0.8162169, 0.6212967, 0.7291100, 0.7222345, 0.2402…
## $ predicao <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ vencedor_0_5 <chr> "México", "Coreia do Sul", "Canadá", "EUA", "Suíça…
## $ vencedor_0_6 <chr> "México", "Coreia do Sul", "Canadá", "EUA", "Suíça…
## $ vencedor_0_7 <chr> "México", "Empate", "Canadá", "EUA", "Suíça", "Emp…
## $ vencedor_0_8 <chr> "México", "Empate", "Empate", "Empate", "Empate", …
## $ vencedor <chr> "México", "Coreia do Sul", "Empate", "EUA", "Empat…
## $ zebra <chr> "Não", "Sim", "Sim", "Sim", "Sim", "Sim", "Sim", "…
## $ comparacao_0_5 <chr> "Correto", "Correto", "Errado", "Correto", "Errado…
## $ resultado_17 <dbl> 1.0000000, 1.0000000, 0.6666667, 0.7500000, 0.6000…
## $ resultado_3a_rodada <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ comparacao_0_6 <chr> "Correto", "Correto", "Errado", "Correto", "Errado…
## $ resultado_20 <dbl> 1.0000000, 1.0000000, 0.6666667, 0.7500000, 0.6000…
## $ comparacao_0_7 <chr> "Correto", "Errado", "Errado", "Correto", "Errado"…
## $ resultado_22 <dbl> 1.0000000, 0.5000000, 0.3333333, 0.5000000, 0.4000…
## $ comparacao_0_8 <chr> "Correto", "Errado", "Correto", "Errado", "Correto…
## $ resultado_24 <dbl> 1.0000000, 0.5000000, 0.6666667, 0.5000000, 0.6000…
## $ x25 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ x26 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ x27 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ x28 <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA…
## $ threshold <dbl> 0.5, 0.6, 0.7, 0.8, NA, NA, NA, NA, NA, NA, NA, NA…
Criação da Variável rodada
As partidas da fase de grupos ocorrem em três rodadas principais (mais uma rodada especial de confrontos simultâneos na última rodada de cada grupo). Criamos a variável rodada com base nas datas das partidas:
- Rodada 0: Ranking ELO antes da Copa
- Rodada 1: 11 a 17 de junho (1ª rodada)
- Rodada 2: 18 a 23 de junho (2ª rodada)
- Rodada 3: 24 a 27 de junho (3ª rodada)
fifa <-
fifa |>
mutate(
data = ymd(data),
rodada = case_when(
data >= "2026-06-11" & data <= "2026-06-17" ~ 0,
data >= "2026-06-18" & data <= "2026-06-23" ~ 1,
data >= "2026-06-24" & data <= "2026-06-27" ~ 2,
data == "2026-06-28" ~ 3
)
)
Verificamos a distribuição das partidas por rodada:
fifa |>
group_by(rodada) |>
count() |>
kable(
col.names = c("Rodada", "Nº de Partidas"),
caption = "Distribuição de partidas por rodada"
)
| Rodada | Nº de Partidas |
|---|---|
| 0 | 24 |
| 1 | 24 |
| 2 | 24 |
| 3 | 24 |
Transformação para Formato Longo
Para facilitar análises centradas nos times e não nas partidas, transformamos o dataset do formato largo para o formato longo. Cada linha passa a representar um time em uma partida.
fifa_longo <-
fifa |>
pivot_longer(
cols = c(time_1, elo_time_1, time_2, elo_time_2),
names_to = c(".value", "numero_time"),
names_pattern = "(time|elo_time)_(.*)"
) |>
rename(elo = elo_time) |>
select(rodada, partida, data, grupo, time, elo)
glimpse(fifa_longo)
## Rows: 192
## Columns: 6
## $ rodada <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ partida <dbl> 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, …
## $ data <date> 2026-06-11, 2026-06-11, 2026-06-12, 2026-06-12, 2026-06-12, 2…
## $ grupo <chr> "A", "A", "A", "A", "B", "B", "D", "D", "B", "B", "C", "C", "C…
## $ time <chr> "México", "África do Sul", "Coreia do Sul", "República Tcheca"…
## $ elo <dbl> 1687, 1428, 1592, 1506, 1559, 1387, 1671, 1505, 1450, 1650, 17…
Análise Descritiva do ELO por Grupo
Grupos com maior variabilidade (Rodada 1)
Grupos com alto desvio-padrão do ELO possuem times muito desiguais - o favorito é mais previsível. Grupos com baixo desvio-padrão são mais equilibrados e tendem a produzir mais surpresas.
fifa_longo |>
filter(rodada == 1) |>
group_by(grupo) |>
summarise(
media = mean(elo),
sd = sd(elo)
) |>
arrange(desc(sd)) |>
kable(
digits = 1,
col.names = c("Grupo", "ELO Médio", "Desvio-Padrão ELO"),
caption = "Variabilidade do ELO por grupo - Rodada 1"
)
| Grupo | ELO Médio | Desvio-Padrão ELO |
|---|---|---|
| C | 1579.5 | 231.0 |
| H | 1585.8 | 215.9 |
| J | 1608.2 | 213.8 |
| L | 1607.2 | 206.0 |
| I | 1639.8 | 192.5 |
| E | 1542.8 | 189.2 |
| G | 1549.8 | 187.0 |
| K | 1599.8 | 156.9 |
| F | 1600.2 | 132.5 |
| A | 1553.0 | 128.6 |
| B | 1511.8 | 107.6 |
| D | 1590.5 | 82.8 |
O Grupo H é o mais desequilibrado da rodada 1. Vemos abaixo quais times o compõem:
fifa_longo |>
filter(grupo == "H") |>
select(time) |>
distinct() |>
kable(col.names = "Times do Grupo H")
| Times do Grupo H |
|---|
| Espanha |
| Cabo Verde |
| Arábia Saudita |
| Uruguai |
Já o Grupo D, que apresentou menor desvio-padrão, é mais equilibrado:
fifa_longo |>
filter(grupo == "D") |>
select(time) |>
distinct() |>
kable(col.names = "Times do Grupo D")
| Times do Grupo D |
|---|
| EUA |
| Paraguai |
| Austrália |
| Turquia |
Grupos com maior variabilidade (Rodada 3 - última rodada simultânea)
fifa_longo |>
filter(rodada == 3) |>
group_by(grupo) |>
summarise(
media = mean(elo),
sd = sd(elo)
) |>
arrange(desc(sd)) |>
kable(
digits = 1,
col.names = c("Grupo", "ELO Médio", "Desvio-Padrão ELO"),
caption = "Variabilidade do ELO por grupo - Rodada 3"
)
| Grupo | ELO Médio | Desvio-Padrão ELO |
|---|---|---|
| C | 1579.2 | 250.1 |
| J | 1608.5 | 224.4 |
| H | 1586.0 | 222.1 |
| L | 1607.0 | 210.4 |
| I | 1639.5 | 207.6 |
| G | 1550.0 | 197.9 |
| E | 1542.5 | 184.9 |
| K | 1599.8 | 171.6 |
| F | 1600.8 | 154.8 |
| A | 1553.2 | 130.8 |
| B | 1511.8 | 128.1 |
| D | 1590.5 | 64.4 |
fifa_longo |>
filter(grupo == "C") |>
select(time) |>
distinct() |>
kable(col.names = "Times do Grupo C")
| Times do Grupo C |
|---|
| Brasil |
| Marrocos |
| Haiti |
| Escócia |
Visualização: Evolução do ELO ao Longo das Rodadas
O gráfico abaixo mostra a trajetória do ELO de cada seleção ao longo das rodadas da fase de grupos, separado por grupo. Cada linha representa um time.
fifa_longo |>
ggplot(aes(x = (rodada - 1), y = elo, group = time)) +
geom_line(alpha = 0.8) +
geom_point(size = 1.5, alpha = 0.6) +
facet_wrap(~ grupo, nrow = 4) +
labs(
title = "Evolução do ELO por Grupo - Copa do Mundo 2026",
subtitle = "Cada linha representa uma seleção participante",
x = "Rodada",
y = "Ranking ELO"
) +
scale_x_continuous(breaks = 0:3, labels = 0:3, minor_breaks = NULL) +
scale_y_continuous(minor_breaks = NULL)

Variação do ELO: Antes e Depois da Fase de Grupos
Times com maior ganho de ELO (entre rodadas 0 e 3)
Identificamos as seleções que mais subiram no ranking ELO entre o início e o fim da fase de grupos, indicando desempenho acima do esperado.
fifa_longo |>
filter(rodada %in% c(0, 3)) |>
pivot_wider(
id_cols = c(time, grupo),
names_from = rodada,
values_from = elo,
names_prefix = "elo_rodada_"
) |>
mutate(diferenca_elo = elo_rodada_3 - elo_rodada_0) |>
arrange(desc(diferenca_elo)) |>
head(10) |>
kable(
digits = 1,
col.names = c("Time", "Grupo", "ELO Rodada 0", "ELO Rodada 3", "Variação ELO"),
caption = "Top 10 seleções com maior ganho de ELO na fase de grupos"
)
| Time | Grupo | ELO Rodada 0 | ELO Rodada 3 | Variação ELO |
|---|---|---|---|---|
| México | A | 1687 | 1736 | 49 |
| Gana | L | 1347 | 1387 | 40 |
| Noruega | I | 1557 | 1594 | 37 |
| França | I | 1871 | 1907 | 36 |
| Cabo Verde | H | 1371 | 1403 | 32 |
| Colômbia | K | 1698 | 1727 | 29 |
| Suíça | B | 1650 | 1676 | 26 |
| Argentina | J | 1877 | 1902 | 25 |
| Costa do Marfim | E | 1541 | 1565 | 24 |
| África do Sul | A | 1428 | 1451 | 23 |
Times com maior queda de ELO (entre rodadas 1 e 3)
fifa_longo |>
filter(rodada %in% c(1, 3)) |>
pivot_wider(
id_cols = c(time, grupo),
names_from = rodada,
values_from = elo,
names_prefix = "elo_rodada_"
) |>
mutate(diferenca_elo = elo_rodada_3 - elo_rodada_1) |>
arrange(diferenca_elo) |>
head(10) |>
kable(
digits = 1,
col.names = c("Time", "Grupo", "ELO Rodada 1", "ELO Rodada 3", "Variação ELO"),
caption = "Top 10 seleções com maior queda de ELO entre as rodadas 1 e 3"
)
| Time | Grupo | ELO Rodada 1 | ELO Rodada 3 | Variação ELO |
|---|---|---|---|---|
| Coreia do Sul | A | 1613 | 1559 | -54 |
| Catar | B | 1459 | 1411 | -48 |
| Escócia | C | 1519 | 1491 | -28 |
| Uruguai | H | 1662 | 1635 | -27 |
| Panamá | L | 1505 | 1478 | -27 |
| Tunísia | F | 1453 | 1427 | -26 |
| Austrália | D | 1606 | 1581 | -25 |
| Iraque | I | 1427 | 1404 | -23 |
| Nova Zelândia | G | 1290 | 1270 | -20 |
| Alemanha | E | 1744 | 1726 | -18 |
Distribuição do ELO por Grupo
Distribuição na Rodada 1
Cada ponto representa um time dentro do grupo. A dispersão horizontal indica o grau de equilíbrio (ou desequilíbrio) entre as forças dos times.
fifa_longo |>
filter(rodada == 1) |>
ggplot(aes(x = elo, y = 0)) +
geom_point(size = 3, alpha = 0.8) +
facet_wrap(~ grupo, nrow = 4) +
scale_y_continuous(breaks = NULL) +
scale_x_continuous(breaks = NULL) +
labs(
title = "Distribuição do ELO por Grupo - Rodada 1",
subtitle = "Cada ponto é uma seleção",
x = "ELO",
y = ""
)

Distribuição na Rodada 3
fifa_longo |>
filter(rodada == 3) |>
ggplot(aes(x = elo, y = 0)) +
geom_point(size = 3, alpha = 0.8) +
facet_wrap(~ grupo, nrow = 4) +
scale_y_continuous(breaks = NULL) +
scale_x_continuous(breaks = NULL) +
labs(
title = "Distribuição do ELO por Grupo - Rodada 3",
subtitle = "Cada ponto é uma seleção",
x = "ELO",
y = ""
)

Conclusão
Esta análise explorou os dados da fase de grupos da Copa do Mundo 2026 sob a ótica do ranking ELO. Os principais achados foram:
- A Copa 2026, com 12 grupos e 48 seleções, apresenta grande variabilidade no nível competitivo, com grupos muito desequilibrados (como o H) e outros bastante nivelados.
- A variação do ELO entre o início e o fim da fase de grupos permite identificar as seleções que superaram ou frustraram as expectativas.
- Há amplo espaço para análises de calibração do modelo ELO, investigação de zebras e comparação entre diferentes estratégias de previsão.