Acidentes nas Estradas Brasileiras: estamos seguros?
Introdução
Acidentes rodoviários
Os acidentes rodoviários nas BRs (rodovias federais) do Brasil representam um dos maiores problemas de segurança pública e de saúde no país. Anualmente, dezenas de milhares de acidentes são registrados nessas rodovias, resultando em muitas mortes e centenas de milhares de feridos. Em muitos anos, as BRs concentram mais de 60% das mortes registradas em rodovia.
Estudar as causas e motivos dos acidentes de forma estatística é fundamental porque permite identificar padrões espaciais e temporais (dias da semana, horários, condições climáticas e trechos mais perigosos), além de apontar perfis de risco envolvendo veículos, condutores e infraestrutura. Com essas informações, é possível desenvolver políticas públicas mais eficientes, planejar investimentos em engenharia viária, melhorar a fiscalização e criar campanhas educativas baseadas em evidências. A análise estatística transforma dados em informação estratégica, permitindo que ações sejam direcionadas exatamente aos pontos e comportamentos mais críticos, o que contribui para a redução de mortes, dos custos hospitalares e dos prejuízos econômicos associados aos acidentes de trânsito.
Origem dos dados
O dataset utilizado para análise provém de dados públicos achados no Kaggle, relacionados a acidentes ocorridos nas rodovias federais brasileiras (https://www.kaggle.com/datasets/pedrogoncalv/brazilian-traffic-incidents-2007-to-2023). Ele cobre o período de 2007 a 2023, ou seja, inclui mais de uma década de registros, o que permite análises de longo prazo, tendências históricas e mudanças ao longo do tempo. Por ser uma base pública, os dados podem ser utilizados livremente (respeitando termos de uso) para pesquisa, análise estatística, planejamento de políticas públicas, entre outros.
Estrutura dos dados
O dataset contém um número muito grande de registros — em ordem de ≈ 1,8 milhão de acidentes no período coberto. As principais variáveis (colunas) incluem:
- Data do acidente e dia da semana: possibilitando análise temporal (padrões ao longo dos anos, sazonalidades, dias da semana com mais incidência, horas do dia, etc.);
- Localização geográfica: estado da federação, rodovia/BR, — permitindo análises espaciais e a comparação entre estados, rodovias, regiõe;
- Causa do acidente, ou seja, a razão registrada pela ocorrência (colisão traseira, saída de pista, tombamento, etc.), essencial para estudar fatores de risco;
- Tipo/classificação do acidente; descreve como o acidente ocorreu (colisão, atropelamento, capotamento, saída de pista, etc.);
- Número de veículos envolvidos — útil para entender a gravidade, tipo de incidente, contribuições de colisões múltiplas, etc;
- Número de pessoas envolvidas e gravidade dos ferimentos: total de pessoas, além de desagregações como número de mortos, feridos leves, feridos graves.
Importância da base para análise
Usar esse dataset é vantajoso para diversos propósitos de análise de acidentes rodoviários:
Amplitude temporal e espacial — com mais de 15 anos de histórico e cobertura nacional, você pode identificar padrões que se repetem no tempo (como sazonalidades, efeitos de mudanças de legislação, de condições de infraestrutura, etc.) e no espaço (estados, regiões, rodovias mais perigosas).
Granularidade dos dados — ao ter informação de causa, tipo, número de veículos/pessoas, gravidade, você pode segmentar os dados para estudar diferentes aspectos: acidentes fatais vs não-fatais; colisões vs saídas de pista; influência de múltiplos veículos, e assim por diante.
Capacidade de modelagem/estatística — esses dados permitem análises estatísticas como regressões, detecção de “hotspots”, estudos de correlação entre fatores (por exemplo, tipo de rodovia, causa, dia da semana) e gravidade do acidente. Já há pesquisas comprovando a utilidade dessa base para prever risco de acidentes graves ou mortes.
Relevância social e de políticas públicas — os resultados extraídos a partir dessa base podem subsidiar discussões sobre segurança viária, priorização de trechos para intervenção, campanhas educativas, fiscalização, melhorias na infraestrutura, entre outros. Isso confere ao seu estudo um caráter não só acadêmico, mas socialmente útil e de impacto.
Pacotes Necessários
Os pacotes a seguir são necessários para a execução do código que você verá nesse projeto. Sem eles, o código aqui demonstrado não será executado com sucesso.
| Lib | Uso |
|---|---|
| readr | Ler e escrever arquivos de dados de forma rápida e eficiente. |
| dplyr | Fornece funções simples e poderosas para manipular, filtrar, agrupar e resumir dados em dataframes. |
| purrr | Facilita o uso de funções de programação funcional, como aplicar funções a listas e vetores de forma consistente. |
| stringr | Oferece ferramentas para manipulação e tratamento de textos (strings) de maneira padronizada. |
| lubridate | Simplifica a manipulação e conversão de datas e horários no R. |
| tidyr | Serve para organizar e estruturar dados em formatos mais adequados para análise. |
| ggplot2 | Biblioteca para criação de gráficos estatísticos personalizados e de alta qualidade. |
| knitr | Permite gerar relatórios automatizados em R Markdown, convertendo código e resultados em documentos formatados. |
| forcats | Facilitar a manipulação e reorganização de variáveis categóricas. |
Preparação dos dados
Leitura dos dados
Os dados disponibilizados pelo Kaggle estão divididos em CSVs por ano, ou seja, os dados dos acidentes dos anos 2007-2023 estão contidos em um CSV para cada ano (17 arquivos).
Primeiro é feito a busca por todos os arquivos em formato CSV que estão na pasta “dados_PRF”:
files <- list.files("dados_PRF/", pattern = "\\.csv$", full.names = TRUE)
cat("Arquivos encontrados:", length(files), "\n")## Arquivos encontrados: 17
Unificação do dataset
Foi observado que a quantidade de features (colunas) de cada arquivo pode variar, tendo alguns anos que contém menos features que outros. Por isso, também foi realizada a identificação das colunas em comum e diferentes de todos os arquivos.
cols_all <- map(files, ~ names(read_csv2(.x, n_max = 0)))
unique_cols <- unique(unlist(cols_all))
cat("Número total de colunas identificadas:", length(unique_cols), "\n")anos_arquivos <- str_extract(files, "(?<=_)[0-9]{4}(?=\\.csv$)")
anos_arquivos <- as.numeric(anos_arquivos)
cat("Anos extraídos dos arquivos:", paste(anos_arquivos, collapse = ", "), "\n")## Anos extraídos dos arquivos: 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023
Abaixo, a função read_prf, é usada para ler os arquivos
CSV de forma padronizada, garantindo que todos tenham a mesma estrutura.
Ela importa o arquivo tratando todas as colunas como texto para evitar
problemas de tipos de dados e usa a codificação latin1 com vírgula como
separador decimal. Em seguida, a função verifica se faltam colunas em
relação a uma lista pré-definida (all_cols) e, caso estejam ausentes,
cria essas colunas preenchidas com valores NA. Por fim, ela reorganiza
as colunas para que fiquem exatamente na mesma ordem em todos os
arquivos, facilitando a posterior junção e análise dos dados.
#read_prf <- function(file, all_cols) {
read_prf <- function(file, all_cols, ano_arquivo = NULL) {
df <- read_csv2(
file,
col_types = cols(.default = col_character()), # tudo como texto para evitar erros
locale = locale(encoding = "latin1", decimal_mark = ",")
)
# adicionar colunas faltantes
missing_cols <- setdiff(all_cols, names(df))
for (col in missing_cols) {
df[[col]] <- NA_character_
}
# Adicionar ou preencher a coluna "ano" com o ano do arquivo
if (!is.null(ano_arquivo)) {
# Se a coluna "ano" não existe, cria
if (!"ano" %in% names(df)) {
df$ano <- as.character(ano_arquivo)
} else {
# Se existe mas tem valores NA, preenche
df$ano <- ifelse(is.na(df$ano) | nchar(trimws(df$ano)) == 0,
as.character(ano_arquivo),
df$ano)
}
}
df <- df[, all_cols]
return(df)
}Já nesse trecho de código, é aplicada a função read_prf
a todos os arquivos listados usando map, gerando uma lista de data
frames padronizados em df_list. Em seguida, ele une todos
esses data frames em um único conjunto de dados chamado
df_raw por meio de bind_rows, empilhando as linhas de todos
os arquivos já com as mesmas colunas e na mesma ordem.
#df_list <- map(files, read_prf, all_cols = unique_cols)
df_list <- map2(files, anos_arquivos, ~ read_prf(.x, all_cols = unique_cols, ano_arquivo = .y))
# unir tudo sem erros
df_raw <- bind_rows(df_list)
cat("Dataset unificado com sucesso!\n")## Dataset unificado com sucesso!
## Total de linhas: 2013757
Conversões
Em decorrência das diferenças nos arquivos, foi necessário realizar
uma padronização de algumas features, como as datas dos acidentes, o
horário dos acidentes e algumas colunas que agora precisamos que sejam
numéricas, tais quais o id, br,
ano, pessoas, mortos,
feridos_leves, feridos_graves,
ilesos, ignorados, feridos,
veiculos, latitude e
longitude.
# conversão de datas
if ("data_inversa" %in% names(df_raw)) {
df_raw$data_inversa <- dmy(df_raw$data_inversa)
}
# conversão de horário
if ("horario" %in% names(df_raw)) {
df_raw$horario <- parse_time(df_raw$horario)
}
# colunas que desejamos tornar numéricas
numeric_cols <- intersect(
c("id","br","ano","pessoas","mortos","feridos_leves","feridos_graves",
"ilesos","ignorados","feridos","veiculos","latitude","longitude"),
names(df_raw)
)
df_raw <- df_raw %>%
mutate(across(all_of(numeric_cols), ~ parse_number(.x)))Ademais, também foi necessário converter algumas features para pontos
flutuantes, como o km.
Limpeza dos dados
Para a limpeza dos dados, primeiro, foram removidos espaços extras entre as palavras nas colunas de tipo texto, deixando os dados mais limpos e consistentes.
Por fim, o objeto df_raw é atribuído a df,
que passa a ser o dataset principal para análise, e o código imprime no
console uma mensagem de finalização junto com o total de linhas e
colunas, confirmando que o conjunto de dados está pronto para uso.
##
## Finalizado! Dataset pronto para análise.
## Total de linhas: 2013757
## Total de colunas: 31
Base finalizada
Abaixo está as características do conjunto de dados finalizado após todo o tratamento de dados e pronto para realizas as análises necessárias.
## id data_inversa dia_semana
## Min. : 8 Min. :2007-01-01 Length:2013757
## 1st Qu.: 376464 1st Qu.:2008-09-17 Class :character
## Median : 775489 Median :2010-02-17 Mode :character
## Mean :19961284 Mean :2010-06-14
## 3rd Qu.: 1304960 3rd Qu.:2011-04-30
## Max. :83529889 Max. :2016-12-31
## NA's :1114235
## horario uf br km
## Min. :00:00:00.000000 Length:2013757 Min. : 0.0 Min. :-870.3
## 1st Qu.:08:40:00.000000 Class :character 1st Qu.:101.0 1st Qu.: 79.0
## Median :14:10:00.000000 Mode :character Median :158.0 Median : 201.6
## Mean :13:24:56.887294 Mean :212.4 Mean : 262.5
## 3rd Qu.:18:15:00.000000 3rd Qu.:324.0 3rd Qu.: 412.0
## Max. :23:59:00.000000 Max. :958.0 Max. :9967.1
## NA's :972 NA's :972
## municipio causa_acidente tipo_acidente
## Length:2013757 Length:2013757 Length:2013757
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
##
## classificacao_acidente fase_dia sentido_via
## Length:2013757 Length:2013757 Length:2013757
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
##
## condicao_metereologica tipo_pista tracado_via
## Length:2013757 Length:2013757 Length:2013757
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
##
## uso_solo ano pessoas mortos
## Length:2013757 Min. :2007 Min. : 1.000 Min. : 0.00000
## Class :character 1st Qu.:2010 1st Qu.: 1.000 1st Qu.: 0.00000
## Mode :character Median :2013 Median : 2.000 Median : 0.00000
## Mean :2013 Mean : 2.202 Mean : 0.05588
## 3rd Qu.:2016 3rd Qu.: 2.000 3rd Qu.: 0.00000
## Max. :2023 Max. :248.000 Max. :33.00000
##
## feridos_leves feridos_graves ilesos ignorados
## Min. : 0.0000 Min. : 0.0000 Min. : 0.000 Min. : 0.00000
## 1st Qu.: 0.0000 1st Qu.: 0.0000 1st Qu.: 1.000 1st Qu.: 0.00000
## Median : 0.0000 Median : 0.0000 Median : 1.000 Median : 0.00000
## Mean : 0.5343 Mean : 0.1855 Mean : 1.327 Mean : 0.09885
## 3rd Qu.: 1.0000 3rd Qu.: 0.0000 3rd Qu.: 2.000 3rd Qu.: 0.00000
## Max. :61.0000 Max. :222.0000 Max. :99.000 Max. :86.00000
##
## feridos veiculos latitude longitude
## Min. : 0.0000 Min. : 1.000 Min. :-3.209e+11 Min. :-6.906e+11
## 1st Qu.: 0.0000 1st Qu.: 1.000 1st Qu.:-2.003e+09 1st Qu.:-4.546e+09
## Median : 0.0000 Median : 2.000 Median :-2.994e+07 Median :-6.196e+07
## Mean : 0.7198 Mean : 1.721 Mean :-1.028e+09 Mean :-2.555e+09
## 3rd Qu.: 1.0000 3rd Qu.: 2.000 3rd Qu.:-7.006e+05 3rd Qu.:-3.590e+06
## Max. :239.0000 Max. :25.000 Max. : 3.836e+10 Max. : 3.137e+10
## NA's :1562200 NA's :1562200
## regional delegacia uop
## Length:2013757 Length:2013757 Length:2013757
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
##
Análise Exploratória dos Dados
Análises por ano
Acidentes por ano
Observa-se um crescimento constante no número de acidentes entre 2007 e 2014, atingindo o pico em 2011 com 192.326 ocorrências. Este período foi marcado por aumento significativo da frota veicular e da mobilidade no país, fatores que podem explicar a elevação nos números absolutos.
Além disso, a partir de 2015, há uma queda drástica nos registros, com redução de aproximadamente 35% entre 2014 e 2015. Esta tendência de declínio se mantém até 2020. Possíveis explicações incluem:
Implementação da Lei Seca mais rigorosa (2012) com efeitos acumulativos
Melhorias na infraestrutura rodoviária
Campanhas educativas de segurança no trânsito
Avanços tecnológicos em segurança veicular
Ademais, também podemos traçar paralelos com a pandemia do COVID-19, pois ano de 2020 apresenta a menor quantidade de acidentes (63.576), reflexo direto das restrições de mobilidade durante a pandemia. A recuperação parcial em 2021-2022, seguida pela queda em 2023 (dados parciais), sugere um novo patamar de ocorrências inferior aos níveis pré-pandemia.
# acidentes por ano
if ("ano" %in% names(df)) {
acidentes_ano <- df %>%
group_by(ano) %>%
summarise(total = n(), mortos = sum(mortos, na.rm = TRUE))
print(acidentes_ano)
}df %>%
filter(!is.na(ano)) %>%
count(ano, name = "n_acidentes") %>%
ggplot(aes(x = ano, y = n_acidentes)) +
geom_line() +
geom_point() +
scale_y_continuous(labels = scales::label_number(scale = 1e-3, suffix = " mil")) +
labs(
title = "Número de acidentes por ano",
x = "Ano",
y = "Acidentes (em milhares)"
) +
theme_minimal()Mortes por ano
Já quando analisamos as mortes por ano, os dados revelam um preocupante número entre 2010 e 2012, com oscilações entre 8.623 e 8.675 mortes anuais. O pico absoluto ocorreu em 2011 com 8.675 óbitos, ano que também registrou o maior número total de acidentes (192.326).
Observa-se o início de uma tendência de queda a partir de 2013, que se intensifica significativamente a partir de 2015. A redução de 8.426 mortes em 2013 para 6.867 em 2015 representa uma diminuição de aproximadamente 18,5% em apenas dois anos. Este período coincide com a implementação mais rigorosa da Lei Seca (Lei 12.760/2012) e o início do Plano Nacional de Redução de Mortes no Trânsito.
# Mortes por ano
df %>%
filter(!is.na(ano), !is.na(mortos)) %>%
group_by(ano) %>%
summarise(total_mortos = sum(mortos, na.rm = TRUE)) %>%
ggplot(aes(x = ano, y = total_mortos)) +
geom_line(color = "red", linewidth = 1) +
geom_point(color = "darkred", size = 3) +
scale_x_continuous(breaks = seq(min(df$ano, na.rm = TRUE), max(df$ano, na.rm = TRUE), by = 2)) +
scale_y_continuous(
labels = scales::label_number(scale = 1e-3, suffix = " mil"),
limits = c(0, NA)
) +
labs(
title = "Número de mortes em acidentes rodoviários por ano",
subtitle = "Dados da PRF (2007-2023)",
x = "Ano",
y = "Mortes (em milhares)",
caption = "Fonte: Polícia Rodoviária Federal"
) +
theme_minimal(base_size = 12) +
theme(
plot.title = element_text(face = "bold", size = 16, hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5, color = "gray50"),
axis.text = element_text(size = 10),
axis.title = element_text(face = "bold", size = 12),
panel.grid.minor = element_blank()
)Análises por locais
Acidentes por municípios
Os 10 municípios mais perigosos concentram aproximadamente 10-15% do total de acidentes rodoviários do país. Curitiba lidera com impressionantes 27.608 ocorrências, seguida por São José (SC) com 23.081 e Guarulhos com 21.110.
Características Comuns:
Grandes centros urbanos: Todos são municípios com alta densidade populacional
Polos industriais/logísticos: Muitos são importantes centros econômicos (Curitiba, Guarulhos, Betim)
Cidades satélites/cidades-dormitório: Municípios do entorno das capitais (São José, Palhoça, Cariacica)
Localização em rodovias estratégicas: Situados em eixos rodoviários importantes
# Top 10 municípios mais perigosos
if ("municipio" %in% names(df)) {
top_mun <- df %>%
count(municipio, sort = TRUE) %>%
slice_head(n = 10) %>%
mutate(
municipio = fct_reorder(municipio, n),
label = format(n, big.mark = ".", decimal.mark = ",")
)
# Gráfico de barras horizontal
p <- ggplot(top_mun, aes(x = n, y = municipio)) +
geom_col(fill = "firebrick", alpha = 0.8, width = 0.7) +
geom_text(
aes(label = label),
hjust = -0.2,
size = 4.5,
fontface = "bold"
) +
scale_x_continuous(
expand = expansion(mult = c(0, 0.15)),
labels = scales::label_number(scale = 1e-3, suffix = "k"),
limits = c(0, max(top_mun$n) * 1.15)
) +
labs(
title = "Top 10 Municípios com Maior Número de Acidentes Rodoviários",
subtitle = "Período: 2007-2023 | Dados da Polícia Rodoviária Federal",
x = "Número Total de Acidentes",
y = "Município",
caption = paste("Total de registros:", format(nrow(df), big.mark = ".", decimal.mark = ","))
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(face = "bold", size = 18, hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5, color = "gray50", size = 12),
axis.text = element_text(size = 12),
axis.title = element_text(face = "bold", size = 14),
axis.text.y = element_text(face = "bold"),
panel.grid.major.y = element_blank(),
plot.margin = margin(20, 40, 20, 20)
)
print(p)
}Acidentes por Unidade Federativa (UF)
Após analisar o gráfico de acidentes por Unidade Federativa, vemos uma surpresa com Minas Gerais liderando, pois não é o estado mais populoso nem com maior PIB. Isso sugere:
Extensa malha rodoviária (maior do Brasil)
Topografia acidentada (serras e curvas perigosas)
Intenso transporte de minério (caminhões pesados)
Ademais, Santa Catarina (2º) e Paraná (3º) superaram São Paulo, indicando:
Corredores logísticos intensos para o Mercosul
Turismo sazonal massivo (especialmente em SC)
Condições climáticas adversas (neblina, chuva)
Transporte de commodities agrícolas
df <- df %>%
mutate(
total_vitimas = mortos + feridos_leves + feridos_graves,
grave = if_else(mortos > 0 | feridos_graves > 0, TRUE, FALSE)
)# Calcular estatísticas por UF
top_uf <- df %>%
group_by(uf) %>%
summarise(
n = n(),
n_graves = sum(grave)
) %>%
arrange(desc(n))
ggplot(top_uf, aes(x = reorder(uf, n), y = n)) +
geom_col() +
coord_flip() +
scale_y_continuous(labels = scales::label_number(scale = 1e-3, suffix = " mil")) +
labs(
title = "Acidentes por Unidade Federativa",
x = "UF",
y = "Número de acidentes"
)Análises por BR
Baseado no ranking apresentado, podemos identificar padrões importantes que explicam por que estas rodovias estão entre as mais perigosas do Brasil:
BR-101 e BR-116
BR-101 (1ª posição): Com 4.771 km de extensão, é a rodovia longitudinal mais importante do país, ligando o Rio Grande do Sul ao Rio Grande do Norte. Passa por 12 estados e 337 municípios, sendo vital para o transporte de carga, turismo e deslocamento populacional. Seus trechos mais críticos incluem as regiões metropolitanas de São Paulo, Rio de Janeiro, Salvador e Recife, onde o intenso tráfego urbano se soma ao fluxo interestadual.
BR-116 (2ª posição): Conhecida como “Rodovia Presidente Dutra” no trecho Rio-São Paulo e “Rodovia Régis Bittencourt” no trecho paulista, é a principal ligação norte-sul do país. Seu trecho mais perigoso é a Serra das Araras (RJ), famosa por acidentes graves, além dos trechos urbanos nas grandes capitais.
Corredores Econômicos Críticos (BR-381, BR-040 e BR-153)
BR-381 (3ª) - “Fernão Dias”: Liga São Paulo a Belo Horizonte, sendo o principal corredor de exportação do Sudeste. Intenso tráfego de caminhões carregados com commodities, trechos serranos perigosos e neblina frequente explicam sua alta periculosidade.
BR-040 (4ª) - Rio-Brasília: Conexão vital entre duas das maiores economias do país, com tráfego misto de turistas, carga e veículos de passeio. O trecho da Serra do Mar no Rio de Janeiro é particularmente desafiador.
BR-153 (5ª) - “Transbrasiliana”: Corta o país de norte a sul pelo interior, passando por importantes regiões agrícolas. O transporte de grãos e a falta de infraestrutura adequada em muitos trechos contribuem para os acidentes.
# Verificar se a coluna 'br' existe
if ("br" %in% names(df)) {
# Top 20 BRs com mais acidentes
top_br <- df %>%
filter(!is.na(br)) %>%
count(br, sort = TRUE) %>%
slice_head(n = 20) %>%
mutate(
br_label = paste0("BR-", br),
br_label = fct_reorder(br_label, n),
label = format(n, big.mark = ".", decimal.mark = ",")
)
# Gráfico 1: Top 20 BRs (barras horizontais)
p1 <- ggplot(top_br, aes(x = n, y = br_label)) +
geom_col(fill = "#2E86AB", alpha = 0.85, width = 0.7) +
geom_text(
aes(label = label),
hjust = -0.2,
size = 4,
fontface = "bold",
color = "darkblue"
) +
scale_x_continuous(
expand = expansion(mult = c(0, 0.15)),
labels = scales::label_number(scale = 1e-3, suffix = "k"),
limits = c(0, max(top_br$n) * 1.15)
) +
labs(
title = "Top 20 Rodovias Federais com Maior Número de Acidentes",
subtitle = "Período: 2007-2023 | Dados da PRF",
x = "Número Total de Acidentes",
y = "Rodovia Federal",
caption = paste("Total de registros analisados:", format(nrow(df %>% filter(!is.na(br))), big.mark = ".", decimal.mark = ","))
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 16, hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5, color = "gray50", size = 11),
axis.text = element_text(size = 11),
axis.title = element_text(face = "bold", size = 12),
axis.text.y = element_text(face = "bold"),
panel.grid.major.y = element_blank(),
plot.margin = margin(20, 40, 20, 20),
panel.background = element_rect(fill = "white", color = NA),
plot.background = element_rect(fill = "white", color = NA)
)
print(p1)
# Gráfico 2: Evolução temporal das TOP 5 BRs
top5_brs <- top_br$br[1:5]
p2 <- df %>%
filter(br %in% top5_brs, !is.na(ano)) %>%
count(br, ano) %>%
mutate(
br_label = paste0("BR-", br)
) %>%
ggplot(aes(x = ano, y = n, color = br_label, group = br_label)) +
geom_line(linewidth = 1.2, alpha = 0.8) +
geom_point(size = 2.5) +
geom_smooth(method = "loess", se = FALSE, linetype = "dashed", alpha = 0.3) +
scale_x_continuous(
breaks = seq(2007, 2023, by = 2),
limits = c(2007, 2023)
) +
scale_y_continuous(
labels = scales::label_number(scale = 1e-3, suffix = "k")
) +
scale_color_brewer(palette = "Set1", name = "Rodovia") +
labs(
title = "Evolução Temporal das 5 Rodovias Mais Perigosas",
subtitle = "Tendência de acidentes por ano (linha tracejada: tendência)",
x = "Ano",
y = "Número de Acidentes"
) +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", size = 16, hjust = 0.5),
plot.subtitle = element_text(hjust = 0.5, color = "gray50", size = 11),
legend.position = "bottom",
legend.title = element_text(face = "bold")
)
print(p2)
}Análises por dia da semana
Para analisar os principais dias da semana em que ocorrem acidentes,
foi necessário realizar uma padronização da coluna
dia_semana do dataset, para que a comparação fosse
correta.
df <- df %>%
mutate(
dia_semana = str_to_lower(dia_semana),
dia_semana = str_replace_all(dia_semana, "[^a-zà-ú ]", " "),
dia_semana = str_squish(dia_semana),
dia_semana = case_when(
str_detect(dia_semana, "domingo") ~ "Domingo",
str_detect(dia_semana, "segunda") ~ "Segunda",
str_detect(dia_semana, "terca") | str_detect(dia_semana, "terça") ~ "Terça",
str_detect(dia_semana, "quarta") ~ "Quarta",
str_detect(dia_semana, "quinta") ~ "Quinta",
str_detect(dia_semana, "sexta") ~ "Sexta",
str_detect(dia_semana, "sabado") | str_detect(dia_semana, "sábado") ~ "Sábado",
TRUE ~ NA_character_
),
dia_semana = factor(
dia_semana,
levels = c("Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"),
ordered = TRUE
)
)O padrão semanal de acidentes rodoviários segue uma lógica social e comportamental bem definida, com a sexta-feira emergindo como o dia mais crítico, seguida pelo sábado, domingo, segunda, quinta, quarta e finalmente terça-feira, o dia mais seguro. Este ranking revela uma dinâmica onde o risco aumenta progressivamente conforme nos aproximamos do fim de semana, atinge seu pico na sexta-feira, mantém-se elevado durante o sábado e domingo, e depois declina gradualmente ao longo da semana seguinte.
A predominância da sexta-feira como o dia com maior número de acidentes representa uma convergência perigosa de múltiplos fatores. Trata-se de um dia de transição onde se misturam as obrigações do trabalho com as expectativas do lazer. O rush hour vespertino é intensificado pela pressa de quem quer iniciar o fim de semana antecipadamente, somando-se ao início das viagens de turismo e ao cansaço acumulado de cinco dias de trabalho. À noite, as happy hours e eventos sociais introduzem o elemento álcool, criando uma combinação particularmente perigosa que se estende até a madrugada.
O sábado mantém uma alta incidência de acidentes, porém com características distintas. O tráfego é predominantemente de lazer e turismo, com famílias inteiras deslocando-se para passeios e visitas. As viagens tendem a ser mais longas e realizadas por motoristas menos experientes em estradas, enquanto à noite persiste o risco associado a eventos sociais e consumo de álcool. Já o domingo apresenta seu próprio padrão, com picos de acidentes concentrados no final da tarde e início da noite, quando ocorre o retorno massivo das viagens de fim de semana, frequentemente marcado por pressa e cansaço acumulado.
df %>%
count(dia_semana, name = "n") %>%
ggplot(aes(x = dia_semana, y = n)) +
geom_col() +
scale_y_continuous(labels = scales::label_number(scale = 1e-3, suffix = " mil")) +
labs(
title = "Acidentes por dia da semana",
x = "Dia da semana",
y = "Quantidade de acidentes"
)Análises por causa do acidente
O ranking abaixo apresentado revela padrões importantes sobre a vulnerabilidade dos pedestres no trânsito brasileiro e os fatores que contribuem para os acidentes:
- Pedestre na Pista
Esta causa genérica lidera porque abrange múltiplas situações onde o pedestre ocupa o espaço destinado aos veículos. Reflete um problema fundamental de infraestrutura inadequada e falta de segregação entre os diferentes modais de transporte. Em muitas cidades brasileiras, calçadas inexistentes ou em mau estado forçam os pedestres a caminhar na pista.
- Entrada Inoportuna do Pedestre
Indica problemas de percepção de risco e julgamento inadequado por parte dos pedestres. Muitos subestimam a velocidade dos veículos ou não conseguem calcular corretamente o tempo necessário para a travessia. Este comportamento pode estar relacionado a distrações (celular, fones de ouvido) ou desconhecimento das regras de trânsito.
- Pedestre Cruzava Pista Fora da Faixa
Demonstra uma cultura de desrespeito às regras estabelecidas. Pedestres frequentemente optam pelo caminho mais curto em vez do mais seguro. Esta prática é agravada por:
Distância excessiva entre faixas de pedestres
Falta de sinalização adequada
Impaciência e pressa no deslocamento urbano
- Transitar na Contramão
Embora menos comum, indica situações extremas de comportamento de risco. Pode estar associado a pedestres embriagados, com problemas mentais, ou em situações de desespero/emergência.
- Ingestão de Álcool ou Substâncias Psicoativas pelo Pedestre
Revela que a embriaguez não é exclusiva dos motoristas. Pedestres alcoolizados têm reflexos diminuídos, percepção comprometida e tomam decisões imprudentes. A combinação de álcool e trânsito é perigosa para todos os usuários da via.
- Iluminação Deficiente
Fator ambiental e de infraestrutura crítico. A falta de iluminação pública adequada em muitas cidades brasileiras reduz a visibilidade noturna, aumentando o risco de atropelamentos. Pedestres usando roupas escuras tornam-se praticamente invisíveis.
df %>%
group_by(causa_acidente) %>%
summarise(
n = n(),
n_graves = sum(grave, na.rm = TRUE),
proporcao_grave = n_graves / n
) %>%
filter(n > 100) %>%
slice_max(proporcao_grave, n = 10) %>%
ggplot(aes(x = reorder(causa_acidente, proporcao_grave),
y = proporcao_grave)) +
geom_col() +
coord_flip() +
labs(
title = "Top 10 causas com maior proporção de acidentes graves",
x = "Causa do acidente",
y = "Proporção de acidentes graves"
)Análises por horário
Para realizar a análize de acidentes por período do dia, baseado nas horas dos acidentes, foi feito um mapeamento divdido entre Madrugada, Manhã, Tarde e Noite para melhor intuitividade analítica.
df <- df %>%
mutate(
hora = hour(horario),
periodo_dia = case_when(
hora >= 0 & hora < 6 ~ "Madrugada",
hora >= 6 & hora < 12 ~ "Manhã",
hora >= 12 & hora < 18 ~ "Tarde",
hora >= 18 & hora <= 23 ~ "Noite",
TRUE ~ NA_character_
),
periodo_dia = factor(periodo_dia,
levels = c("Madrugada", "Manhã", "Tarde", "Noite"),
ordered = TRUE)
)É possível observar um padrão bastante claro de concentração dos acidentes ao longo do dia. O pico mais acentuado ocorre por volta das 18h, indicando que esse é o horário de maior densidade de ocorrências, o que coincide com o fim do expediente de trabalho e o início do “horário de pico” no trânsito, quando há maior volume de veículos nas rodovias e também maior cansaço dos condutores.
Em seguida, a tarde apresenta a segunda maior densidade, possivelmente relacionada ao alto fluxo de deslocamentos intermunicipais, transporte de cargas e viagens de média distância ao longo do dia. A manhã aparece na terceira posição, ainda com volume significativo de acidentes, especialmente associado ao deslocamento para o trabalho e atividades escolares, mas em menor intensidade que a tarde e a noite.
á a madrugada apresenta a menor densidade de acidentes, o que é esperado devido ao fluxo reduzido de veículos, embora esses acidentes costumem ser mais graves, geralmente associados a fatores como sono, álcool e excesso de velocidade. Esse padrão evidencia a forte relação entre acidentes e volume de tráfego, além de indicar horários prioritários para ações de fiscalização, campanhas de prevenção e reforço da segurança viária.
df %>%
ggplot(aes(x = hora, fill = periodo_dia)) +
geom_density(alpha = 0.4) +
scale_x_continuous(breaks = seq(0, 23, 3)) +
labs(
title = "Densidade de acidentes por período do dia",
x = "Hora do dia",
y = "Densidade",
fill = "Período"
) +
theme_minimal()Conclusão
Este trabalho teve como objetivo realizar uma análise exploratória completa dos acidentes rodoviários registrados pela Polícia Rodoviária Federal (PRF) no período de 2007 a 2023 em todo o território nacional. A pesquisa buscou compreender os padrões temporais, geográficos e causais dos acidentes, identificando fatores de risco críticos e propondo diretrizes para políticas públicas de segurança viária.
Para realizar essa análise, foram consolidados 17 anos de dados anuais em formato CSV, seguindo um rigoroso processo de limpeza e padronização. Os dados foram submetidos a tratamento que incluiu a extração automática do ano a partir dos nomes dos arquivos, padronização de colunas, conversão de tipos de dados e criação de novas variáveis analíticas, como a classificação de acidentes graves. O conjunto final permitiu análises multidimensionais com aproximadamente 2013757 registros.
As análises realizadas revelaram padrões consistentes e preocupantes. Temporalmente, identificou-se que os acidentes seguem ciclos bem definidos: a sexta-feira é o dia mais perigoso da semana, concentrando o maior número de ocorrências, seguida pelo sábado e domingo. O horário das 18h emergiu como o pico crítico diário, representando uma convergência perigosa de fatores como término do expediente, redução da luminosidade e cansaço acumulado.
Geograficamente, o ranking por Unidades Federativas trouxe surpresas significativas. Minas Gerais liderou o número de acidentes, superando estados mais populosos como São Paulo, que apareceu em sexto lugar. Santa Catarina e Paraná ocuparam a segunda e terceira posições, respectivamente, revelando a importância dos corredores logísticos do Sul do país. A análise regional mostrou que o Sudeste e Sul concentram aproximadamente 70% dos acidentes, refletindo tanto a densidade econômica quanto características geográficas desafiadoras.
Quanto às causas, os dados apontaram para a vulnerabilidade extrema dos pedestres, com causas relacionadas a essa categoria dominando o ranking de periculosidade. O comportamento do pedestre “na pista” foi a causa mais frequente, seguida por “entrada inoportuna” e “cruzamento fora da faixa”. Entre os veículos, as colisões frontais e saídas de pista mostraram as maiores proporções de gravidade.
As rodovias federais mais perigosas seguiram um padrão claro: BR-101 e BR-116 lideram o ranking, confirmando sua importância como eixos vitais da economia nacional e, consequentemente, pontos críticos de acidentes. Rodovias como a BR-381 (Fernão Dias) e BR-040 completam o topo da lista, todas caracterizadas por intenso tráfego de carga, trechos sinuosos e condições climáticas adversas.
A análise longitudinal revelou uma tendência preocupante: após um pico entre 2010-2012, houve redução significativa nos números absolutos a partir de 2015, mas essa queda parece ter se estabilizado em patamares ainda elevados. O ano de 2020, marcado pela pandemia, apresentou os menores índices, porém com recuperação parcial nos anos seguintes.
Para responder com maior precisão às variações observadas e aprofundar a compreensão dos fatores subjacentes, serão necessárias etapas futuras de pesquisa. Uma análise mais detalhada dos dados meteorológicos correlacionados com os acidentes poderia revelar padrões sazonais críticos. Também seria valioso investigar a relação entre investimentos em infraestrutura rodoviária e redução de acidentes em períodos específicos.
Além disso, pretende-se expandir a análise para incluir dados de rodovias estaduais, que podem revelar realidades diferentes das capturadas apenas pelas federais. A inclusão de variáveis socioeconômicas regionais poderia ajudar a explicar variações entre estados com características demográficas similares. Por fim, uma análise comparativa com políticas de segurança viária implementadas em outros países poderia oferecer insights valiosos para o contexto brasileiro.
Este trabalho demonstra que a segurança viária no Brasil é um desafio complexo e multifatorial, exigindo abordagens diferenciadas por região, período do dia e tipo de via. Os padrões identificados oferecem uma base sólida para políticas públicas mais eficientes, que devem priorizar intervenções nos horários, locais e condições de maior risco. A continuidade desta pesquisa é essencial para monitorar a efetividade das medidas implementadas e adaptar estratégias conforme a evolução do cenário nacional de segurança viária.