1. Introdução

1.1 Contexto e Relevância

O excesso de velocidade nas vias urbanas representa um dos principais fatores de risco para acidentes de trânsito graves e fatais. Em Recife, uma metrópole com mais de 1,6 milhão de habitantes e intensa circulação diária de veículos, a análise dos dados de fiscalização eletrônica de velocidade oferece uma oportunidade única para compreender padrões de comportamento dos motoristas e identificar áreas críticas que demandam intervenção.

Este estudo é relevante para diversos públicos:

  • Gestores públicos: Podem utilizar os insights para direcionar recursos de fiscalização e implementar medidas preventivas em locais e horários críticos.
  • Urbanistas e engenheiros de tráfego: Podem identificar necessidades de intervenções estruturais em vias com alto índice de infrações.
  • Cidadãos: Podem se beneficiar de informações que contribuam para um trânsito mais seguro e eficiente.
  • Pesquisadores: Podem utilizar estes dados como base para estudos mais aprofundados sobre comportamento no trânsito urbano.

Segundo a Organização Mundial da Saúde, a cada 1% de aumento na velocidade média, há um aumento de 4% no risco de acidentes fatais. Isso torna o monitoramento e análise desses dados não apenas uma questão administrativa, mas de saúde pública.

1.2 Problema de Pesquisa

Este projeto busca responder às seguintes questões:

  1. Quais são os padrões temporais (horários, dias da semana e meses) do fluxo de veículos e das infrações de velocidade em Recife?
  2. Existem locais específicos que apresentam índices críticos de desrespeito aos limites de velocidade?
  3. Como diferentes tipos de equipamentos de fiscalização (lombadas e fotossensores) se comparam em termos de eficácia na detecção de infrações?
  4. Há correlação entre características específicas das vias (velocidade permitida, localização) e o comportamento dos motoristas?

1.3 Abordagem Metodológica

Para abordar estas questões, adotei uma metodologia de análise exploratória de dados (EDA) utilizando a linguagem R e um conjunto de pacotes especializados para manipulação e visualização de dados. O processo incluiu:

  1. Importação e limpeza de múltiplos conjuntos de dados públicos da Prefeitura do Recife
  2. Transformação e padronização dos dados para formatos apropriados à análise
  3. Análise temporal e geográfica dos padrões de tráfego e infrações
  4. Criação de visualizações para comunicar os resultados

Uma característica fundamental desta abordagem é a conversão dos dados do formato “largo” para o formato “longo”, permitindo análises mais granulares e a criação de novas variáveis derivadas, como a classificação de infrações e o cálculo de excesso percentual de velocidade.

1.4 Relevância para Stakeholders

Os resultados deste estudo podem beneficiar diversos grupos:

  • Secretaria de Mobilidade Urbana: Otimização da alocação de recursos fiscalizatórios e avaliação da eficácia das medidas existentes.
  • CTTU (Companhia de Trânsito e Transporte Urbano): Identificação de pontos críticos para intervenções específicas.
  • Empresas de transporte público e privado: Compreensão dos padrões de tráfego para otimização de rotas e horários.
  • Comunidade acadêmica: Base empírica para estudos mais aprofundados sobre comportamento no trânsito urbano.
  • Cidadãos: Acesso a informações que contribuam para deslocamentos mais seguros e eficientes.

Esta análise também contribui para o movimento de dados abertos e ciência de dados aplicada à gestão pública, demonstrando como informações coletadas rotineiramente podem gerar insights valiosos quando adequadamente processadas e interpretadas.

2. Pacotes e Transformação dos Dados

2.1 Carregamento dos Pacotes

# Manipulação de dados
library(tidyverse)    # Conjunto de pacotes para manipulação de dados
library(readr)        # Importação eficiente de dados
library(lubridate)    # Manipulação de datas
library(janitor)      # Limpeza de nomes de variáveis

# Visualização
library(ggplot2)      # Criação de gráficos
library(plotly)       # Gráficos interativos
library(leaflet)      # Mapas interativos
library(viridis)      # Paletas de cores acessíveis
library(scales)       # Formatação de escalas em gráficos

# Apresentação
library(knitr)        # Geração de relatórios dinâmicos
library(kableExtra)   # Tabelas formatadas
library(DT)           # Tabelas interativas
library(flexdashboard) # Layout de dashboard

Propósito e Funcionalidade dos Pacotes

Esta análise utiliza diversos pacotes R, cada um com funções específicas que se complementam:

Pacotes para manipulação de dados: - tidyverse: Um meta-pacote que inclui ferramentas essenciais como dplyr (manipulação), tidyr (organização), purrr (programação funcional) e ggplot2 (visualização). Utilizo principalmente as funções de filtragem, agrupamento e sumarização. - readr: Oferece funções mais rápidas e flexíveis para importação de dados, especialmente útil para lidar com os diferentes formatos de arquivos CSV dos equipamentos de fiscalização. - lubridate: Simplifica a manipulação de datas e horas, permitindo extrair facilmente componentes como dia da semana e criar classificações temporais. - janitor: Facilita a limpeza de nomes de variáveis e dados com funções como clean_names().

Pacotes para visualização: - ggplot2: Implementa a “gramática dos gráficos” para criar visualizações estatísticas complexas com código declarativo. - plotly: Permite converter gráficos estáticos em interativos, facilitando a exploração dos padrões temporais. - leaflet: Integra a biblioteca JavaScript Leaflet para criar mapas interativos dos pontos de fiscalização. - viridis: Fornece paletas de cores cientificamente validadas e perceptualmente uniformes, importantes para visualizações acessíveis. - scales: Facilita a formatação de números em gráficos, especialmente útil para valores formatados com separadores de milhar.

Pacotes para apresentação: - knitr: Integra código R e resultados em um documento dinâmico. - kableExtra: Estende as funcionalidades de tabulação do knitr, permitindo criar tabelas bem formatadas. - DT: Cria tabelas interativas com recursos de pesquisa, paginação e ordenação. - flexdashboard: Fornece a estrutura para organizar o relatório em formato de dashboard.

2.2 Descrição e Origem dos Dados

2.2.1 Fonte e Contexto dos Dados

Os dados utilizados neste estudo foram obtidos do Portal de Dados Abertos da Prefeitura do Recife, especificamente da seção de “Mobilidade Urbana”. Estes dados são coletados pela Autarquia de Trânsito e Transporte Urbano do Recife (CTTU) como parte do programa de fiscalização eletrônica de velocidade no município.

O conjunto de dados representa registros completos de 2020, cobrindo todo o sistema de monitoramento de velocidade da cidade, que inclui dois tipos principais de equipamentos:

  1. Lombadas Eletrônicas: Dispositivos fixos que monitoram a velocidade pontualmente, normalmente instalados em vias locais ou coletoras.
  2. Fotossensores: Equipamentos mais sofisticados, geralmente instalados em vias arteriais ou de trânsito rápido.

Estes dados são coletados em tempo real pelos equipamentos, que registram o número de veículos que passam por cada faixa de velocidade em intervalos de 15 minutos, 24 horas por dia, 7 dias por semana. O propósito original desta coleta é administrativo e fiscalizatório, visando monitorar o cumprimento dos limites de velocidade e direcionar ações de educação e fiscalização no trânsito.

2.2.2 Estrutura Original dos Dados

O conjunto de dados original está dividido em múltiplos arquivos:

  1. Tabela de Equipamentos (lombadas-fotossensores.csv): Contém informações sobre cada equipamento de fiscalização, incluindo:
    • Identificador único do equipamento
    • Tipo de equipamento (lombada ou fotossensor)
    • Logradouro onde está instalado
    • Velocidade regulamentada da via
    • Coordenadas geográficas (latitude e longitude)
  2. Tabelas Mensais de Fotossensores (ex: recife-fotossensores-20-janeiro.csv): 12 arquivos (um para cada mês) contendo os registros de velocidade dos fotossensores, com as variáveis:
    • Identificador do equipamento
    • Faixa de rolamento
    • Data e hora do registro
    • Intervalo de minutos (em blocos de 15 minutos)
    • Contagens de veículos em 11 faixas de velocidade (0-10km/h, 11-20km/h, etc.)
  3. Tabelas Mensais de Lombadas (ex: janeirolomb2020.csv): 12 arquivos (um para cada mês) contendo os registros de velocidade das lombadas eletrônicas, com estrutura similar às tabelas de fotossensores.

