O trânsito de Recife é um tema bastante relevante para sua população. Portanto, é interessante analisar dados sobre os acidentes de trânsito. Por exemplo, em 2023, 144 pessoas morreram em sinistros de trânsito no Recife. Sendo assim, serão analisados os dados de 2024, investigando se houve mais óbitos comparados ao ano anterior, quais bairros e quais meses tiveram mais acidentes, porcentagem de quantos acidentes tiveram vítimas fatais.
Como visto, diversos dados relevantes para a população recifense podem ser extraídos utilizando os dados disponíveis no portal oficial da cidade, sendo fundamental para identificar padrões e fatores de risco. Entender as circunstâncias que levam a esses acidentes permite o desenvolvimento de políticas públicas direcionadas e campanhas educativas mais eficazes.
Como foi antecipado, os dados a serem utilizados vão ser obtidos pelo portal oficial de Recife, que são sobre Acidentes de Trânsito em 2024. A partir dessas informações, vão ser extraídos alguns dados, como: quantidade de mortes envolvendo acidentes de trânsito em 2024, meses e bairros com mais acidentes.
library(rmarkdown) #Utilizado na conversão de arquivo em R em diversos formatos
library(knitr) #Para geração de tabelas
library(dplyr) #Para manipulação avançada dos DataFrames
##
## Anexando pacote: 'dplyr'
## Os seguintes objetos são mascarados por 'package:stats':
##
## filter, lag
## Os seguintes objetos são mascarados por 'package:base':
##
## intersect, setdiff, setequal, union
library(DT) #Para criar tabelas funcionais no HTML
library(lubridate) #Para manipulação avançada de datas
##
## Anexando pacote: 'lubridate'
## Os seguintes objetos são mascarados por 'package:base':
##
## date, intersect, setdiff, union
library(ggplot2) # Para visualização de gráficos
Os dados utilizados foram obtidos no portal oficial de Recife e podem ser acessados através desse link sobre Acidentes de Trânsito em 2024.
Estes dados têm como principal propósito mostrar os sinistros de trânsito com e sem vítimas do ano 2024, descrevendo o dia, data, hora e onde aconteceu. Esse conjunto de dados foi criado no dia 29/Julho/2024 e atualizado pela última vez no dia 20/Janeiro/2025, mas todas as suas informações foram coletadas ao decorrer do ano de 2024, apenas agrupadas posteriormente. Originalmente, possui 28 variáveis e 5315 inserções. As colunas são separadas por “;” e na existência de alguma célula vazia, nada é inserido, ficando vazio. A data é inserida no formato AAAA-MM-DD, a hora no formato HH-MM-SS, mas os segundos são sempre 00, ou seja, não são registrados. Ainda sobre a hora, é importante ressaltar que ela está no formato de 12, mas não tem indicação se é AM ou PM, resultando na impossibilidade de saber o período em que aconteceu. Os dados numéricos são inseridos com a sua parte fracionada, por exemplo, “1,0”, mas nunca há decimais, pois os dados são todos inteiros.
Para realizar a importação dos dados, primeiro eu defino o diretório de trabalho:
setwd("~/CPAD")
E depois faço a importação:
acidentes <- read.csv("acidentes2024.csv", sep=";")
datatable(head(acidentes, 5), options = list(scrollX = TRUE))
Sobre o comando acima, vale a pena salientar o uso do sep=“;”, como explicado, as colunas estão separadas por “;” e o comando read.csv espera que elas fossem separadas por “,”, desse modo, tenho que explicitar o símbolo de separação para o comando funcionar corretamente.
Nota-se que a partir da coluna “acidente_verificado” não há dados inseridos. Portanto, irei excluir essas colunas já que não possuem dados. Para isso, vou primeiro descobrir qual é o índice dessa coluna utilizando o seguinte comando:
indice <- which(names(acidentes) == "acidente_verificado")
print(indice)
## [1] 26
E em seguida, excluo todas as colunas desnecessárias, mantendo apenas o que vem antes dela:
acidentes <- acidentes[, 1:(indice-1)]
datatable(head(acidentes, 5), options = list(scrollX = TRUE))
Portanto, após esses comandos, restaram 25 colunas e 13 foram excluídas.Mas não são apenas essas colunas que não servem para análise de dados. As colunas “Protocolo”, “endereco”, “numero”, “detalhe_endereco_acidente”, “complemento”, “bairro_cruzamento” e “num_semaforo” também serão removidas. “Protocolo” porque não interessa o id, “bairro_cruzamento” pois os dados contidos nelas são iguais aos dados da coluna “bairro” e as outras listadas pois não precisamos desse nível de detalhes do endereço.
acidentes <- acidentes %>% select(-c(Protocolo, endereco, numero, detalhe_endereco_acidente, complemento, bairro_cruzamento, num_semaforo))
datatable(head(acidentes, 5), options = list(scrollX = TRUE))
Após essas novas remoções, sobraram 18 colunas, já que 7 foram excluídas. Agora é preciso remover as linhas cuja a situação seja duplicada, já que contém informações que outro registro tem e cancelada, já que não tem valor para as métricas.
acidentes <- acidentes %>% filter(!(situacao %in% c("DUPLICIDADE", "CANCELADA")))
datatable(head(acidentes, 5), options = list(scrollX = TRUE))
Com essa última operação, foram deletadas 385 linhas, restando 4930. Após isso, a coluna “situacao” não tem mais serventia, por isso será deleteda. A coluna “tipo”, “natureza” e “sentido_via” serão transformadas em fatores. Mas antes, o próximo passo é a substituição de células vazias por NA, para facilitar o trabalho do R na interpretação dos dados e também na transformação de algumas colunas em dados númericos. Uma observação importante a ser feita, é que na biblioteca DT, utilizada para a visualização da tabela, trata valores NA como string vazias, por isso o NA não ta sendo observado.
acidentes <- acidentes %>% mutate_all(~na_if(., ""))
datatable(head(acidentes, 5), options = list(scrollX = TRUE))
Mas antes de fazer, como comentado acima, preciso tratar os dados da coluna sentido_via, pois há dados incorretos:
acidentes$sentido_via[acidentes$sentido_via == "1987"] <- NA
acidentes$sentido_via[acidentes$sentido_via %in% c("BOA VIAGEM", "PRAIA", "CI", "CID")] <- "CIDADE"
acidentes$sentido_via[acidentes$sentido_via %in% c("OLINDA", "SUB")] <- "SUBURBIO"
acidentes <- acidentes %>%
select(-situacao) %>%
mutate(across(c(tipo, natureza, sentido_via), as.factor))
datatable(head(acidentes, 5), options = list(scrollX = TRUE))
Verificando os níveis de cada um dos fatores:
levels(acidentes$tipo)
## [1] "ATROPELAMENTO DE ANIMAL" "ATROPELAMENTO DE PESSOA"
## [3] "CAPOTAMENTO" "CHOQUE"
## [5] "COLISÃO" "COLISÃO COM CICLISTA"
## [7] "COLISÃO FRONTAL" "COLISÃO LATERAL"
## [9] "COLISÃO TRANSVERSAL" "COLISÃO TRASEIRA"
## [11] "ENGAVETAMENTO" "QUEDA"
## [13] "TOMBAMENTO"
levels(acidentes$natureza)
## [1] "COM VÍTIMA" "SEM VÍTIMA" "VÍTIMA FATAL"
levels(acidentes$sentido_via)
## [1] "CIDADE" "SUBURBIO"
Passado todas essas manipulações, aqui esta resumidamente em algumas linhas como ficou o conjunto de dados final:
datatable(head(acidentes, 10), options = list(scrollX = TRUE))
4930 linhas e 17 colunas, sendo que dessas 17 colunas, 3 são fatores. Sobre as variáveis, temos:
Primeiro, vou criar uma nova variável chamada região, onde nela vai conter a região em que ocorreu o acidente. Recife tem 6 regiões:
acidentes <- acidentes %>%
mutate(regiao = case_when(
bairro %in% c("BAIRRO DO RECIFE", "SANTO AMARO", "BOA VISTA", "CABANGA", "ILHA DO LEITE", "PAISSANDU", "SANTO ANTONIO", "SAO JOSE", "COELHOS", "SOLEDADE", "ILHA JOANA BEZERRA", "JOANA BEZERRA" ) ~ "central",
bairro %in% c("ARRUDA", "CAMPINA DO BARRETO", "ENCRUZILHADA", "HIPODROMO", "CAMPO GRANDE", "PEIXINHOS", "PONTO DE PARADA", "ROSARINHO", "TORREAO", "AGUA FRIA", "ALTO SANTA TERESINHA", "BOMBA DO HEMETERIO", "CAJUEIRO", "FUNDAO", "PORTO DA MADEIRA", "BEBERIBE", "DOIS UNIDOS", "LINHA DO TIRO") ~ "norte",
bairro %in% c("AFLITOS", "ALTO DO MANDU", "ALTO JOSE BONIFACIO", "ALTO JOSE DO PINHO", "APIPUCOS", "BREJO DA GUABIRABA", "BREJO DE BEBERIBE", "CASA AMARELA", "CASA FORTE", "CORREGO DO JENIPAPO", "DERBY", "DOIS IRMAOS", "ESPINHEIRO", "GRACAS", "GUABIRABA", "JAQUEIRA", "MACAXEIRA", "MONTEIRO", "NOVA DESCOBERTA", "PARNAMIRIM", "PASSARINHO", "PAU-FERRO", "POCO DA PANELA", "SANTANA", "SITIO DOS PINTOS", "TAMARINEIRA", "MANGABEIRA", "MORRO DA CONCEICAO", "VASCO DA GAMA") ~ "noroeste",
bairro %in% c("CORDEIRO", "ILHA DO RETIRO", "IPUTINGA", "MADALENA", "PRADO", "TORRE", "ZUMBI", "ENGENHO DO MEIO", "TORROES", "CAXANGA", "CIDADE UNIVERSITARIA", "VARZEA") ~ "oeste",
bairro %in% c("AFOGADOS", "AREIAS", "BARRO", "BONGI", "CACOTE", "COQUEIRAL", "CURADO", "ESTANCIA", "JARDIM SAO PAULO", "JIQUIA", "MANGUEIRA", "MUSTARDINHA", "SAN MARTIN", "SANCHO", "TEJIPIO", "TOTO") ~ "sul",
bairro %in% c("BOA VIAGEM", "BRASILIA TEIMOSA", "IMBIRIBEIRA", "IPSEP", "PINA", "IBURA", "JORDAO", "COHAB") ~ "sudoeste",
TRUE ~ "Desconhecida" #Caso o bairro não esteja na lista
))
datatable(head(acidentes, 5), options = list(scrollX = TRUE))
Vou também criar uma tabela em que me mostra quantos acidentes teve por mês, juntamente com seu gráfico:
meses <- c("jan", "fev", "mar", "abr", "mai", "jun",
"jul", "ago", "set", "out", "nov", "dez")
# Criar o novo dataframe com a contagem de acidentes por mês
acidentes_mes <- acidentes %>%
mutate(
mes = factor(format(as.Date(data), "%b"),
levels = format(seq(as.Date("2024-01-01"), by = "month", length.out = 12), "%b"),
labels = meses)
) %>%
group_by(mes) %>%
summarise(quantidade = n(), .groups = "drop")
print(acidentes_mes)
## # A tibble: 12 × 2
## mes quantidade
## <fct> <int>
## 1 jan 365
## 2 fev 323
## 3 mar 385
## 4 abr 389
## 5 mai 408
## 6 jun 407
## 7 jul 438
## 8 ago 451
## 9 set 473
## 10 out 416
## 11 nov 432
## 12 dez 443
ggplot(acidentes_mes, aes(x = mes, y = quantidade, fill = mes)) +
geom_bar(stat = "identity", show.legend = FALSE) +
labs(title = "Número de Acidentes por Mês",
x = "Mês",
y = "Quantidade de Acidentes") +
theme_minimal() +
theme(text = element_text(size = 14))
E outra tabela e gráfico que mostra os acidentes por regiões como também a porcentagem:
acidentes_regiao <- acidentes %>%
group_by(regiao) %>%
summarise(quantidade = n(), .groups = "drop") %>%
arrange(desc(quantidade)) # Ordena da maior para a menor quantidade
acidentes_regiao <- acidentes_regiao %>%
mutate(perc = quantidade / sum(quantidade) * 100, # Calcula percentual
label = paste0(regiao, "\n", quantidade, " (", round(perc, 1), "%)")) # Rótulo com nome, valor e percentual
# Exibir o novo dataframe
print(acidentes_regiao)
## # A tibble: 7 × 4
## regiao quantidade perc label
## <chr> <int> <dbl> <chr>
## 1 sudoeste 1285 26.1 "sudoeste\n1285 (26.1%)"
## 2 oeste 827 16.8 "oeste\n827 (16.8%)"
## 3 central 815 16.5 "central\n815 (16.5%)"
## 4 noroeste 809 16.4 "noroeste\n809 (16.4%)"
## 5 sul 629 12.8 "sul\n629 (12.8%)"
## 6 norte 559 11.3 "norte\n559 (11.3%)"
## 7 Desconhecida 6 0.122 "Desconhecida\n6 (0.1%)"
## Criar o gráfico de pizza com valores
ggplot(acidentes_regiao, aes(x = "", y = quantidade, fill = regiao)) +
geom_bar(stat = "identity", width = 1, color = "white") +
coord_polar(theta = "y") +
geom_text(aes(label = label), position = position_stack(vjust = 0.5), size = 3.2) + #Adiciona os valores dentro das fatias
labs(title = "Distribuição de Acidentes por Região") +
theme_minimal() +
theme(axis.text.x = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank()) +
guides(fill = guide_legend(title = "Região"))
Com isso, descobrimos que a maioria dos acidentes do ano de 2024 foram na região sudoeste, como também o mês que ocorreu mais sinistros, sendo este o mês de Setembro.
Podemos verificar, também qual ocorrência é a mais comum:
## Criar um dataframe agrupando por tipo de colisão
acidentes_tipo <- acidentes %>%
group_by(tipo) %>%
summarise(quantidade = n(), .groups = "drop") %>%
arrange(desc(quantidade)) # Ordena da maior para a menor quantidade
# Exibir o novo dataframe
print(acidentes_tipo)
## # A tibble: 14 × 2
## tipo quantidade
## <fct> <int>
## 1 COLISÃO 2576
## 2 COLISÃO LATERAL 1176
## 3 COLISÃO TRASEIRA 359
## 4 COLISÃO FRONTAL 250
## 5 ATROPELAMENTO DE PESSOA 170
## 6 CHOQUE 113
## 7 COLISÃO COM CICLISTA 84
## 8 QUEDA 74
## 9 COLISÃO TRANSVERSAL 61
## 10 <NA> 26
## 11 CAPOTAMENTO 20
## 12 ENGAVETAMENTO 11
## 13 TOMBAMENTO 7
## 14 ATROPELAMENTO DE ANIMAL 3
##Criar o gráfico de barras
ggplot(acidentes_tipo, aes(x = reorder(tipo, -quantidade), y = quantidade, fill = tipo)) +
geom_bar(stat = "identity", show.legend = FALSE) +
labs(title = "Número de Acidentes por Tipo de Colisão",
x = "Tipo de Colisão",
y = "Quantidade de Acidentes") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1, size = 12))
Logo, o tipo mais comum é colisão, sem explicitar o tipo de colisão, seguido de colisão lateral.
Por fim, outro dado importante é sobre o quantitativo de acidentes com vítimas e vítimas fatais.
## Contar o total de acidentes
acidentes_total <- nrow(acidentes)
## Agrupar por natureza e calcular a quantidade e porcentagem
acidentes_natureza <- acidentes %>%
group_by(natureza) %>%
summarise(quantidade = n(), .groups = "drop") %>%
mutate(porcentagem = (quantidade / acidentes_total) * 100) %>%
arrange(desc(quantidade)) # Ordena do maior para o menor
# Exibir o resultado
print(acidentes_natureza)
## # A tibble: 3 × 3
## natureza quantidade porcentagem
## <fct> <int> <dbl>
## 1 COM VÍTIMA 4339 88.0
## 2 SEM VÍTIMA 558 11.3
## 3 VÍTIMA FATAL 33 0.669
##Criar o gráfico de barras horizontais
ggplot(acidentes_natureza, aes(x = reorder(natureza, porcentagem), y = porcentagem, fill = natureza)) +
geom_bar(stat = "identity", show.legend = FALSE) +
geom_text(aes(label = paste0(quantidade, " (", round(porcentagem, 1), "%)")),
hjust = -0.2, size = 5) + # Exibe "Quantidade (Porcentagem%)"
labs(title = "Distribuição de Acidentes por Natureza",
x = "Natureza do Acidente",
y = "Porcentagem (%)") +
theme_minimal() +
coord_flip() + # Deixa as barras horizontais
expand_limits(y = max(acidentes_natureza$porcentagem) * 1.5) # Adiciona mais espaço no eixo Y
Isso nós mostrou que apenas 0,7%, ou seja, 33 de 4930 tiveram vítimas fatais.
Este trabalho teve como propósito analisar os acidentes de trânsito ocorridos em Recife no ano de 2024. Com isso, foi possível obter informações pertinentes e que ajudam toda a sociedade recifense.
Portanto, os meios utilizados para chegar nos resultados adequados foram, primeiramente, realizar uma limpa nos dados desnecessários e corrigir dados que estavam errados, como também a criação de novos dados a partir dos existentes no portal oficial da cidade de Recife.
Após todas as manipulações, descobrimos dados interessantes. Por exemplo, o mês em que mais aconteceram sinistros foi em setembro. A região que mais ocorreu acidentes foi a sudoeste, que compreende os seguintes bairros: Boa Viagem; Brasília Teimosa; Imbiribeira; Ipsep; Pina; Ibura; Jordão; Cohab. O tipo de colisão mais frequente não é tão explicito nos dados, pois geralmente, a maioria tem somente “colisão”, mas logo em seguida, temos a “colisão lateral” como a mais comum. Por último, felizmente, apenas 0,7% dos acidentes houve fatalidades. Representando uma redução de 66.67% comparada com as fatalidades em acidentes em 2023, já que houve 48 óbitos.
Estes possibilitam a população saber as localidades em que o risco de acidente é maior, como também as repartições públicas, já que conseguem intensificar campanhas de trânsitos em regiões com maior índice de acidentes, além de saber se campanhas anteriores surtiram efeito com base na redução de óbitos comparado ao ano de 2023.
Como limitações, não foi possível saber o período do dia em que acidentes são mais comuns e mais fatais. Isso seria possessível se os dados sobre a hora estivessem no formato 24h ou com AM, ou PM. Além disso, poderia detalhar mais sobre os dados relacionados ao tipo de automóvel envolvido no sinistro, a fim de, por exemplo, oferecer mais possibilidade de campanhas publicitárias direcionadas aos motoristas específicos para cada automóvel.
“Perfil dos Bairros de Recife”, https://www2.recife.pe.gov.br/servico/perfil-dos-bairros
“Acidentes de Trânsito de Recife em 2024”, http://dados.recife.pe.gov.br/it/dataset/acidentes-de-transito-com-e-sem-vitimas/resource/29afbf42-a36c-475c-8b75-761e17e67679
“Mortes no trânsito Recife bate novo recorde”, https://jc.ne10.uol.com.br/colunas/mobilidade/2024/11/18/mortes-no-transito-recife-bate-novo-recorde-de-mortes-no-transito-aumento-foi-de-37-em-2023.html