1 Introdução

1.1 Declaração do Problema e Relevância

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.

1.2 Abordagem, Dados e Metodologia

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:

  • Análise Temporal: Uso de gráficos de linha para avaliar a evolução anual do Fator Casa e da média de gols.
  • Modelagem Estatística: A distribuição dos gols será comparada com a Distribuição de Poisson para verificar a aderência do modelo teórico aos dados observados.
  • Análise Descritiva: Uso de tabelas e gráficos de barras para classificar os resultados gerais, o fator casa regionalizado por estado e o desempenho por equipe (frequência de empates e aproveitamento).

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?

1.3 Valor e Clientes Potenciais

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.

2 Pacotes Necessários

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"
try(Sys.setlocale("LC_ALL", "Portuguese_Brazil.1252"))
[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).

3 Carregamento dos Dados

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"
# Visualizar a estrutura inicial dos dados
glimpse(dados_br)
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~

4 Limpeza e Pré-processamento dos Dados

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.

4.1 Tratamento de Valores Ausentes (NA’s) e Inconsistências

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"

4.2 Ajuste de Tipos de Dados e Conversão de Variáveis

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

4.3 Criação de Variáveis Derivadas (Feature Engineering)

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
Amostra do Dataset Final (dados_br_final)
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.

5 Análise Exploratória

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)

5.1 Fator Casa e Distribuição de Resultados

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):"
print(resumo_resultados)
# 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)
Proporção Anual dos Resultados
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.”

5.2 Análise da Distribuição de Gols

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:"
print(head(resumo_gols, 10)) # Mostra as 10 maiores contagens de gols
# 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)

5.2.1 Análise Estatística da Distribuição de Gols (Poisson)

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)

5.2.2 Tendência Temporal da Média de Gols

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)
Média de Gols por Ano
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)

5.3 Fator Casa por Estado

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:"
print(top_estados)
[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.

5.4 Análise por Equipe: Empates e Desempenho

5.4.1 Frequência de Empates por Equipe

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)
Top 10 Equipes com Maior Proporção de Empates (2003-2024)
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

5.4.2 Desempenho Geral (Vitórias, Derrotas, Empates)

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)
Top 10 Equipes com Melhor Aproveitamento (2003-2024)
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

6 Conclusão

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.

7 Referências

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.