Uma peculiaridade importante destes dados é que eles estão em formato “largo”, onde cada faixa de velocidade é uma coluna separada, tornando necessária uma transformação para formato “longo” para facilitar as análises.

Outros desafios incluem: - Nomenclatura inconsistente entre arquivos mensais - Diferentes separadores decimais (vírgula em vez de ponto) - Falta de padronização nos identificadores de equipamentos (alguns com sufixo “REC”) - Potenciais dados faltantes ou inconsistentes

2.2.3 Importação dos Dados

O processo de importação foi estruturado para lidar com as particularidades dos arquivos:

# Importando dados dos equipamentos
lombadas_fotossensores <- read_delim("lombadas-fotossensores.csv", 
                                    delim = ";", 
                                    locale = locale(decimal_mark = ",")) %>%
  mutate(
    velocidade_via = as.integer(str_extract(velocidade_via, "\\d+")),
    equipamento = as.character(equipamento)  # Garantir que equipamento é character
  )

# Função para importar dados mensais de fotossensores
importar_fotossensores_mensais <- function(mes) {
  arquivo <- sprintf("recife-fotossensores-20-%s.csv", mes)
  dados <- read_delim(arquivo, 
                      delim = ";", 
                      locale = locale(decimal_mark = ","),
                      col_types = cols(
                        mes = col_integer(),
                        equipamento = col_character(),
                        faixa = col_integer(),
                        data = col_date(format = ""),
                        hora = col_integer(),
                        minutos_intervalo = col_character(),
                        .default = col_integer()
                      ))
  return(dados)
}

# Função para importar dados mensais de lombadas
importar_lombadas_mensais <- function(mes) {
  arquivo <- sprintf("%slomb2020.csv", mes)
  dados <- read_delim(arquivo, 
                      delim = ";", 
                      locale = locale(decimal_mark = ","),
                      col_types = cols(
                        ano = col_integer(),
                        mes = col_character(),
                        equipamento = col_character(),
                        faixa = col_integer(),
                        data = col_date(format = ""),
                        hora = col_integer(),
                        minutos_intervalo = col_character(),
                        .default = col_integer()
                      ))
  return(dados)
}

# Importando o mês de janeiro para demonstração
fotossensores_janeiro <- importar_fotossensores_mensais("janeiro")
lombadas_janeiro <- importar_lombadas_mensais("janeiro")

Foi criada uma abordagem funcional para importar os dados mensais, permitindo tratar de forma padronizada arquivos com nomenclaturas diferentes. Essa abordagem utiliza funções como sprintf() para construir nomes de arquivos parametrizados e locale() para lidar com as particularidades regionais de formatação numérica.

2.2.4 Visualização dos Dados Brutos

Vejamos como se apresentam as estruturas originais dos dados:

# Exibindo primeiras linhas dos dados
head(lombadas_fotossensores) %>%
  kable(caption = "Tabela de Equipamentos (lombadas_fotossensores)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE,
                position = "left") %>%
  scroll_box(width = "100%", height = "300px") 
Tabela de Equipamentos (lombadas_fotossensores)
equipamento tipo logradouro velocidade_via latitude longitude
5941 Lombada AV. MAL. MASCARENHAS DE MORAES, EM FRENTE AEROPORTO - SENT. PRAZERES 60 -81309702 -349161612
5942 Lombada AV. MAL. MASCARENHAS DE MORAES, EM FRENTE AEROPORTO - SENT. CENTRO 60 -81306469 -349158856
5943 Lombada AV. BOA VIAGEM - TERCEIRO JARDIM 60 -81078431 -348881609
5944 Lombada DEFRONTE A PCA. GOV. PAULO GUERRA, CABANGA - SENT. PINA 60 -80801208 -348921866
5945 Lombada APOS PONTE AGAMENON MAGALHAES, CABANGA - SENT. DERBY 60 -80808198 -348911590
5946 Lombada AV. BOA VIAGEM – EM FRENTE PARQUE DONA LINDU 60 -81410665 -349032775
head(fotossensores_janeiro, 3) %>%
  kable(caption = "Dados de fotossensores (Janeiro 2020)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE,
                position = "left") %>%
  scroll_box(width = "100%", height = "300px") 
Dados de fotossensores (Janeiro 2020)
mes equipamento faixa data hora minutos_intervalo qtd_0a10km qtd_11a20km qtd_21a30km qtd_31a40km qtd_41a50km qtd_51a60km qtd_61a70km qtd_71a80km qtd_81a90km qtd_91a100km qtd_acimade100km
1 FS002REC 1 2020-01-01 0 0-15 1 2 8 2 0 0 0 0 0 0 0
1 FS002REC 1 2020-01-01 0 16-30 0 8 8 3 0 0 0 0 0 0 0
1 FS002REC 1 2020-01-01 0 31-45 0 12 21 2 0 0 0 0 0 0 0
head(lombadas_janeiro, 3) %>%
  kable(caption = "Dados de lombadas (Janeiro 2020)") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE,
                position = "left") %>%
  scroll_box(width = "100%", height = "300px") 
Dados de lombadas (Janeiro 2020)
ano mes equipamento faixa data hora minutos_intervalo qtd_0a10km qtd_11a20km qtd_21a30km qtd_31a40km qtd_41a50km qtd_51a60km qtd_61a70km qtd_71a80km qtd_81a90km qtd_91a100km qtd_acimade100km
2020 01 1 1 2020-01-01 10 10:00-10:15 0 2 1 7 25 13 0 0 0 0 0
2020 01 1 1 2020-01-01 10 10:15-10:30 0 0 0 6 9 8 0 0 0 0 0
2020 01 1 1 2020-01-01 10 10:30-10:45 1 0 2 9 13 7 0 0 0 0 0

Como podemos observar, os dados originais apresentam:

  1. Tabela de Equipamentos: Informações cadastrais sobre cada ponto de fiscalização
  2. Fotossensores: Registros mensais com colunas para cada faixa de velocidade
  3. Lombadas: Estrutura similar aos fotossensores, mas com algumas diferenças na nomenclatura

2.3 Processo de Transformação e Limpeza dos Dados

2.3.1 Consolidação dos Dados Mensais

O primeiro desafio foi consolidar os 24 arquivos mensais (12 para fotossensores e 12 para lombadas) em uma única estrutura de dados. Para isso, foi criada uma função genérica para importar e padronizar os dados:

# Função para importar dados mensais
importar_dados_mensais <- function(tipo, mes) {
  if(tipo == "fotossensores") {
    arquivo <- sprintf("recife-fotossensores-20-%s.csv", mes)
    dados <- read_delim(arquivo, 
                       delim = ";", 
                       locale = locale(decimal_mark = ",")) %>%
      mutate(
        mes = as.integer(mes),
        equipamento = as.character(equipamento),
        tipo_equipamento = str_to_title(tipo)
      )
  } else {
    arquivo <- sprintf("%slomb2020.csv", mes)
    dados <- read_delim(arquivo, 
                       delim = ";", 
                       locale = locale(decimal_mark = ",")) %>%
      mutate(
        mes = as.integer(mes),
        equipamento = as.character(equipamento),
        tipo_equipamento = tipo
      )
  }
  
  return(dados)
}

# Lista de meses
meses <- c("janeiro", "fevereiro", "marco", "abril", "maio", "junho",
           "julho", "agosto", "setembro", "outubro", "novembro", "dezembro")

# Importar todos os dados
dados_completos <- map_df(meses, function(mes) {
  fotossensores <- tryCatch({
    importar_dados_mensais("fotossensores", mes)
  }, error = function(e) {
    warning(sprintf("Erro ao importar fotossensores do mês %s: %s", mes, e$message))
    return(NULL)
  })
  
  lombadas <- tryCatch({
    importar_dados_mensais("lombadas", mes)
  }, error = function(e) {
    warning(sprintf("Erro ao importar lombadas do mês %s: %s", mes, e$message))
    return(NULL)
  })
  
  bind_rows(fotossensores, lombadas)
}) %>%
  # Limpeza do sufixo REC
  mutate(equipamento = str_replace(equipamento, "REC$", ""))

