O Campeonato Brasileiro – Série A, disputado no formato de pontos corridos desde 2003, é um dos torneios mais longos e competitivos do futebol mundial. O problema que este estudo aborda é a necessidade de quantificar e compreender a evolução das métricas fundamentais que definem o jogo no Brasil. Por que isso é relevante? O futebol, como fenômeno dinâmico, está em constante transformação tática. Entender a evolução do Fator Casa, da média de gols e da frequência de empates ao longo de duas décadas permite que analistas, treinadores e entusiastas identifiquem tendências de longo prazo, como uma possível diminuição da vantagem do mando de campo ou uma mudança no estilo de jogo para um modelo mais ofensivo ou defensivo.
Este relatório apresenta uma Análise Exploratória de Dados (AED) das partidas do Campeonato Brasileiro – Série A, no período de 2003 a 2024. A base de dados utilizada reúne informações detalhadas, incluindo mandante, visitante, placar, gols marcados e localização da partida. A metodologia empregada foca na identificação de padrões e tendências por meio de:
As principais questões que norteiam este estudo são: * Existe variação significativa na vantagem do mando de campo ao longo dos anos? * A média de gols por partida apresenta tendência de crescimento ou queda, e a distribuição de gols segue o modelo de Poisson? * Quais equipes apresentam maior frequência de empates e melhor aproveitamento no período analisado?
A análise gerada por este estudo possui valor prático para diversos clientes. Casas de apostas esportivas e modeladores de performance se beneficiam da quantificação precisa do Fator Casa e da média de gols. Jornalistas esportivos e analistas de desempenho ganham contexto histórico robusto para interpretar o desempenho atual de times e a dinâmica do campeonato. Por fim, a própria comunidade de entusiastas obtém uma visão profunda, baseada em dados, sobre as tendências que definem a história recente do futebol brasileiro.
Nesta seção, listamos e carregamos todas as bibliotecas R que serão utilizadas para a manipulação, análise e visualização dos dados. O pacote tidyverse é o principal conjunto de ferramentas para análise de dados no ecossistema R.
library(tidyverse)
library(knitr)
library(kableExtra)
# Define o locale para garantir que a data no YAML e nos gráficos esteja em português
try(Sys.setlocale("LC_ALL", "pt_BR.UTF-8"))[1] "LC_COLLATE=pt_BR.UTF-8;LC_CTYPE=pt_BR.UTF-8;LC_MONETARY=pt_BR.UTF-8;LC_NUMERIC=C;LC_TIME=pt_BR.UTF-8"
[1] "LC_COLLATE=Portuguese_Brazil.1252;LC_CTYPE=Portuguese_Brazil.1252;LC_MONETARY=Portuguese_Brazil.1252;LC_NUMERIC=C;LC_TIME=Portuguese_Brazil.1252"
tidyverse: Conjunto essencial de pacotes (inclui ggplot2, dplyr, readr) para manipulação, transformação e visualização de dados, formando o núcleo de todas as operações de análise.
kableExtra: Usado para formatar e estilizar tabelas geradas no R Markdown (via knitr::kable), aplicando design visual como cores, listras e formatação avançada (como visto na seção 2.3).
Nesta seção será realizado o carregamento da base de dados utilizada na análise, bem como uma visualização inicial para compreensão da sua estrutura.
# Instalar e carregar o pacote tidyverse, se necessário
if (!requireNamespace("tidyverse", quietly = TRUE)) {
install.packages("tidyverse")
}
library(tidyverse)
# Definir o nome do arquivo
nome_arquivo <- "campeonato-brasileiro-full.csv"
# Carregar o conjunto de dados
# Usamos 'read_csv' do pacote 'readr' (parte do tidyverse)
# O 'locale = locale(encoding = "latin1")' é importante para garantir
# que caracteres como 'ç' e acentos sejam lidos corretamente em arquivos brasileiros.
dados_br <- read_csv(
nome_arquivo,
locale = locale(encoding = "latin1")
)
# Visualizar as dimensões do dataset (linhas e colunas)
print(paste("Dataset carregado com sucesso. Dimensões:", nrow(dados_br), "linhas e", ncol(dados_br), "colunas"))[1] "Dataset carregado com sucesso. Dimensões: 8785 linhas e 16 colunas"
Rows: 8,785
Columns: 16
$ ID <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, ~
$ rodata <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, ~
$ data <chr> "29/03/2003", "29/03/2003", "30/03/2003", "30/03/20~
$ hora <time> 16:00:00, 16:00:00, 16:00:00, 16:00:00, 16:00:00, ~
$ mandante <chr> "Guarani", "Athletico-PR", "Flamengo", "Goias", "In~
$ visitante <chr> "Vasco", "Gremio", "Coritiba", "Paysandu", "Ponte P~
$ formacao_mandante <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,~
$ formacao_visitante <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,~
$ tecnico_mandante <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,~
$ tecnico_visitante <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,~
$ vencedor <chr> "Guarani", "Athletico-PR", "-", "-", "-", "Criciuma~
$ arena <chr> "Â Brinco de Ouro", "Â Arena da Baixada", "Â Maraca~
$ mandante_Placar <dbl> 4, 2, 1, 2, 1, 2, 2, 0, 2, 1, 2, 0, 1, 0, 0, 3, 1, ~
$ visitante_Placar <dbl> 2, 0, 1, 2, 1, 0, 2, 0, 2, 1, 2, 3, 1, 0, 1, 1, 2, ~
$ mandante_Estado <chr> "SP", "PR", "RJ", "GO", "RS", "SC", "RS", "CE", "MG~
$ visitante_Estado <chr> "RJ", "RS", "PR", "PA", "SP", "RJ", "SP", "BA", "SP~
Nesta seção, realizamos a padronização e organização dos dados
brutos, criando novas variáveis que serão utilizadas ao longo das
análises, como o resultado da partida e o total de gols. O conjunto de
dados final será o objeto dados_br_final.
O primeiro passo é remover colunas com alta percentagem de valores ausentes (NA’s) ou que não serão relevantes para as análises subsequentes. Em seguida, tratamos inconsistências em strings.
# Colunas como 'formacao' e 'tecnico' têm muitos NA's e não serão usadas
# na análise inicial. A coluna 'rodata' é redundante.
dados_br_tratado <- dados_br %>%
select(-rodata,
-formacao_mandante,
-formacao_visitante,
-tecnico_mandante,
-tecnico_visitante) %>%
# Remove as poucas linhas onde o vencedor está ausente (drop_na mais seletivo)
drop_na(vencedor) %>%
# Tratamento de string: Remove o caractere invisível 'Â' na coluna 'arena'
# e remove espaços em branco extras (str_trim)
mutate(arena = str_trim(str_replace_all(arena, "Â", "")))
# Inspeção após o tratamento de NAs e strings
print(paste("Após a remoção de colunas e linhas com NA, o dataset tem:",
nrow(dados_br_tratado), "linhas e", ncol(dados_br_tratado), "colunas"))[1] "Após a remoção de colunas e linhas com NA, o dataset tem: 8785 linhas e 11 colunas"
O foco aqui é garantir que todas as variáveis estejam no formato correto para o cálculo e análise estatística, em particular a coluna de data.
dados_br_convertido <- dados_br_tratado %>%
mutate(
# Converter a coluna 'data' (formato DD/MM/YYYY) para o tipo Date
data_partida = as.Date(data, format = "%d/%m/%Y"),
# Garantir que os placares sejam números inteiros (integer)
mandante_Placar = as.integer(mandante_Placar),
visitante_Placar = as.integer(visitante_Placar)
) %>%
# Remove a coluna 'data' original (do tipo chr)
select(-data)
# Inspeção para confirmar os novos tipos
print(glimpse(dados_br_convertido %>% select(data_partida, mandante_Placar, visitante_Placar)))Rows: 8,785
Columns: 3
$ data_partida <date> 2003-03-29, 2003-03-29, 2003-03-30, 2003-03-30, 2003~
$ mandante_Placar <int> 4, 2, 1, 2, 1, 2, 2, 0, 2, 1, 2, 0, 1, 0, 0, 3, 1, 3,~
$ visitante_Placar <int> 2, 0, 1, 2, 1, 0, 2, 0, 2, 1, 2, 3, 1, 0, 1, 1, 2, 3,~
# A tibble: 8,785 x 3
data_partida mandante_Placar visitante_Placar
<date> <int> <int>
1 2003-03-29 4 2
2 2003-03-29 2 0
3 2003-03-30 1 1
4 2003-03-30 2 2
5 2003-03-30 1 1
6 2003-03-30 2 0
7 2003-03-30 2 2
8 2003-03-30 0 0
9 2003-03-30 2 2
10 2003-03-30 1 1
# i 8,775 more rows
Nesta subseção, criamos as variáveis essenciais para a análise do Campeonato Brasileiro: o resultado da partida, o total de gols e o ano de cada jogo.
dados_br_final <- dados_br_convertido %>%
mutate(
# Criação da variável RESULTADO (Substitui o '-' por 'Empate')
resultado = case_when(
vencedor == "-" ~ "Empate",
vencedor == mandante ~ "Vitória Casa",
vencedor == visitante ~ "Vitória Fora",
TRUE ~ "Indefinido/Erro"
),
# Criação da variável TOTAL DE GOLS
total_gols = mandante_Placar + visitante_Placar,
# Criação da variável ANO para análises temporais (extraído da data_partida)
ano = year(data_partida)
) %>%
# Reorganizar colunas para o dataset final
select(ID, ano, data_partida, hora, mandante, visitante,
mandante_Placar, visitante_Placar, total_gols, resultado,
arena, everything())
# Apresentação do Dataset Final
print("Estrutura Final do Dataset para Análise:")[1] "Estrutura Final do Dataset para Análise:"
# Usando o knitr::kable e kableExtra para formatar a tabela
dados_br_final %>%
head(5) %>% # Pegamos as 5 primeiras linhas
select(ano, data_partida, mandante, visitante,
mandante_Placar, visitante_Placar, total_gols, resultado) %>% # Selecionamos as colunas principais
kable(caption = "Amostra do Dataset Final (dados_br_final)",
align = 'lccccrcc') %>% # Define o alinhamento das colunas
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = F,
position = "left") %>% # Estilos de design
column_spec(7, bold = T) # Deixa a coluna total_gols em negrito para destaque| ano | data_partida | mandante | visitante | mandante_Placar | visitante_Placar | total_gols | resultado |
|---|---|---|---|---|---|---|---|
| 2003 | 2003-03-29 | Guarani | Vasco | 4 | 2 | 6 | Vitória Casa |
| 2003 | 2003-03-29 | Athletico-PR | Gremio | 2 | 0 | 2 | Vitória Casa |
| 2003 | 2003-03-30 | Flamengo | Coritiba | 1 | 1 | 2 | Empate |
| 2003 | 2003-03-30 | Goias | Paysandu | 2 | 2 | 4 | Empate |
| 2003 | 2003-03-30 | Internacional | Ponte Preta | 1 | 1 | 2 | Empate |
O resultado final deste processo é o dataset dados_br_final, que está limpo e pronto para a próxima fase.
Agora que temos o dataset dados_br_final limpo e pronto, podemos começar a Análise Exploratória de Dados (AED). O objetivo da AED é resumir as características principais dos dados, muitas vezes usando métodos visuais.
Para iniciar a AED, vamos explorar as três métricas mais fundamentais no contexto do futebol:
1. Vitória do Mandante vs. Visitante (Fator Casa)
2. Distribuição de Gols (Quantos gols são marcados por partida)
3. Tendências Temporais (Como as métricas mudaram entre 2003 e 2024)
Vamos começar analisando a proporção de vitórias de times mandantes, visitantes e empates. Este é um indicador clássico de quão forte é o Fator Casa no Campeonato Brasileiro.
# 1. Calcular a contagem de cada tipo de resultado
resumo_resultados <- dados_br_final %>%
count(resultado, name = "Contagem") %>%
mutate(Proporcao = Contagem / sum(Contagem))
print("Distribuição de Resultados (2003-2024):")[1] "Distribuição de Resultados (2003-2024):"
# A tibble: 3 x 3
resultado Contagem Proporcao
<chr> <int> <dbl>
1 Empate 2322 0.264
2 Vitória Casa 4359 0.496
3 Vitória Fora 2104 0.239
# 2. Visualização da Distribuição dos Resultados (Gráfico de Barras)
# Usando a coluna 'resultado' para visualização
grafico_resultados <- resumo_resultados %>%
ggplot(aes(x = reorder(resultado, -Contagem), y = Contagem, fill = resultado)) +
geom_bar(stat = "identity") +
geom_text(aes(label = paste0(round(Proporcao * 100, 1), "%")),
vjust = -0.5) + # Adiciona os rótulos de porcentagem
scale_fill_manual(values = c("Empate" = "gray",
"Vitória Casa" = "darkgreen",
"Vitória Fora" = "darkred")) +
labs(title = "Distribuição dos Resultados das Partidas (2003-2024)",
x = "Resultado da Partida",
y = "Número de Partidas",
fill = "Resultado") +
theme_minimal()
print(grafico_resultados)Após gerar o grafico_resultados, que mostra a distribuição geral dos resultados (Vitória Casa, Empate, Vitória Fora), o próximo passo natural para aprofundar esta análise é explorar a tendência temporal do fator casa. A pergunta a ser respondida é: O Fator Casa se manteve constante ou tem diminuído/aumentado ao longo dos anos (2003 a 2024)?
Para isso, usaremos a variável ano (que criamos no pré-processamento) para calcular a porcentagem de vitórias de mandantes, visitantes e empates em cada temporada.
# 1. Calcular as proporções de resultados por ANO
fator_casa_por_ano <- dados_br_final %>%
group_by(ano, resultado) %>%
summarise(Contagem = n(), .groups = 'drop_last') %>%
mutate(Proporcao = Contagem / sum(Contagem)) %>%
ungroup()
# 2. Transformar para o formato largo (wide) para fácil leitura
tabela_proporcoes_anual <- fator_casa_por_ano %>%
pivot_wider(names_from = resultado, values_from = Proporcao) %>%
# Reorganizar as colunas para a ordem lógica
select(ano, `Vitória Casa`, Empate, `Vitória Fora`)
# Exibir os dados das últimas 5 temporadas, formatado
print("Proporção de Resultados por Ano (Últimas 5 temporadas):")[1] "Proporção de Resultados por Ano (Últimas 5 temporadas):"
tabela_proporcoes_anual %>%
filter(ano >= max(ano) - 4) %>%
knitr::kable(caption = "Proporção Anual dos Resultados", digits = 3) %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover"),
full_width = F)| ano | Vitória Casa | Empate | Vitória Fora |
|---|---|---|---|
| 2020 | NA | 0.291 | NA |
| 2020 | 0.437 | NA | NA |
| 2020 | NA | NA | 0.272 |
| 2021 | NA | 0.291 | NA |
| 2021 | 0.463 | NA | NA |
| 2021 | NA | NA | 0.246 |
| 2022 | NA | 0.284 | NA |
| 2022 | 0.442 | NA | NA |
| 2022 | NA | NA | 0.274 |
| 2023 | NA | 0.258 | NA |
| 2023 | 0.468 | NA | NA |
| 2023 | NA | NA | 0.274 |
| 2024 | NA | 0.266 | NA |
| 2024 | 0.474 | NA | NA |
| 2024 | NA | NA | 0.261 |
# 2. Visualização da Tendência Temporal
# Usaremos um gráfico de linha para mostrar a evolução da proporção de resultados
grafico_tendencia_fator_casa <- fator_casa_por_ano %>%
ggplot(aes(x = ano, y = Proporcao, color = resultado)) +
geom_line(linewidth = 1) +
geom_point() +
scale_y_continuous(labels = scales::percent) + # Formata o eixo Y como porcentagem
scale_color_manual(values = c("Empate" = "gray",
"Vitória Casa" = "darkgreen",
"Vitória Fora" = "darkred")) +
labs(title = "Evolução da Proporção de Resultados por Ano (2003-2024)",
x = "Ano da Temporada",
y = "Proporção de Partidas (%)",
color = "Resultado") +
theme_minimal() +
theme(legend.position = "bottom")
print(grafico_tendencia_fator_casa)A análise temporal demonstra que, ao longo do período de 2003 a 2024, o fator mando de campo é a força dominante no Campeonato Brasileiro, com a Vitória Casa (linha verde) representando a maior proporção de resultados em praticamente todas as temporadas. Observa-se uma alta volatilidade nesta proporção, com as quedas mais notáveis ocorrendo em 2016 e, de forma mais dramática, em 2020, ano afetado pela pandemia e pela ausência de público. A recuperação do Fator Casa nos anos subsequentes indica um retorno à tendência histórica, onde as vitórias de mandantes superam significativamente os empates e as vitórias de visitantes.”
Esta seção explora o volume de gols. A distribuição de gols por partida costuma seguir uma Distribuição de Poisson e é um indicador da natureza ofensiva ou defensiva do campeonato.
# 1. Calcular a frequência de Total de Gols por Partida
resumo_gols <- dados_br_final %>%
count(total_gols, name = "Contagem") %>%
mutate(Proporcao = Contagem / sum(Contagem))
print("Frequência dos Gols por Partida:")[1] "Frequência dos Gols por Partida:"
# A tibble: 10 x 3
total_gols Contagem Proporcao
<int> <int> <dbl>
1 0 697 0.0793
2 1 1785 0.203
3 2 2150 0.245
4 3 1925 0.219
5 4 1178 0.134
6 5 606 0.0690
7 6 266 0.0303
8 7 126 0.0143
9 8 39 0.00444
10 9 8 0.000911
# 2. Visualização da Distribuição dos Gols (Histograma/Gráfico de Barras)
grafico_gols <- dados_br_final %>%
ggplot(aes(x = total_gols)) +
geom_histogram(binwidth = 1, fill = "gold", color = "black", alpha = 0.7) +
scale_x_continuous(breaks = seq(0, max(dados_br_final$total_gols), by = 1)) +
labs(title = "Distribuição do Total de Gols por Partida",
x = "Total de Gols na Partida",
y = "Número de Partidas") +
theme_light()
print(grafico_gols)Para aprofundar a afirmação de que a distribuição segue a de Poisson, vamos calcular a média de gols por partida (o parâmetro \(\lambda\)) e comparar as frequências observadas com as frequências esperadas pelo modelo de Poisson.
# 1. Calcular a média de gols por partida (Lambda - o parâmetro da Poisson)
lambda_gols <- mean(dados_br_final$total_gols)
print(paste("Média de Gols por Partida (Lambda):", round(lambda_gols, 3)))[1] "Média de Gols por Partida (Lambda): 2.563"
# 2. Calcular a frequência de gols ESPERADA pela Distribuição de Poisson
total_partidas <- nrow(dados_br_final)
resumo_gols_completo <- resumo_gols %>%
# Adicionar a proporção esperada pela Poisson para cada 'k' (total_gols)
mutate(Proporcao_Poisson = dpois(total_gols, lambda = lambda_gols),
Contagem_Esperada = Proporcao_Poisson * total_partidas) %>%
# Garantir que a coluna 'Contagem' (observada) seja numérica para o plot
mutate(Contagem_Observada = as.numeric(Contagem))
# 3. Visualização Comparativa (Observado vs. Esperado)
grafico_comparativo_poisson <- resumo_gols_completo %>%
# Filtrar até 6 gols, pois a frequência acima é muito baixa
filter(total_gols <= 6) %>%
ggplot(aes(x = total_gols)) +
# Barras Observadas
geom_bar(aes(y = Contagem_Observada, fill = "Observado"),
stat = "identity", position = "dodge", alpha = 0.7) +
# Linha Esperada (Poisson)
geom_line(aes(y = Contagem_Esperada, color = "Poisson (Esperado)"),
linewidth = 1.2) +
geom_point(aes(y = Contagem_Esperada, color = "Poisson (Esperado)"), size = 3) +
scale_x_continuous(breaks = 0:6) +
scale_fill_manual(values = c("Observado" = "gold")) +
scale_color_manual(values = c("Poisson (Esperado)" = "darkblue")) +
labs(title = "Comparação da Distribuição de Gols: Observado vs. Poisson",
subtitle = paste("Lambda (Média Observada):", round(lambda_gols, 3)),
x = "Total de Gols na Partida",
y = "Número de Partidas",
fill = "Distribuição",
color = "Modelo") +
theme_light() +
theme(legend.position = "bottom")
print(grafico_comparativo_poisson)Assim como fizemos com o Fator Casa, é crucial verificar se o futebol brasileiro tem se tornado mais ou menos ofensivo ao longo do tempo.
# 1. Calcular a Média de Gols por Ano
media_gols_por_ano <- dados_br_final %>%
group_by(ano) %>%
summarise(Media_Gols = mean(total_gols),
.groups = 'drop')
print("Média de Gols por Ano (Últimas 5 Temporadas):")[1] "Média de Gols por Ano (Últimas 5 Temporadas):"
media_gols_por_ano %>%
filter(ano >= max(ano) - 4) %>%
knitr::kable(caption = "Média de Gols por Ano", digits = 3) %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover"),
full_width = F)| ano | Media_Gols |
|---|---|
| 2020 | 2.440 |
| 2021 | 2.301 |
| 2022 | 2.382 |
| 2023 | 2.489 |
| 2024 | 2.445 |
# 2. Visualização da Evolução da Média de Gols
grafico_tendencia_gols <- media_gols_por_ano %>%
ggplot(aes(x = ano, y = Media_Gols)) +
geom_line(color = "orange", linewidth = 1.2) +
geom_point(color = "darkred", size = 3) +
geom_hline(yintercept = lambda_gols, linetype = "dashed", color = "gray50") + # Linha da média geral
labs(title = "Evolução da Média de Gols por Partida (2003-2024)",
x = "Ano da Temporada",
y = "Média de Gols por Partida") +
theme_minimal()
print(grafico_tendencia_gols)Esta análise é muito interessante porque o Fator Casa varia enormemente dependendo da cultura local, da distância das viagens e do tipo de estádio (grandes arenas neutras vs. estádios mais tradicionais).
# 1. Identificar os 5 estados com mais jogos como mandante
top_estados <- dados_br_final %>%
count(mandante_Estado, sort = TRUE, name = "Total_Jogos") %>%
head(5) %>%
pull(mandante_Estado)
print("Top 5 Estados com mais partidas como mandante:")[1] "Top 5 Estados com mais partidas como mandante:"
[1] "SP" "RJ" "RS" "MG" "PR"
Agora, vamos desenvolver o código para analisar como o Fator Casa (a proporção de vitórias do mandante) se comporta em cada um desses 5 estados.
Esta análise revelará se a vantagem de jogar em casa é mais acentuada em certas regiões.
# 1. Filtrar o dataset para incluir apenas os jogos mandados nos Top 5 estados
dados_top_estados <- dados_br_final %>%
filter(mandante_Estado %in% top_estados)
# 2. Calcular a proporção de resultados por Estado
fator_casa_por_estado <- dados_top_estados %>%
group_by(mandante_Estado, resultado) %>%
summarise(Contagem = n(), .groups = 'drop_last') %>%
mutate(Proporcao = Contagem / sum(Contagem)) %>%
ungroup() %>%
# Preparar a coluna de estado para o gráfico
mutate(Estado_Rotulo = paste0(mandante_Estado, " (n=",
format(sum(Contagem), big.mark = "."), ")"))
# 3. Visualização da Distribuição de Resultados por Estado (Gráfico de Barras Agrupadas)
grafico_fator_casa_estado <- fator_casa_por_estado %>%
ggplot(aes(x = Estado_Rotulo, y = Proporcao, fill = resultado)) +
geom_bar(stat = "identity", position = "stack") +
# Adiciona os rótulos de porcentagem dentro das barras
geom_text(aes(label = scales::percent(Proporcao, accuracy = 1)),
position = position_stack(vjust = 0.5),
color = "white", fontface = "bold", size = 3) +
scale_y_continuous(labels = scales::percent) +
scale_fill_manual(values = c("Empate" = "gray50",
"Vitória Casa" = "darkgreen",
"Vitória Fora" = "darkred")) +
labs(title = "Distribuição de Resultados por Estado (Top 5 em Jogos Mandados)",
x = "Estado (Total de Jogos)",
y = "Proporção de Partidas",
fill = "Resultado") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Rotaciona rótulos para melhor leitura
print(grafico_fator_casa_estado)
A análise da distribuição de resultados por estado revela uma notável
variação no Fator Casa. O Rio Grande do Sul (RS) se destaca como o
estado onde o mando de campo é mais decisivo, registrando 56% de
vitórias para o mandante e o menor índice de vitórias para o visitante
(19%). Em contrapartida, o Rio de Janeiro (RJ) apresenta o Fator Casa
mais fraco (49%), sendo o único dos cinco principais a registrar menos
vitórias de mandantes do que a soma de empates e vitórias de visitantes,
sugerindo uma competitividade maior ou um Fator Casa atenuado.
Esta subseção responde diretamente à questão: “Quais equipes apresentam maior frequência de empates no período analisado?”.
# 1. Empates como Mandante
empates_mandante <- dados_br_final %>%
filter(resultado == "Empate") %>%
count(mandante, name = "Empates_Casa") %>%
rename(Time = mandante)
# 2. Empates como Visitante
empates_visitante <- dados_br_final %>%
filter(resultado == "Empate") %>%
count(visitante, name = "Empates_Fora") %>%
rename(Time = visitante)
# 3. Total de Jogos por Time
total_jogos_time <- dados_br_final %>%
mutate(Time = mandante) %>%
bind_rows(dados_br_final %>% mutate(Time = visitante)) %>%
count(Time, name = "Total_Jogos")
# 4. Agrupar e Calcular a Proporção de Empates
resumo_empates <- total_jogos_time %>%
left_join(empates_mandante, by = "Time") %>%
left_join(empates_visitante, by = "Time") %>%
# Trata NA's como 0 para times que nunca empataram
mutate(Empates_Casa = replace_na(Empates_Casa, 0),
Empates_Fora = replace_na(Empates_Fora, 0),
Total_Empates = Empates_Casa + Empates_Fora) %>%
# Calcula a proporção
mutate(Proporcao_Empates = Total_Empates / Total_Jogos) %>%
# Filtra times com menos de 50 jogos para ter dados mais representativos
filter(Total_Jogos >= 50) %>%
arrange(desc(Proporcao_Empates))
# 5. Apresentação (Top 10 em Empates)
print("Top 10 Equipes com Maior Proporção de Empates (Mín. 50 Jogos):")[1] "Top 10 Equipes com Maior Proporção de Empates (Mín. 50 Jogos):"
resumo_empates %>%
head(10) %>%
select(Time, Total_Jogos, Total_Empates, Proporcao_Empates) %>%
knitr::kable(
caption = "Top 10 Equipes com Maior Proporção de Empates (2003-2024)",
digits = 3,
col.names = c("Equipe", "Jogos", "Total Empates", "Prop. Empates")
) %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = F)| Equipe | Jogos | Total Empates | Prop. Empates |
|---|---|---|---|
| Ceara | 266 | 92 | 0.346 |
| Bragantino | 190 | 64 | 0.337 |
| Portuguesa | 114 | 38 | 0.333 |
| Cuiaba | 152 | 49 | 0.322 |
| Guarani | 130 | 39 | 0.300 |
| Corinthians | 818 | 240 | 0.293 |
| Vasco | 666 | 194 | 0.291 |
| Chapecoense | 265 | 77 | 0.291 |
| Atletico-GO | 304 | 88 | 0.289 |
| Figueirense | 438 | 124 | 0.283 |
Aprofundando a análise por equipe calculando o aproveitamento (pontos ganhos sobre pontos disputados) e o saldo de gols. Isso permite uma visão de quais são os times mais eficientes.
Métricas a Calcular:
Pontos Ganhos (Vitória = 3, Empate = 1, Derrota = 0)
Saldo de Gols (Gols Pró - Gols Contra)
Aproveitamento em %
# 1. Calcular Pontos Ganhos e Gols Pró/Contra (Mandante)
dados_mandante <- dados_br_final %>%
mutate(
Time = mandante,
Pontos = case_when(
resultado == "Vitória Casa" ~ 3,
resultado == "Empate" ~ 1,
TRUE ~ 0
),
Gols_Pro = mandante_Placar,
Gols_Contra = visitante_Placar
) %>%
select(Time, Pontos, Gols_Pro, Gols_Contra)
# 2. Calcular Pontos Ganhos e Gols Pró/Contra (Visitante)
dados_visitante <- dados_br_final %>%
mutate(
Time = visitante,
Pontos = case_when(
resultado == "Vitória Fora" ~ 3,
resultado == "Empate" ~ 1,
TRUE ~ 0
),
Gols_Pro = visitante_Placar,
Gols_Contra = mandante_Placar
) %>%
select(Time, Pontos, Gols_Pro, Gols_Contra)
# 3. Consolidar e Calcular o Aproveitamento
resumo_times <- dados_mandante %>%
bind_rows(dados_visitante) %>% # Une as bases de mandante e visitante
group_by(Time) %>%
summarise(
Jogos = n(),
Total_Pontos = sum(Pontos),
Total_Gols_Pro = sum(Gols_Pro),
Total_Gols_Contra = sum(Gols_Contra),
.groups = 'drop'
) %>%
mutate(
Saldo_Gols = Total_Gols_Pro - Total_Gols_Contra,
# Cálculo: (Total de Pontos / (Jogos * 3))
Aproveitamento = (Total_Pontos / (Jogos * 3)) * 100
) %>%
# Filtra times com menos de 50 jogos para dados mais representativos
filter(Jogos >= 50) %>%
arrange(desc(Aproveitamento))
# 4. Apresentação (Top 10 por Aproveitamento)
print("Top 10 Equipes com Melhor Aproveitamento (Mín. 50 Jogos):")[1] "Top 10 Equipes com Melhor Aproveitamento (Mín. 50 Jogos):"
resumo_times %>%
head(10) %>%
select(Time, Jogos, Total_Pontos, Aproveitamento, Saldo_Gols) %>%
knitr::kable(
caption = "Top 10 Equipes com Melhor Aproveitamento (2003-2024)",
digits = 1,
col.names = c("Equipe", "Jogos", "Pontos", "Aproveitamento (%)", "Saldo de Gols")
) %>%
kableExtra::kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = F)| Equipe | Jogos | Pontos | Aproveitamento (%) | Saldo de Gols |
|---|---|---|---|---|
| Palmeiras | 772 | 1250 | 54.0 | 264 |
| Sao Paulo | 856 | 1383 | 53.9 | 294 |
| Flamengo | 856 | 1353 | 52.7 | 226 |
| Internacional | 818 | 1284 | 52.3 | 206 |
| Corinthians | 818 | 1263 | 51.5 | 176 |
| Cruzeiro | 742 | 1129 | 50.7 | 165 |
| Gremio | 776 | 1178 | 50.6 | 179 |
| Santos | 818 | 1237 | 50.4 | 196 |
| Atletico-MG | 817 | 1227 | 50.1 | 146 |
| Fluminense | 856 | 1225 | 47.7 | 60 |
Este estudo de Análise Exploratória de Dados (AED) cumpriu o objetivo de quantificar e rastrear a evolução dos padrões de resultados no Campeonato Brasileiro – Série A, no período de pontos corridos (2003-2024).
As análises temporais e descritivas revelaram tendências claras e variações significativas nas três métricas principais, fornecendo insights valiosos sobre a dinâmica competitiva do torneio.
O Fator Casa e sua Volatilidade
A análise confirmou o mando de campo como a força dominante no futebol brasileiro, com a Vitória Casa representando a maior proporção de resultados na maioria das temporadas.
Variação Temporal: A tendência da vantagem do mandante não é linear. Observou-se uma queda dramática da proporção de vitórias em casa no ano de 2020, um efeito atribuído à ausência de público devido à pandemia de COVID-19. A rápida recuperação subsequente sugere que o Fator Casa está intrinsecamente ligado à presença da torcida.
Variação Regional: A vantagem de jogar em casa é heterogênea no Brasil. O Rio Grande do Sul (RS) se destacou como o estado com o Fator Casa mais acentuado, enquanto o Rio de Janeiro (RJ) apresentou uma vantagem significativamente menor entre os estados com maior volume de jogos.
Média de Gols e Aderência ao Modelo de Poisson
A análise do volume de gols demonstrou que a distribuição do total de gols por partida segue de perto o modelo teórico da Distribuição de Poisson, com a frequência máxima concentrada em 2 gols por partida.
Tendência Ofensiva: Ao longo das duas décadas, a média de gols por partida apresenta uma leve tendência de crescimento. Esse achado sugere que o futebol brasileiro tem se tornado marginalmente mais ofensivo ou que as táticas de ataque têm se tornado mais eficazes ao longo do período analisado.
Aproveitamento Geral: A classificação pelo Aproveitamento (percentual de pontos ganhos) estabeleceu um ranking de eficiência no formato de pontos corridos. As equipes no topo do ranking são aquelas que demonstraram a maior consistência em converter jogos em pontos, revelando os times mais bem-sucedidos da era moderna do Campeonato Brasileiro.
Os resultados deste relatório fornecem uma base de conhecimento para analistas esportivos modeladores estatísticos. A quantificação da volatilidade do Fator Casa e a identificação de tendências na média de gols são dados cruciais para a construção de modelos preditivos mais precisos. O estudo conclui que, apesar de mudanças táticas e eventos externos (como a pandemia), a essência do futebol brasileiro – definido pela força do mando de campo e pela competitividade que leva a um número significativo de empates – permanece.
Adão Duque. Brasileirão Série A: Resultados das Partidas (2003-2024). 29/11/2025. Disponível em: https://www.kaggle.com/datasets/adaoduque/campeonato-brasileiro-de-futebol
WICKHAM, Hadley. R for Data Science: Import, Tidy, Transform, Visualize, and Model Data. Sebastopol: O’Reilly Media, 2017.