Esta abordagem utiliza programação funcional através da função map_df() do pacote purrr, que aplica a mesma função a cada elemento de uma lista (neste caso, cada mês) e combina os resultados em um único data frame. Também foi implementado tratamento de erros com tryCatch() para lidar com possíveis arquivos ausentes ou corrompidos.

2.3.2 Transformação para Formato Longo

Um desafio significativo foi transformar os dados do formato “largo” original para um formato “longo”, mais adequado para análise. No formato original, cada faixa de velocidade é uma coluna separada, dificultando análises comparativas entre faixas.

# Transformação para formato longo
dados_longos <- dados_completos %>%
  pivot_longer(
    cols = starts_with("qtd_"),
    names_to = "faixa_velocidade",
    values_to = "quantidade_veiculos"
  ) %>%
  mutate(
    faixa_velocidade = case_when(
      faixa_velocidade == "qtd_0a10km" ~ "0-10",
      faixa_velocidade == "qtd_11a20km" ~ "11-20",
      faixa_velocidade == "qtd_21a30km" ~ "21-30",
      faixa_velocidade == "qtd_31a40km" ~ "31-40",
      faixa_velocidade == "qtd_41a50km" ~ "41-50",
      faixa_velocidade == "qtd_51a60km" ~ "51-60",
      faixa_velocidade == "qtd_61a70km" ~ "61-70",
      faixa_velocidade == "qtd_71a80km" ~ "71-80",
      faixa_velocidade == "qtd_81a90km" ~ "81-90",
      faixa_velocidade == "qtd_91a100km" ~ "91-100",
      faixa_velocidade == "qtd_acimade100km" ~ ">100"
    ),
    velocidade_media = case_when(
      faixa_velocidade == "0-10" ~ 5,
      faixa_velocidade == "11-20" ~ 15,
      faixa_velocidade == "21-30" ~ 25,
      faixa_velocidade == "31-40" ~ 35,
      faixa_velocidade == "41-50" ~ 45,
      faixa_velocidade == "51-60" ~ 55,
      faixa_velocidade == "61-70" ~ 65,
      faixa_velocidade == "71-80" ~ 75,
      faixa_velocidade == "81-90" ~ 85,
      faixa_velocidade == "91-100" ~ 95,
      faixa_velocidade == ">100" ~ 110
    ),
    periodo = case_when(
      hora >= 0 & hora < 6 ~ "Madrugada",
      hora >= 6 & hora < 12 ~ "Manhã",
      hora >= 12 & hora < 18 ~ "Tarde",
      hora >= 18 ~ "Noite"
    ),
    dia_semana = factor(wday(data),
                       levels = 1:7,
                       labels = c("Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"))
  )

Este processo envolveu:

  1. Usar pivot_longer() para transformar as colunas de faixas de velocidade em linhas
  2. Padronizar os nomes das faixas para um formato mais legível
  3. Criar uma coluna velocidade_media estimada para cada faixa
  4. Adicionar classificações temporais como periodo (parte do dia) e dia_semana

2.3.3 Enriquecimento com Dados de Localização e Classificação de Infrações

Para permitir análises mais avançadas, foi necessário: 1. Mesclar os registros de velocidade com as informações de localização e velocidade regulamentada 2. Criar novas variáveis derivadas para análise de infrações

# Junção com dados de localização
dados_finais <- dados_longos %>%
  left_join(lombadas_fotossensores, by = "equipamento") %>%
  mutate(
    acima_limite = velocidade_media > velocidade_via,
    excesso_kmh = if_else(acima_limite, velocidade_media - velocidade_via, 0),
    excesso_percentual = (velocidade_media / velocidade_via - 1) * 100
  )

Nesta etapa: 1. Utilizamos left_join() para mesclar os dados de velocidade com as informações cadastrais dos equipamentos 2. Criamos a variável booleana acima_limite para identificar infrações 3. Calculamos métricas de excesso como excesso_kmh (em km/h) e excesso_percentual (percentual acima do limite)

2.3.4 Tratamento de Valores Ausentes e Inconsistências

Durante o processo de limpeza, foram identificados e tratados diversos casos de valores ausentes ou inconsistentes:

# Verificando e tratando valores ausentes no campo equipamento
dados_completos <- dados_completos %>%
  mutate(equipamento = if_else(is.na(equipamento), "Não identificado", equipamento))

# Verificando quantidade de registros com informações ausentes
registros_incompletos <- dados_finais %>%
  filter(is.na(tipo) | is.na(logradouro) | is.na(velocidade_via)) %>%
  nrow()

cat("Registros com informações cadastrais incompletas:", registros_incompletos, "\n")
## Registros com informações cadastrais incompletas: 18150

Os principais desafios encontrados e soluções adotadas foram:

  1. Equipamentos não identificados: Alguns registros não possuíam código de equipamento válido - estes foram marcados como “Não identificado”
  2. Registros sem correspondência: Registros de equipamentos que não constavam na tabela de cadastro - mantidos na análise, mas com ressalvas
  3. Valores atípicos: Picos incomuns de velocidade em determinados horários - mantidos para análise, mas sinalizados nas visualizações

2.4 Estrutura Final dos Dados

Após todo o processo de transformação, o conjunto de dados final possui a seguinte estrutura:

# Visualização dos dados transformados
head(dados_finais) %>%
  # select(data, hora, periodo, faixa_velocidade, quantidade_veiculos, 
  #        logradouro, velocidade_via, acima_limite) %>%
  kable(caption = "Dados Finais Transformados") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), 
                full_width = FALSE,
                position = "left") %>%
  scroll_box(width = "100%", height = "300px") 
Dados Finais Transformados
mes equipamento faixa data hora minutos_intervalo tipo_equipamento ano faixa_velocidade quantidade_veiculos velocidade_media periodo dia_semana tipo logradouro velocidade_via latitude longitude acima_limite excesso_kmh excesso_percentual
1 FS002 1 2020-01-01 0 0-15 Fotossensores NA 0-10 1 5 Madrugada Qua Fotossensor RUA MADRE DE DEUS, SEMAFORO 020. 30 -80634002 -348736694 FALSE 0 -83.33333
1 FS002 1 2020-01-01 0 0-15 Fotossensores NA 11-20 2 15 Madrugada Qua Fotossensor RUA MADRE DE DEUS, SEMAFORO 020. 30 -80634002 -348736694 FALSE 0 -50.00000
1 FS002 1 2020-01-01 0 0-15 Fotossensores NA 21-30 8 25 Madrugada Qua Fotossensor RUA MADRE DE DEUS, SEMAFORO 020. 30 -80634002 -348736694 FALSE 0 -16.66667
1 FS002 1 2020-01-01 0 0-15 Fotossensores NA 31-40 2 35 Madrugada Qua Fotossensor RUA MADRE DE DEUS, SEMAFORO 020. 30 -80634002 -348736694 TRUE 5 16.66667
1 FS002 1 2020-01-01 0 0-15 Fotossensores NA 41-50 0 45 Madrugada Qua Fotossensor RUA MADRE DE DEUS, SEMAFORO 020. 30 -80634002 -348736694 TRUE 15 50.00000
1 FS002 1 2020-01-01 0 0-15 Fotossensores NA 51-60 0 55 Madrugada Qua Fotossensor RUA MADRE DE DEUS, SEMAFORO 020. 30 -80634002 -348736694 TRUE 25 83.33333

O conjunto final de dados inclui: - Dimensões temporais: Data, hora, período do dia, dia da semana, mês - Localização: Equipamento, logradouro, coordenadas geográficas - Velocidade: Faixa de velocidade, velocidade média estimada, limite da via - Métricas de infração: Indicador de excesso, quantidade em km/h, percentual

A transformação de formato “largo” para “longo” resultou em uma explosão do número de linhas, saindo da casa dos 3 milhões de linhas para aproximadamente 38 milhões de linhas, mas proporcionou muito maior flexibilidade analítica. Cada registro agora representa o número de veículos em determinada faixa de velocidade, em determinado equipamento, durante um intervalo de 15 minutos.

2.5 Limitações e Considerações Metodológicas

É importante reconhecer algumas limitações inerentes a estes dados:

  1. Agrupamento em faixas de velocidade: Os dados originais já vêm agregados em faixas, não permitindo análises precisas sobre a distribuição contínua de velocidades.
  2. Estimativa de velocidade média: Para cada faixa, utilizei o ponto médio como estimativa da velocidade média, o que é uma simplificação da realidade.
  3. Cobertura territorial desigual: Os equipamentos de fiscalização não estão distribuídos uniformemente pela cidade, o que pode criar viés geográfico nas análises.
  4. Impacto da pandemia: 2020 foi um ano atípico devido à COVID-19, com restrições de mobilidade que podem ter alterado significativamente os padrões de tráfego.
  5. Ausência de metadados detalhados: Não há informações sobre calibração, manutenção ou eventuais períodos de inatividade dos equipamentos.

Estas limitações foram consideradas nas análises subsequentes e interpretação dos resultados.

3. Análise Exploratória

3.1 Visão Geral dos Dados

# Estatísticas gerais
stats_gerais <- dados_finais %>%
  summarise(
    total_registros = n(),
    total_veiculos = sum(quantidade_veiculos, na.rm = TRUE),
    total_equipamentos = n_distinct(equipamento),
    media_diaria = round(total_veiculos / n_distinct(data), 0)
  )

# Visualização das estatísticas
kable(stats_gerais, 
      format = "html",
      caption = "Estatísticas Gerais dos Dados",
      format.args = list(big.mark = ".")) %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Estatísticas Gerais dos Dados
total_registros total_veiculos total_equipamentos media_diaria
38.601.079 278.364.052 70 758.485

3.2 Análise Temporal

3.2.1 Movimentação e Infrações por horário

# Preparar os dados para ambas as métricas
analise_horaria <- dados_finais %>%
  filter(!is.na(hora)) %>%
  group_by(hora) %>%
  summarise(
    total_infracoes = sum(quantidade_veiculos * acima_limite, na.rm = TRUE),
    total_veiculos = sum(quantidade_veiculos, na.rm = TRUE),
    percentual_infracoes = round((total_infracoes / total_veiculos) * 100, 2),
    .groups = 'drop'
  )

# Determinar a proporção entre os eixos para visualização adequada
# Encontrar a proporção aproximada entre os valores máximos
proporcao <- max(analise_horaria$total_veiculos) / max(analise_horaria$total_infracoes)


# Versão alternativa com legenda em vez de cores nos títulos dos eixos
ggplot(analise_horaria) +
  # Linha e pontos para infrações (eixo Y primário)
  geom_line(aes(x = hora, y = total_infracoes, color = "Infrações"), size = 1.2) +
  geom_point(aes(x = hora, y = total_infracoes, color = "Infrações"), size = 3) +
  
  # Linha e pontos para volume total (eixo Y secundário)
  geom_line(aes(x = hora, y = total_veiculos / proporcao, color = "Volume Total"), size = 1.2) +
  geom_point(aes(x = hora, y = total_veiculos / proporcao, color = "Volume Total"), size = 3) +
  
  # Configuração dos eixos
  scale_y_continuous(
    name = "Total de Infrações",
    labels = scales::comma,
    sec.axis = sec_axis(~.*proporcao, name = "Total de Veículos", labels = scales::comma)
  ) +
  scale_x_continuous(breaks = 0:23) +
  
  # Configuração de cores
  scale_color_manual(values = c("Infrações" = "red", "Volume Total" = "blue")) +
  
  # Estilo e títulos
  theme_minimal() +
  labs(
    title = "Infrações e Volume de Veículos por Hora do Dia",
    subtitle = "Distribuição ao longo do dia",
    x = "Hora",
    color = ""
  ) +
  theme(
    plot.title = element_text(face = "bold"),
    axis.title = element_text(face = "bold"),
    panel.grid.major = element_line(color = "gray90"),
    panel.grid.minor = element_line(color = "gray95"),
    legend.position = "bottom"
  )

# Gráfico com percentual de infrações por hora - mantendo os valores nas barras
ggplot(analise_horaria) +
  geom_col(aes(x = hora, y = percentual_infracoes, fill = percentual_infracoes), 
           width = 0.7) +
  geom_text(aes(x = hora, y = percentual_infracoes, 
                label = paste0(format(percentual_infracoes, decimal.mark = ","), "%")),
            vjust = -0.5, size = 3) +
  scale_fill_gradient(low = "lightblue", high = "darkred") +
  scale_x_continuous(breaks = 0:23) +
  theme_minimal() +
  guides(fill = "none") +
  labs(title = "Percentual de Infrações por Hora do Dia",
       subtitle = "Proporção de veículos que cometem infrações em cada horário",
       x = "Hora",
       y = "% de Infrações") +
  theme(
    plot.title = element_text(face = "bold"),
    axis.title = element_text(face = "bold"),
    panel.grid.minor = element_blank()
  )

3.2.2 Padrão Semanal

# Preparar os dados
analise_dia_semana <- dados_finais %>%
  filter(!is.na(dia_semana)) %>%
  group_by(dia_semana) %>%
  summarise(
    total_veiculos = sum(quantidade_veiculos, na.rm = TRUE),
    total_infracoes = sum(quantidade_veiculos * acima_limite, na.rm = TRUE),
    percentual_infracoes = round((total_infracoes / total_veiculos) * 100, 1),
    .groups = 'drop'
  )

# Gráfico de barras principal com veículos
ggplot(analise_dia_semana) +
  # Barras para total de veículos
  geom_col(aes(x = dia_semana, y = total_veiculos), fill = "steelblue", alpha = 0.7) +
  
  # Linha com percentual de infrações (eixo secundário)
  geom_line(aes(x = dia_semana, y = total_veiculos * percentual_infracoes/100), 
            color = "red", size = 1.5, group = 1) +
  geom_point(aes(x = dia_semana, y = total_veiculos * percentual_infracoes/100), 
             color = "red", size = 3) +
  
  # Rótulos nas barras
  geom_text(aes(x = dia_semana, y = total_veiculos, 
                label = scales::comma(total_veiculos)), vjust = -0.5) +
  
  # Rótulos na linha percentual
  geom_text(aes(x = dia_semana, y = total_veiculos * percentual_infracoes/100, 
                label = paste0(percentual_infracoes, "%")), 
            vjust = -0.8, color = "red", fontface = "bold") +
  
  # Escalas e eixos
  scale_y_continuous(
    name = "Total de Veículos",
    labels = scales::comma,
    sec.axis = sec_axis(~.*100/max(analise_dia_semana$total_veiculos), 
                        name = "% de Infrações", labels = function(x) paste0(round(x, 1), "%"))
  ) +
  
  # Estilo e títulos
  theme_minimal() +
  labs(title = "Volume de Veículos e Percentual de Infrações por Dia da Semana",
       subtitle = "Barras: total de veículos | Linha vermelha: percentual de infrações",
       x = "Dia da Semana",
       y = "Total de Veículos") +
  theme(
    plot.title = element_text(face = "bold"),
    axis.title = element_text(face = "bold"),
    axis.title.y.right = element_text(color = "red"),
    panel.grid.minor = element_blank(),
    axis.text.x = element_text(angle = 0, hjust = 0.5)
  )

# Análise por dia da semana
analise_semanal <- dados_finais %>%
  filter(!is.na(dia_semana)) %>%
  group_by(dia_semana, periodo) %>%
  summarise(
    media_veiculos = round(mean(quantidade_veiculos, na.rm = TRUE), 0),
    media_infracoes = round(mean(quantidade_veiculos * acima_limite, na.rm = TRUE), 0),
    .groups = 'drop'
  )

# Gráfico de movimentação por dia e período - sem valores nas barras
ggplot(analise_semanal, 
       aes(x = dia_semana, y = media_veiculos, fill = periodo)) +  # Corrigido: fill = periodo sem aspas
  geom_col(position = "dodge") +
  theme_minimal() +
  scale_fill_viridis_d() +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Média de Veículos por Dia da Semana e Período",
       x = "Dia da Semana",
       y = "Média de Veículos",
       fill = "Período") +
  theme(
    legend.position = "top",
    panel.grid.minor = element_blank(),
    axis.text.x = element_text(angle = 0, hjust = 0.5),
    plot.title = element_text(face = "bold")
  )

3.2.3 Padrão Mensal

# Análise mensal
analise_mensal <- dados_finais %>%
  filter(!is.na(mes)) %>%
  mutate(
    nome_mes = factor(month.abb[mes], levels = month.abb)
  ) %>%
  group_by(mes, nome_mes) %>%
  summarise(
    total_veiculos = sum(quantidade_veiculos, na.rm = TRUE),
    total_infracoes = sum(quantidade_veiculos * acima_limite, na.rm = TRUE),
    percentual_infracoes = round((total_infracoes / total_veiculos) * 100, 2),
    .groups = 'drop'
  )

# Criar anotações para os períodos importantes
anotacoes <- data.frame(
  mes = c(3, 4),
  nome_mes = factor(c("Mar", "Apr"), levels = month.abb),
  nota = c("Início das\nrestrições", "Início das\nrestrições"),
  y_pos = c(0.9, 0.85)
)

# Gráfico 1: Tendência de movimentação e infrações em um único gráfico (layout vertical)
plot1 <- ggplot(analise_mensal) +
  geom_line(aes(x = nome_mes, y = total_veiculos, group = 1), color = "blue", size = 1.2) +
  geom_point(aes(x = nome_mes, y = total_veiculos), color = "blue", size = 3) +
  geom_text(aes(x = nome_mes, y = total_veiculos, label = scales::comma(total_veiculos)), 
            vjust = -0.8, size = 3) +
  # Adicionar linhas verticais para destacar períodos importantes
  geom_vline(xintercept = which(month.abb == "Mar"), linetype = "dashed", alpha = 0.5) +
  geom_text(data = anotacoes %>% filter(mes == 3),
            aes(x = nome_mes, y = y_pos * max(analise_mensal$total_veiculos), label = nota),
            size = 3.5, fontface = "bold") +
  theme_minimal() +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Tendência de Movimentação ao Longo do Ano",
       x = "",  # Remover label do eixo X para o primeiro gráfico
       y = "Total de Veículos") +
  theme(
    axis.text.x = element_text(angle = 0, hjust = 0.5),
    plot.title = element_text(face = "bold"),
    plot.margin = margin(b = 0)  # Reduzir margem inferior
  )

plot2 <- ggplot(analise_mensal) +
  geom_line(aes(x = nome_mes, y = total_infracoes, group = 1), color = "darkred", size = 1.2) +
  geom_point(aes(x = nome_mes, y = total_infracoes), color = "darkred", size = 3) +
  geom_text(aes(x = nome_mes, y = total_infracoes, label = scales::comma(total_infracoes)), 
            vjust = -0.8, size = 3) +
  # Adicionar linhas verticais para destacar períodos importantes
  geom_vline(xintercept = which(month.abb == "Mar"), linetype = "dashed", alpha = 0.5) +
  geom_text(data = anotacoes %>% filter(mes == 4),
            aes(x = nome_mes, y = y_pos * max(analise_mensal$total_infracoes), label = nota),
            size = 3.5, fontface = "bold") +
  theme_minimal() +
  scale_y_continuous(labels = scales::comma) +
  labs(title = "Tendência de Infrações ao Longo do Ano",
       x = "Mês",
       y = "Total de Infrações") +
  theme(
    axis.text.x = element_text(angle = 0, hjust = 0.5),
    plot.title = element_text(face = "bold"),
    plot.margin = margin(t = 0)  # Reduzir margem superior
  )

# Combinar os dois gráficos em uma única visualização
gridExtra::grid.arrange(plot1, plot2, nrow = 2)

3.3 Análise Volume de Veículos x Infrações

Neste tópico estão sendo comparadas o valor percentual de infrações com relação ao volume de veículos na rua.

# Preparar dados para análise da correlação entre volume de tráfego e taxa de infrações
correlacao_volume_infracoes <- dados_finais %>%
  filter(!is.na(mes)) %>%
  mutate(
    nome_mes = factor(month.abb[mes], levels = month.abb)
  ) %>%
  group_by(mes, nome_mes) %>%
  summarise(
    total_veiculos = sum(quantidade_veiculos, na.rm = TRUE),
    total_infracoes = sum(quantidade_veiculos * acima_limite, na.rm = TRUE),
    percentual_infracoes = round((total_infracoes / total_veiculos) * 100, 2),
    .groups = 'drop'
  )
# Criar anotações para os períodos importantes
anotacoes <- data.frame(
  mes = c(3, 4),
  nome_mes = factor(c("Mar", "Apr"), levels = month.abb),
  nota = c("Início das\nrestrições", "Lockdown\nmais severo"),
  y_pos = rep(max(correlacao_volume_infracoes$percentual_infracoes) * 0.9, 2)
)
# Gráfico comparativo entre volume de tráfego e taxa de infrações por mês
ggplot() +
  # Linha para o volume de veículos (eixo esquerdo)
  geom_line(data = correlacao_volume_infracoes, 
            aes(x = nome_mes, y = total_veiculos, group = 1, color = "Volume de Tráfego"),
            size = 1.2) +
  geom_point(data = correlacao_volume_infracoes, 
             aes(x = nome_mes, y = total_veiculos, color = "Volume de Tráfego"),
             size = 3) +
  
  # Linha para o percentual de infrações (eixo direito)
  geom_line(data = correlacao_volume_infracoes, 
            aes(x = nome_mes, y = percentual_infracoes * max(total_veiculos) / max(percentual_infracoes), 
                group = 1, color = "% de Infrações"),
            size = 1.2) +
  geom_point(data = correlacao_volume_infracoes, 
             aes(x = nome_mes, y = percentual_infracoes * max(total_veiculos) / max(percentual_infracoes), 
                 color = "% de Infrações"),
             size = 3) +
  
  # Adicionar rótulos de dados
  geom_text(data = correlacao_volume_infracoes, 
            aes(x = nome_mes, 
                y = total_veiculos, 
                label = scales::comma(total_veiculos)),
            vjust = -0.8, size = 3, color = "darkblue") +
  
  geom_text(data = correlacao_volume_infracoes, 
            aes(x = nome_mes, 
                y = percentual_infracoes * max(total_veiculos) / max(percentual_infracoes), 
                label = paste0(format(percentual_infracoes, decimal.mark = ","), "%")),
            vjust = 1.8, size = 3, color = "darkred") +
  
  # Linhas verticais para destacar o início da pandemia
  geom_vline(xintercept = which(month.abb == "Mar"), linetype = "dashed", alpha = 0.5) +
  
  # Destacar anotações importantes
  geom_text(data = anotacoes,
            aes(x = nome_mes, y = y_pos * max(correlacao_volume_infracoes$total_veiculos) / max(correlacao_volume_infracoes$percentual_infracoes), 
                label = nota),
            size = 3.5, fontface = "bold") +
  
  # Configurar eixos duplos
  scale_y_continuous(
    name = "Volume de Tráfego (veículos)",
    labels = scales::comma,
    sec.axis = sec_axis(~. * max(correlacao_volume_infracoes$percentual_infracoes) / max(correlacao_volume_infracoes$total_veiculos), 
                        name = "Percentual de Infrações (%)")
  ) +
  
  # Configurar cores
  scale_color_manual(values = c("Volume de Tráfego" = "darkblue", "% de Infrações" = "darkred")) +
  
  # Adicionar título e tema
  labs(title = "Relação entre Volume de Tráfego e Taxa de Infrações durante 2020",
       subtitle = "Análise do impacto da redução de tráfego devido à pandemia na taxa de infrações",
       x = "Mês") +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", size = 14),
    plot.subtitle = element_text(size = 12),
    axis.title = element_text(face = "bold"),
    panel.grid.minor = element_blank(),
    legend.title = element_blank(),
    legend.position = "top"
  )

# NOVO GRÁFICO 1: Análise por dia da semana
# Preparar dados para análise por dia da semana
correlacao_semanal <- dados_finais %>%
  filter(!is.na(dia_semana)) %>%
  group_by(dia_semana) %>%
  summarise(
    total_veiculos = sum(quantidade_veiculos, na.rm = TRUE),
    total_infracoes = sum(quantidade_veiculos * acima_limite, na.rm = TRUE),
    percentual_infracoes = round((total_infracoes / total_veiculos) * 100, 2),
    .groups = 'drop'
  )

# Gráfico comparativo entre volume de tráfego e taxa de infrações por dia da semana
ggplot() +
  # Linha para o volume de veículos (eixo esquerdo)
  geom_line(data = correlacao_semanal, 
            aes(x = dia_semana, y = total_veiculos, group = 1, color = "Volume de Tráfego"),
            size = 1.2) +
  geom_point(data = correlacao_semanal, 
             aes(x = dia_semana, y = total_veiculos, color = "Volume de Tráfego"),
             size = 3) +
  
  # Linha para o percentual de infrações (eixo direito)
  geom_line(data = correlacao_semanal, 
            aes(x = dia_semana, y = percentual_infracoes * max(total_veiculos) / max(percentual_infracoes), 
                group = 1, color = "% de Infrações"),
            size = 1.2) +
  geom_point(data = correlacao_semanal, 
             aes(x = dia_semana, y = percentual_infracoes * max(total_veiculos) / max(percentual_infracoes), 
                 color = "% de Infrações"),
             size = 3) +
  
  # Adicionar rótulos de dados
  geom_text(data = correlacao_semanal, 
            aes(x = dia_semana, 
                y = total_veiculos, 
                label = scales::comma(total_veiculos)),
            vjust = -0.8, size = 3, color = "darkblue") +
  
  geom_text(data = correlacao_semanal, 
            aes(x = dia_semana, 
                y = percentual_infracoes * max(total_veiculos) / max(percentual_infracoes), 
                label = paste0(format(percentual_infracoes, decimal.mark = ","), "%")),
            vjust = 1.8, size = 3, color = "darkred") +
  
  # Configurar eixos duplos
  scale_y_continuous(
    name = "Volume de Tráfego (veículos)",
    labels = scales::comma,
    sec.axis = sec_axis(~. * max(correlacao_semanal$percentual_infracoes) / max(correlacao_semanal$total_veiculos), 
                        name = "Percentual de Infrações (%)")
  ) +
  
  # Configurar cores
  scale_color_manual(values = c("Volume de Tráfego" = "darkblue", "% de Infrações" = "darkred")) +
  
  # Adicionar título e tema
  labs(title = "Relação entre Volume de Tráfego e Taxa de Infrações por Dia da Semana",
       subtitle = "Análise do comportamento dos motoristas em diferentes dias da semana",
       x = "Dia da Semana") +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", size = 14),
    plot.subtitle = element_text(size = 12),
    axis.title = element_text(face = "bold"),
    panel.grid.minor = element_blank(),
    legend.title = element_blank(),
    legend.position = "top"
  )

# NOVO GRÁFICO 2: Análise por hora do dia
# Preparar dados para análise por hora
correlacao_horaria <- dados_finais %>%
  filter(!is.na(hora)) %>%
  group_by(hora) %>%
  summarise(
    total_veiculos = sum(quantidade_veiculos, na.rm = TRUE),
    total_infracoes = sum(quantidade_veiculos * acima_limite, na.rm = TRUE),
    percentual_infracoes = round((total_infracoes / total_veiculos) * 100, 2),
    .groups = 'drop'
  )

# Criar anotações para horários de pico
anotacoes_hora <- data.frame(
  hora = c(8, 18),
  nota = c("Pico\nmatutino", "Pico\nnoturno"),
  y_pos = rep(max(correlacao_horaria$percentual_infracoes) * 0.9, 2)
)

# Gráfico comparativo entre volume de tráfego e taxa de infrações por hora
ggplot() +
  # Linha para o volume de veículos (eixo esquerdo)
  geom_line(data = correlacao_horaria, 
            aes(x = hora, y = total_veiculos, group = 1, color = "Volume de Tráfego"),
            size = 1.2) +
  geom_point(data = correlacao_horaria, 
             aes(x = hora, y = total_veiculos, color = "Volume de Tráfego"),
             size = 3) +
  
  # Linha para o percentual de infrações (eixo direito)
  geom_line(data = correlacao_horaria, 
            aes(x = hora, y = percentual_infracoes * max(total_veiculos) / max(percentual_infracoes), 
                group = 1, color = "% de Infrações"),
            size = 1.2) +
  geom_point(data = correlacao_horaria, 
             aes(x = hora, y = percentual_infracoes * max(total_veiculos) / max(percentual_infracoes), 
                 color = "% de Infrações"),
             size = 3) +
  
  # Adicionar rótulos de dados apenas para alguns pontos para não sobrecarregar o gráfico
  geom_text(data = correlacao_horaria %>% 
              filter(hora %in% c(0, 6, 8, 12, 15, 18, 21, 23)), 
            aes(x = hora, 
                y = total_veiculos, 
                label = scales::comma(total_veiculos)),
            vjust = -0.8, size = 3, color = "darkblue") +
  
  geom_text(data = correlacao_horaria %>% 
              filter(hora %in% c(0, 3, 6, 9, 12, 15, 18, 21, 23)), 
            aes(x = hora, 
                y = percentual_infracoes * max(total_veiculos) / max(percentual_infracoes), 
                label = paste0(format(percentual_infracoes, decimal.mark = ","), "%")),
            vjust = 1.8, size = 3, color = "darkred") +
  
  # Linhas verticais para destacar horários de pico
  geom_vline(xintercept = c(8, 18), linetype = "dashed", alpha = 0.5) +
  
  # Destacar anotações importantes
  geom_text(data = anotacoes_hora,
            aes(x = hora, 
                y = y_pos * max(correlacao_horaria$total_veiculos) / max(correlacao_horaria$percentual_infracoes), 
                label = nota),
            size = 3.5, fontface = "bold") +
  
  # Configurar eixos duplos
  scale_y_continuous(
    name = "Volume de Tráfego (veículos)",
    labels = scales::comma,
    sec.axis = sec_axis(~. * max(correlacao_horaria$percentual_infracoes) / max(correlacao_horaria$total_veiculos), 
                        name = "Percentual de Infrações (%)")
  ) +
  
  # Configurar eixo x com todas as horas
  scale_x_continuous(breaks = 0:23) +
  
  # Configurar cores
  scale_color_manual(values = c("Volume de Tráfego" = "darkblue", "% de Infrações" = "darkred")) +
  
  # Adicionar título e tema
  labs(title = "Relação entre Volume de Tráfego e Taxa de Infrações por Hora do Dia",
       subtitle = "Análise do comportamento dos motoristas em diferentes horários",
       x = "Hora do Dia") +
  theme_minimal() +
  theme(
    plot.title = element_text(face = "bold", size = 14),
    plot.subtitle = element_text(size = 12),
    axis.title = element_text(face = "bold"),
    panel.grid.minor = element_blank(),
    legend.title = element_blank(),
    legend.position = "top"
  )

3.4 Análise de Velocidade

# Distribuição das velocidades
dados_finais %>%
  group_by(faixa_velocidade) %>%
  summarise(total = sum(quantidade_veiculos, na.rm = TRUE)) %>%
  ggplot(aes(x = faixa_velocidade, y = total)) +
  geom_col(fill = "darkred") +
  geom_text(aes(label = scales::comma(total)), vjust = -0.5) +
  scale_y_continuous(labels = scales::comma) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  labs(title = "Distribuição de Velocidades",
       x = "Faixa de Velocidade (km/h)",
       y = "Total de Veículos")

# Análise de infrações
dados_finais %>%
  group_by(tipo_equipamento) %>%
  summarise(
    total_veiculos = sum(quantidade_veiculos, na.rm = TRUE),
    veiculos_acima = sum(quantidade_veiculos * acima_limite, na.rm = TRUE),
    percentual_acima = round(veiculos_acima / total_veiculos * 100, 2)
  ) %>%
  kable(
    format = "html",
    caption = "Percentual de Infrações por Tipo de Equipamento",
    format.args = list(big.mark = ".", decimal.mark = ",")
  ) %>%
  kable_styling(bootstrap_options = c("striped", "hover"))
Percentual de Infrações por Tipo de Equipamento
tipo_equipamento total_veiculos veiculos_acima percentual_acima
Fotossensores 78.313.456 907.731 1,16
lombadas 200.050.596 2.621.959 1,31

3.5 Infrações por Local

# Análise de infrações por local em formato de tabela
infracoes_local <- dados_finais %>%
  filter(!is.na(logradouro)) %>%
  group_by(logradouro) %>%
  summarise(
    total_veiculos = sum(quantidade_veiculos, na.rm = TRUE),
    total_infracoes = sum(quantidade_veiculos * acima_limite, na.rm = TRUE),
    velocidade_via = max(velocidade_via, na.rm = TRUE), 
    qtd_faixas = max(faixa, na.rm = TRUE),
    .groups = 'drop'
  ) %>%
  mutate(
    percentual_infracoes = round((total_infracoes / total_veiculos) * 100, 2)
  ) %>%
  arrange(desc(percentual_infracoes))

# Exibição em formato de tabela
kable(infracoes_local, 
      format = "html",
    col.names = c("Local", "Total de Veículos", "Total de Infrações", "Velocidade da Via (km/h)" ,"Qtd. Faixas", "Percentual de Infrações (%)"),
      caption = "Infrações por Local",
      format.args = list(big.mark = ".", decimal.mark = ",")) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), 
                full_width = TRUE) %>%
  row_spec(0, bold = TRUE) %>%
  column_spec(1, width = "30%") %>%
  column_spec(4, color = "white", 
              background = spec_color(infracoes_local$percentual_infracoes, 
                                     end = 0.7,
                                     option = "D",
                                     direction = 1))
Infrações por Local
Local Total de Veículos Total de Infrações Velocidade da Via (km/h) Qtd. Faixas Percentual de Infrações (%)
RUA ARQ. LUIZ NUNES CRUZAMENTO RUA DEOLINDO TAVARES, SENT. SUBURBIO 3.422.551 203.905 40 2 5,96
RUA MADRE DE DEUS, SEMAFORO 020. 2.012.098 95.223 30 3 4,73
AV. MARQUES DE OLINDA, SEMAFORO 020. 375.190 17.379 30 2 4,63
RUA GUILHERME PINTO, SEMAFORO 432. 1.240.836 51.894 40 2 4,18
AV. DOM JOAO VI, ENTRE OS N. 777 E 835 - SENT. CENTRO 5.150.262 167.120 50 2 3,24
AV. ENG. ABDIAS DE CARVALHO, ENTRE OS N. 1785 E 1745 - SENT. CENTRO 6.264.079 178.544 60 2 2,85
AV. MARECHAL MASCARENHAS DE MORAES, SEMAFORO 530/531. 2.644.262 69.514 60 4 2,63
RUA REAL DA TORRE, SEMAFORO 237. 1.341.253 33.678 50 3 2,51
AV. ALFREDO LISBOA, ENTRE OS N. 33 E 18 5.097.902 126.620 30 2 2,48
AV. CDE. DA BOA VISTA, SEMAFORO 486. 1.299.247 32.234 40 4 2,48
AV. DOM JOAO VI, EM FRT. AO PT. DE ONIBUS N. 010243, IMBIRIBEIRA 4.700.308 107.869 50 2 2,29
AV. ENG. ABDIAS DE CARVALHO, SEMAFORO 271. 2.392.082 50.682 60 3 2,12
AV. CELSO FURTADO KM 1,5 - SENT. CENTRO 7.439.160 144.998 60 2 1,95
AV. MAL. MASCARENHAS DE MORAES, EM FRENTE AEROPORTO - SENT. CENTRO 10.384.754 196.573 60 4 1,89
AV. BEBERIBE, 3101 - SENT. CENTRO 6.983.041 113.924 50 2 1,63
AV. REPUBLICA DO LIBANO, N. 115 - PINA - SENT. SUBURBIO 9.647.536 149.593 60 3 1,55
AV. ENG. ABDIAS DE CARVALHO, SEMAFORO 328. 3.012.398 46.524 60 4 1,54
RUA CONEGO BARATA, 55 - SENTIDO TORRE 3.371.746 50.396 50 2 1,49
AV. BOA VIAGEM, SEMAFORO 104. 2.977.494 43.871 60 4 1,47
AV. GOV. AGAMENON MAGALHAES – PROX. VIADUTO PRES. MEDICI - SENT. DERBY 8.706.159 120.406 60 4 1,38
AV. DR. JOSE RUFINO, SEMAFORO 082. 850.105 11.597 60 4 1,36
AV. GOV. AGAMENON MAGALHAES – EM FRENTE REITORIA UPE - SENT. OLINDA 12.500.080 160.447 60 2 1,28
AV. MAL. MASCARENHAS DE MORAES, EM FRENTE AEROPORTO - SENT. PRAZERES 12.798.869 157.293 60 4 1,23
AV. LIBERDADE, SEMAFORO 440 1.132.482 12.600 50 2 1,11
RUA FALCAO DE LACERDA SEMAFORO 285 3.016.398 32.561 50 2 1,08
AV. RECIFE, SEMAFORO 617. 3.039.101 31.198 60 3 1,03
AV. ENG. DOMINGOS FERREIRA, SEMAFORO 297. 4.169.440 42.051 60 4 1,01
AV. SATURNINO DE BRITO - PROX. A COMPESA, SENT. SUBURBIO 4.292.221 43.043 60 2 1,00
AV. RECIFE, SEMAFORO 336. 2.093.155 20.467 60 3 0,98
AV. BEBERIBE, 2960 - SENT. SUBÚRBIO 5.573.743 53.254 50 2 0,96
AV. DESEMBARGADOR JOSÉ NEVES, SEMAFORO 400 3.566.954 33.919 50 2 0,95
PONTE DELMIRO GOUVEIA, SEMAFORO 075. 254.715 2.349 50 2 0,92
RUA VISCONDE DE JEQUITINHONHA,SEMAFORO 158 6.331.409 57.916 60 4 0,91
AV. BOA VIAGEM - TERCEIRO JARDIM 6.402.919 56.845 60 3 0,89
CAIS SANTA RITA, PROX.  AO N. 675 - SENT. CENTRO 7.922.201 70.436 60 2 0,89
AV. CONS. AGUIAR, N. 4620 2.266.284 19.366 60 2 0,85
AV. CELSO FURTADO KM 2,4 - SENT. SUBURBIO 7.039.102 59.028 60 2 0,84
AV. GENERAL SAN MARTIN, N. 1864, SENT. AV. RECIFE 6.164.783 49.965 40 2 0,81
AV. ENG. DOMINGOS FERREIRA, SEMAFORO 338. 2.271.213 18.053 60 4 0,79
AV. BOA VIAGEM – EM FRENTE PARQUE DONA LINDU 8.882.796 68.121 60 2 0,77
AV. ENG. JOSÉ ESTELITA - ENTRE PTS. DE ILUM. 19-R e 21-R, SENT. CENTRO 4.280.428 32.329 60 2 0,76
AV. AFONSO OLINDENSE, N. 996, SENT. CAXANGA 4.013.849 29.345 40 2 0,73
AV. ENG. ANTONIO DE GOES, N. 124 5.203.000 38.051 60 2 0,73
AV. DESEMBARGADOR JOSÉ NEVES, SEMAFORO 580 2.887.116 20.539 50 2 0,71
AV. GOV. AGAMENON MAGALHAES, SEMAFORO 173. 4.220.419 29.338 60 4 0,70
AV. ENG. ABDIAS DE CARVALHO, SEMAFORO 272. 2.229.180 15.425 60 3 0,69
APOS PONTE AGAMENON MAGALHAES, CABANGA - SENT. DERBY 11.113.061 74.764 60 2 0,67
AV. GOV. AGAMENON MAGALHAES, SEMAFORO 069. 2.919.624 19.208 60 4 0,66
AV. HERCULANO BANDEIRA, SEMAFORO 137. 9.138.414 58.924 60 4 0,64
AV. CELSO FURTADO KM 2,5 - SENT. CENTRO 5.791.112 36.683 60 2 0,63
AV.NORTE MIGUEL ARRAES DE ALENCAR, SEMAFORO 424 3.753.486 21.371 60 2 0,57
AV. GOV. AGAMENON MAGALHAES, SEMAFORO 069 4.061.483 22.877 60 4 0,56
AV. RUI BARBOSA, N. 1397 5.848.450 31.080 60 2 0,53
DEFRONTE A PCA. GOV. PAULO GUERRA, CABANGA - SENT. PINA 8.423.660 43.851 60 2 0,52
AV. DEZESSETE DE AGOSTO, SEMAFORO 370. 2.497.391 10.625 60 4 0,43
RUA PARIS, PRÓXIMO A PARADA DE ÔNIBUS N.020470 4.404.278 18.466 50 2 0,42
AV. MAURICIO DE NASSAU ENTRONCAMENTO 1a. TRV. SANTA LÚCIA, SENT. CENTRO 5.794.386 19.644 40 2 0,34
RUA PROF. ARNALDO CARNEIRO LEAO, SEMAFORO 544. 1.468.387 3.660 60 3 0,25
AV. BEBERIBE, SEMAFORO 131. 1.118.124 2.054 60 2 0,18

4. Conclusão

4.1 Principais Descobertas

A análise exploratória dos dados de fiscalização eletrônica em Recife revelou padrões significativos no comportamento dos motoristas e na eficácia dos sistemas de monitoramento:

  1. Correlação Inversa entre Volume de Tráfego e Infrações: Um dos achados mais relevantes deste estudo é a clara relação inversa entre o volume de veículos e o percentual de infrações. Em múltiplos contextos temporais, observamos que quando o fluxo de veículos diminui, o percentual de infrações aumenta significativamente:

    • Durante a madrugada (1h-5h), quando o volume de tráfego é mínimo, o percentual de infrações alcança picos superiores a 10-15%.
    • No período de lockdown devido à pandemia, enquanto o volume de tráfego caiu drasticamente (de 40 milhões para aproximadamente 10 milhões de veículos), a taxa de infrações mais que dobrou (de cerca de 1% para 2,2%).
    • Aos domingos, com tráfego reduzido a 26 milhões de veículos (comparado a 40-45 milhões em dias úteis), o percentual de infrações atingiu 2%, o mais alto da semana.

    Este padrão sugere que a percepção de vias livres pode induzir comportamentos de maior risco, com motoristas aproveitando a ausência de congestionamentos para exceder os limites de velocidade.

  2. Padrões Temporais Distintos: Os dados demonstram uma clara variação no volume de tráfego e nas infrações ao longo do dia, semana e ano. As primeiras horas da manhã apresentam os maiores percentuais de infrações, apesar do baixo volume de veículos. Durante o período diurno, o volume de tráfego aumenta significativamente enquanto o percentual de infrações cai para menos de 1%.

  3. Impacto da Pandemia como Experimento Natural: O gráfico de tendência mensal evidencia uma queda acentuada no volume de tráfego a partir de março, coincidindo com o “Início das restrições” devido à pandemia. Esta situação funcionou como um experimento natural que corroborou a hipótese da correlação inversa entre volume e infrações - quando as vias esvaziaram, o comportamento de risco aumentou proporcionalmente.

  4. Padrão Semanal: Os dias úteis (segunda a sexta) apresentam volumes de tráfego similares, com queda significativa nos finais de semana, especialmente aos domingos. O percentual de infrações, entretanto, é mais alto aos domingos, reforçando o padrão identificado.

  5. Distribuição de Velocidades: A maior concentração de veículos trafega na faixa de velocidade de 40-50 km/h, seguida pela faixa de 30-40 km/h. Isso sugere que a maioria dos motoristas respeita os limites estabelecidos nas vias urbanas de Recife.

  6. Eficácia dos Equipamentos: Os fotossensores detectaram infrações em 1,16% dos veículos monitorados, enquanto as lombadas eletrônicas registraram 1,31%. Esta diferença pode indicar variações na eficácia ou nas características das vias.

  7. Pontos Críticos: Identificamos locais com percentuais de infração significativamente acima da média, como a Rua Madre de Deus (4,73%) e a Av. Marquês de Olinda (4,63%), ambas com limite de 30 km/h.

4.2 Implicações para Políticas Públicas

Nossos resultados sugerem diversas abordagens que poderiam aumentar a eficácia das políticas de segurança viária em Recife:

Fiscalização adaptativa baseada no volume: Implementar estratégias de fiscalização que considerem as condições de fluxo de veículos, intensificando a presença em períodos de baixo volume (madrugadas, domingos e situações excepcionais como lockdowns), quando o comportamento de risco aumenta significativamente.

Intervenções específicas: Implementar medidas de moderação de tráfego nos pontos críticos identificados, como a Rua Madre de Deus e Av. Marquês de Olinda, que podem incluir desde campanhas educativas até intervenções físicas no desenho urbano.

Medidas automáticas para períodos de baixo fluxo: Considerar a implementação de redutores de velocidade físicos ou temporários e radares adaptativos que possam ser intensificados em períodos de menor fluxo.

Campanhas educativas direcionadas: Desenvolver mensagens específicas sobre os riscos associados ao excesso de velocidade em vias menos congestionadas, focando nos horários e locais de maior incidência de infrações.

Avaliação de equipamentos: Realizar estudos complementares sobre a eficácia comparativa entre fotossensores e lombadas eletrônicas, considerando as características específicas das vias onde estão instalados.

4.3 Contribuições e Valor do Estudo

Este estudo contribui para o campo da segurança viária de várias formas:

Abordagem baseada em evidências: Nossa análise fornece evidências quantitativas sobre padrões reais de velocidade e comportamento no trânsito, superando percepções anedóticas.

Identificação da correlação inversa tráfego-infração: A clara demonstração de que períodos e locais com menor volume de tráfego apresentam maiores índices de infração oferece um insight valioso para a elaboração de políticas públicas mais eficazes.

Granularidade temporal: A análise por períodos do dia, dias da semana e meses do ano permite identificar padrões cíclicos que podem orientar políticas temporalmente dirigidas.

Impacto da pandemia como experimento natural: As restrições de mobilidade durante a pandemia proporcionaram um cenário único para observar como a redução significativa do volume de tráfego afeta o comportamento dos motoristas.

Identificação de hot spots: O mapeamento de pontos críticos possibilita a priorização de intervenções onde o impacto pode ser maximizado.

Para os gestores da mobilidade urbana do Recife, estes insights fornecem um valioso subsídio para a tomada de decisões baseadas em dados, potencialmente contribuindo para a redução de acidentes e a preservação de vidas.

4.4 Limitações do Estudo

É importante reconhecer algumas limitações que contextualizem adequadamente nossos resultados:

Período atípico: Os dados de 2020 foram significativamente influenciados pela pandemia de COVID-19, com mudanças drásticas nos padrões de mobilidade urbana a partir de março.

Ausência de dados contextuais: Não tivemos acesso a dados sobre acidentes e fatalidades, o que limitou nossa capacidade de correlacionar infrações com desfechos de segurança.

Variáveis socioeconômicas: Não foram consideradas variáveis socioeconômicas que possam influenciar os padrões de tráfego e comportamento dos motoristas em diferentes regiões da cidade.

Fatores psicológicos: A análise quantitativa não captura os fatores psicológicos que levam motoristas a aumentar a velocidade quando as vias estão mais livres.

4.5 Direções para Pesquisas Futuras

Baseado em nossas descobertas e limitações, sugerimos algumas direções promissoras para pesquisas futuras:

Análise espacial detalhada: Utilizar técnicas de georreferenciamento para identificar clusters de infrações e correlacioná-los com características específicas das vias.

Correlação com acidentes: Integrar dados de acidentes de trânsito para quantificar a relação entre infrações de velocidade e desfechos de segurança viária.

Experimentos controlados: Testar intervenções específicas em períodos de baixo fluxo para avaliar sua eficácia na redução de infrações.

Modelos preditivos: Desenvolver modelos que incorporem a variável de volume de tráfego para antecipar comportamentos de risco em diferentes cenários.

Estudos comparativos: Realizar comparações com outras capitais brasileiras para identificar se o padrão de correlação inversa entre volume e infrações é consistente em diferentes contextos urbanos.

Análise de custo-benefício: Avaliar diferentes estratégias de fiscalização adaptadas aos padrões de volume de tráfego para determinar a abordagem mais eficiente.

A continuidade deste tipo de análise, especialmente com a integração de outras fontes de dados e perspectivas disciplinares, tem o potencial de contribuir significativamente para a construção de um sistema de mobilidade mais seguro e eficiente para o Recife.