CE302: Acidentes de Trem nos EUA
Este trabalho explora o banco de dados Railroad Accident & Incident Data, que documenta acidentes ferroviários ocorridos nos Estados Unidos entre 1975 e 2022, com o objetivo de identificar padrões e facilitar a análise de informações relevantes. Foi realizado o pré-processamento dos dados, incluindo o tratamento de valores ausentes e a exclusão de variáveis irrelevantes, seguido por uma análise descritiva para gerar insights. Entre os resultados, destacam-se tendências temporais de redução de acidentes, predominância de descarrilamentos e melhorias na segurança no transporte de cargas perigosas. Para disseminar as descobertas de forma interativa, foi desenvolvida uma aplicação Shiny que permite ao usuário explorar os dados por meio de filtros, gráficos e mapas. A aplicação está estruturada em abas que refinam progressivamente a análise, abordando o total de acidentes, estados específicos, períodos, tipos de acidentes e o envolvimento de cargas perigosas. Esta abordagem busca oferecer uma visão abrangente e interativa dos acidentes ferroviários, auxiliando na identificação de padrões e áreas críticas de melhoria.
Acidentes Ferroviários, Estados Unidos, ShinyApp, Railroad Accident & Incident Data, Banco de Dados, Pré-processamento, Valores Ausentes, Filtragem, Mapas Interativos, Gráficos Interativos, ggplot2, Leaflet, Plotly, Carga Perigosa, Descarrilamento, Colisão, Condições Climáticas, Tendências Temporais, Visualização de Dados, Texas, Illinois, Segurança no Transporte, Evolução Tecnológica, Interface Interativa, Dados Espaciais
Introdução
Ao nos depararmos com um acidente ferroviario, pergunta-se o local, a data, motivo, mortes e entre várias outras condições envolvidas. Porém tentar achar possiveis correlações e dados relevantes vendo caso a caso é uma tarefa trabalhosa e cansativa. Principalmente quando se quer analizar o banco de dados Railroad Accident & Incident Data, que tem os acidentes ferroviarios ocorridos nos Estados Unidos da América, de 1975 até 2022.
Por isso foi realizado trabalho de exploratória dos dados, identificandos NA’s, removendo colunas não utilizadas e uma anaálise descritiva dos dados para poder obter informações que os dados possuem, e transformar isso em um Shinyapp para facilitar as interpretações dos dados ao usuário final.
Materiais e ferramentas
Fonte dos Dados:
A fonte de dados utilizada foi Railroad Accident & Incident Data (Chrico03, 2024), proveniente do site https://www.kaggle.com/, no qual os dados estão disponibilizados em um arquivo CSV com dimensões 215849 linhas e 160 colunas.
Os dados do mapa do EUA foram obtidos do site https://catalog.data.gov/ (U.S. Government, 2023).
As principais informações dos dados incluem o local do acidente, condições climáticas, tipo da bitola do trilho utilizada, se a carga é perigosa ou não, e com isso podemos destacar as principais colunas como:
Accident Type: Tipo de acidente, coluna do tipo caracter.
Weather Condition: Condições climáticas, coluna do tipo caracter.
State Name: Nome do estado, coluna do tipo caracter.
Total Persons Killed: Total de pessoas mortas, coluna do tipo inteiro.
Total Persons Injured: Total de pessoas feridas, coluna do tipo inteiro.
Hazmat Cars: Carros de carga perigosa, coluna do tipo inteiro.
Hazmat Cars Damaged: Carros de carga danificados, coluna do tipo inteiro.
Report Year: Ano do acidente, coluna do tipo inteiro.
Accident Month: Mês do acidente, coluna do tipo inteiro.
Firemen On Duty: Bombeiros de plantão, coluna do tipo inteiro.
Bibliotecas
As bibliotecas usadas para a produção do codigo foram:
Apresentação e elementos web : shiny, shinybusy, bslib, gridlayout, bsicons;
Gráficos estáticos e interativos: ggplot2, DT, plotly, leaflet, sf, ggcorrplot, corrplot;
No processamento dos dados: tidyverse, dbplyr, tidyr, data.table
Tratamento dos dados
Pré-processamento
Nessa etapa foi realizado o carregamento dos dados, tratamento de valores ausentes, limitação de valores ausentes, filtragem e exclusão de variáveis desnecessárias, e carregamento de dados limpos.
Carregamento de dados:
O código começa carregando um arquivo CSV comprimido (Rail_Equipment_Accident_Incident_Data.csv.gz) que contém dados sobre acidentes ferroviários. O arquivo é lido usando o fread do pacote data.table, o que proporciona maior rapidez no carregamento dos dados. Os valores faltantes são identificados com strings como “NA”, “N/A”, ““,”None” e “Na”, e são tratados de forma apropriada durante o pré-processamento.
Tratamento de valores ausentes (NAs):
O código trabalha para substituir os valores ausentes (NAs) nas colunas numéricas. Primeiramente, as colunas numéricas do data frame são identificadas. Em seguida, a função lapply é utilizada para substituir os NAs por 0 nas colunas numéricas.
Limitação de valores ausentes:
O código calcula a porcentagem de valores ausentes em cada coluna e aplica um limite (5% de valores ausentes). Apenas as colunas que possuem valores ausentes abaixo desse limite são mantidas, removendo assim aquelas com maior quantidade de dados ausentes.
Código
# Define o limite máximo permitido de valores ausentes (em %)
limite_na <- 5
# Calcula a porcentagem de valores ausentes por coluna
percent_missing <- colSums(is.na(dados)) / nrow(dados) * 100
# Seleciona apenas as colunas com valores ausentes abaixo do limite
colunas_validas <- names(percent_missing[percent_missing <= limite_na])
# Filtra o dataframe para manter apenas as colunas válidas
dados_filtrados <- dados[, ..colunas_validas]Filtragem e exclusão de variáveis desnecessárias:
Após a remoção das colunas com NAs excessivos, o código filtra o data frame para manter apenas as colunas válidas (com menos de 5% de valores ausentes). Além disso, realiza a remoção de variáveis temporárias (como dados e dados_filtrados) para liberar memória, seguido por uma chamada para gc() (garbage collection).
Carregamento de dados limpos:
Após o processo de filtragem e remoção de NAs, os dados são salvos no formato .RData com compressão gzip para otimizar o armazenamento.
Considerações gerais:
O pré-processamento foca na limpeza e preparação dos dados para uma análise mais eficiente, removendo dados ausentes em excesso e ajustando valores faltantes. A criação do arquivo dados.RData comprimido é uma estratégia para otimizar o uso de memória e garantir que o conjunto de dados limpo esteja disponível para processamento futuro.
Análise dos Dados
Exploração Inicial
A análise exploratória dos dados é realizada para entender a distribuição e características dos acidentes ferroviários nos Estados Unidos. A exploração inclui a contagem de acidentes por estado, a distribuição de acidentes por tipo, a evolução temporal dos acidentes e a análise de cargas perigosas. A visualização dos dados é feita por meio de gráficos interativos e tabelas, permitindo uma análise detalhada dos acidentes ferroviários.
Contagem de acidentes por estado
O código calcula a contagem de acidentes por estado e exibe um gráfico de barras com os cinco estados com maior número de acidentes. O gráfico destaca os estados Texas, Illinois, California, Pennsylvania e Ohio como os mais afetados por acidentes ferroviários.
Código
# Contagem de acidentes por estado
acidentes_por_estado <- dados %>%
select(`State Name`) %>%
group_by(`State Name`) %>%
summarise(Total_Acidentes = n()) %>%
arrange(desc(Total_Acidentes)) %>%
slice(1:5)
# Gráfico de barras com os cinco estados com mais acidentes
acidentes_por_estado %>%
ggplot()+
aes(x = reorder(`State Name`, Total_Acidentes), y = Total_Acidentes)+
geom_bar(stat = "identity")+
scale_y_continuous()+
scale_x_discrete() +
labs(x = 'Os 5 estados com mais acidentes entre 1975 e 2022',
y = 'Acidentes totais por estado')+
theme_classic()Distribuição de acidentes por tipo
O código calcula a distribuição de acidentes por tipo e exibe um gráfico de barras empilhadas com a proporção de cada tipo de acidente. O gráfico destaca o descarrilamento como o tipo mais comum de acidente ferroviário, seguido por colisões e outros tipos de acidentes.
Código
# Distribuição de acidentes por tipo
acidentes_por_tipo <- dados %>%
select(`Accident Type`) %>%
group_by(`Accident Type`) %>%
summarise(Total_Acidentes = n()) %>%
arrange(desc(Total_Acidentes))
# Gráfico de barras empilhadas com a distribuição de acidentes por tipo
acidentes_por_tipo %>%
ggplot()+
aes(x = reorder(`Accident Type`, Total_Acidentes), y = Total_Acidentes, fill = `Accident Type`)+
geom_bar(stat = "identity")+
scale_y_continuous()+
scale_x_discrete() +
labs(x = 'Tipo de acidente',
y = 'Total de acidentes')+
theme_classic()Evolução temporal dos acidentes
O código calcula a evolução temporal dos acidentes ferroviários ao longo dos anos e exibe um gráfico de linha com a quantidade de acidentes por ano. O gráfico destaca a redução significativa de acidentes ao longo do tempo, refletindo melhorias na segurança ferroviária.
Código
# Evolução temporal dos acidentes
evolucao_acidentes <- dados %>%
select(`Report Year`) %>%
group_by(`Report Year`) %>%
summarise(Total_Acidentes = n()) %>%
arrange(`Report Year`)
# Gráfico de linha com a evolução temporal dos acidentes
evolucao_acidentes %>%
ggplot()+
aes(x = `Report Year`, y = Total_Acidentes)+
geom_line()+
scale_y_continuous()+
scale_x_continuous() +
labs(x = 'Ano',
y = 'Total de acidentes')+
theme_classic()Análise de cargas perigosas
O código calcula a proporção de acidentes envolvendo cargas perigosas e exibe um gráfico de pizza com a distribuição de acidentes com e sem cargas perigosas. O gráfico destaca a diminuição de acidentes envolvendo cargas perigosas, refletindo avanços tecnológicos e medidas de segurança no transporte ferroviário.
Código
# Análise de cargas perigosas
cargas_perigosas <- dados %>%
mutate(`Hazmat Cars` = ifelse(`Hazmat Cars` > 0, "Com Carga Perigosa", "Sem Carga Perigosa")) %>%
group_by(`Hazmat Cars`) %>%
summarise(Total_Acidentes = n())
# Gráfico de pizza com a proporção de acidentes com e sem cargas perigosas
cargas_perigosas %>%
mutate(Percentual = Total_Acidentes / sum(Total_Acidentes) * 100) %>%
ggplot()+
aes(x = "", y = Total_Acidentes, fill = `Hazmat Cars`)+
geom_bar(stat = "identity", width = 1)+
coord_polar("y")+
labs(fill = "Carga Perigosa")+
geom_text(aes(label = paste0(round(Percentual, 1), "%")),
position = position_stack(vjust = 0.5))
theme_void()Considerações finais
A análise exploratória dos dados fornece insights valiosos sobre os acidentes ferroviários nos Estados Unidos, destacando tendências temporais, tipos de acidentes mais comuns e a presença de cargas perigosas. A redução significativa de acidentes ao longo dos anos reflete avanços na segurança ferroviária, enquanto a predominância de descarrilamentos como tipo de acidente sugere áreas de melhoria. A análise de cargas perigosas mostra uma diminuição nos acidentes envolvendo esse tipo de carga, indicando melhorias na gestão de riscos e segurança no transporte ferroviário.
Desenvolvimento da Aplicação Shiny
A aplicação Shiny foi desenvolvida para permitir a exploração interativa dos dados de acidentes ferroviários nos Estados Unidos. A interface oferece filtros por estado, ano e condições climáticas, além de gráficos interativos e mapas geográficos para visualização dos dados. A aplicação é dividida em 5 abas principais: “Total”, “Estado”, “Por Ano”, “Tipo de Acidente” e “Carga Perigosa”.
Metodologia
Ao nos depararmos com diversas variáveis e as diversas observações que elas podem assumir, torna-se difícil modelá-las ao mesmo tempo. Por isso, surgiu a ideia de um funilamento dos dados, em que cada aba refina um pouco mais a busca pela informação. A principal ideia foi:
Total - Aqui, o usuário verificaria, ao longo do tempo, onde se concentram as maiores ocorrências de acidentes por estado e ao longo dos anos, podendo incluir a quantidade de mortos. É possível trocar o mapa por uma tabela que inclui a quantidade de acidentes, mortos e feridos, sendo estes últimos em menor número.
Estado - Nesta aba, temos um filtro mais específico. O usuário, ao saber em que época e lugar há mais ocorrências de acidentes, teoricamente buscaria por tais locais, como o Texas ou Illinois. Assim, receberia a informação sobre qual é a rota com maior contagem de acidentes e em quais meses eles mais ocorrem. Ao que tudo indica, as estações mais predominantes em cada estado são as que concentram o maior número de acidentes. Por exemplo, o Texas, por ser mais quente e estar próximo à linha do Equador, quase nunca registra neve e apresenta calor durante todo o ano. Logo, não faria sentido haver muitos registros de acidentes em condições de neve nesse estado.
Por Ano - Aqui, verifica-se simultaneamente o clima predominante nos acidentes, selecionando uma variável diferente das demais: a quantidade de feridos (que é baixa) e o tipo de acidente. No caso, o descarrilamento lidera, com muitas ocorrências em climas de chuva.
Tipo de Acidente - Constata-se que, nos estados com maior número de acidentes, assim como na maioria dos casos de forma geral, o descarrilamento é o principal tipo de acidente, independentemente do clima ou do ano. Ao filtrar pelos casos de chuva de granizo no Texas, nota-se que, basicamente, todos os acidentes que envolveram granizo foram do tipo descarrilamento, exceto no período de 2001 a 2010, em que outros tipos de acidentes também ocorreram. Ainda assim, o descarrilamento foi o principal tipo. Os demais tipos de acidentes apresentaram uma redução nas taxas ao longo dos anos, com exceção do descarrilamento.
Carga Perigosa - Observa-se que as cargas danificadas sempre superaram as não danificadas nos casos de descarrilamento. Estados com mais ocorrências de acidentes naturalmente registraram mais casos nesta categoria.
Essas abas filtram uma parte de uma informação total, representada pelo banco de dados. Podemos vê-las como um jogo de perguntas e respostas entre o usuário e o banco de dados.
Interface do usuário
O código define a interface (UI) para uma aplicação Shiny interativa, com foco na visualização de dados sobre acidentes ferroviários nos Estados Unidos. A UI é estruturada para fornecer diferentes tipos de visualização e facilitar a interação com o usuário. Abaixo está o resumo das principais seções da UI:
Pacotes e Bibliotecas:
São carregados pacotes essenciais como shiny, shinybusy (para adicionar um indicador de carregamento), bslib (para temas Bootstrap), ggplot2, DT, plotly, leaflet, e sf, que são utilizados para manipulação de dados e gráficos interativos. O pacote gridlayout é utilizado para organizar a interface em abas e seções.
Layout:
O layout é criado usando o grid_container e grid_card do pacote gridlayout, que organiza as seções da interface. Cada aba (como Total, Estado, Ano, etc.) é dividida em áreas configuráveis e interativas, como áreas para gráficos e controles de configuração. Dentro de cada aba, a configuração da interface é feita de forma modular, permitindo aos usuários ajustar visualizações com entradas como selectInput, radioButtons, sliderInput e checkboxInput.
Interatividade e Controles de Entrada:
Abas de Configuração: Cada aba tem uma seção de configurações à esquerda onde o usuário pode selecionar variáveis como:
- Tipo de visualização (por exemplo, mapa ou tabela).
- Ano de interesse (com slider ou seleção de intervalos).
- Tipo de acidente, condição climática, e outras variáveis específicas.
Gráficos e Tabelas: Dependendo das configurações escolhidas, a interface exibe gráficos e tabelas interativas que respondem aos filtros definidos pelo usuário. Para exibir os gráficos, são utilizados pacotes como plotly, ggplot2 e leaflet.
Indicador de Carregamento:
Um spinner de carregamento é adicionado usando o shinybusy::add_busy_bar, que ajuda a indicar ao usuário que os dados estão sendo processados ou carregados.
Funções de Visualização:
Gráficos:Vários gráficos são preparados para exibição, como gráficos de dispersão, gráficos de densidade, e gráficos de distribuição, com opções para diferentes tipos de dados, como volume de feridos, mortos, ou densidade de acidentes ao longo do tempo. Mapas:Embora o código faça referência a um “Mapa Estático”, ele parece preparar a infraestrutura para potencialmente integrar visualizações geoespaciais, como um mapa interativo (referência ao pacote leaflet).
Considerações gerais:
A interface é projetada para ser intuitiva e modular, permitindo que o usuário explore os dados interativamente. Com uma organização clara em abas e várias opções de filtro, a aplicação oferece uma maneira eficiente de analisar os acidentes ferroviários nos EUA. O uso de gráficos interativos, tabelas e mapas (embora o mapa interativo esteja comentado) enriquece a experiência do usuário, permitindo a análise em diversos níveis e granularidades.
Server
Carregamento e pré-processamento de dados
O código carrega um arquivo de dados de acidentes ferroviários (dados.RData), excluindo registros de um tipo específico de acidente, denominado “Other”. Define-se uma lista de estados continentais dos EUA que serão utilizados em filtros para seleção dos dados no mapa. Um shapefile dos estados é carregado e transformado em um objeto espacial (sf), o qual será utilizado para exibir um mapa dos Estados Unidos.
Realiza-se uma filtragem inicial para selecionar os tipos de acidentes e as condições climáticas distintas presentes no conjunto de dados, preparando essas variáveis para serem usadas nas opções de seleção do usuário. Interface e funcionalidades do servidor
A função do servidor (server) começa configurando as opções dinâmicas da interface, através da função updateSelectInput. Isso permite que o usuário selecione diversas variáveis, como o tipo de acidente, a condição climática e o estado dos EUA para análise. Para cada aba do aplicativo (Ano, Tipo de Acidente, Tipo de Carga, etc.), as opções de seleção são atualizadas com base nos dados disponíveis.
Filtragem dos dados
Diversas variáveis de entrada são monitoradas através de reactive e debounce para garantir que as atualizações da interface ocorram de maneira eficiente, minimizando a sobrecarga de processamento. Isso inclui o monitoramento das seleções de ano, estado e outros filtros do usuário. A função debounce é aplicada para garantir que as mudanças de entrada sejam registradas apenas após um pequeno intervalo, o que ajuda a otimizar a performance da aplicação.
Renderização de gráficos e mapas
Mapa Estático (ggplot): Um gráfico de mapa é gerado para exibir a distribuição de acidentes por estado. O mapa é enriquecido com informações sobre a quantidade de acidentes, mortos e feridos, que são representados em rótulos sobre cada estado. O código permite que o usuário escolha visualizar diferentes métricas (acidentes, mortos ou feridos) através de filtros de entrada.
Tabela Interativa: A tabela interativa (DT) exibe os dados filtrados de acidentes, incluindo o número total de acidentes, mortos e feridos por estado. O formato da tabela é configurado para permitir paginação e autoajuste das colunas.
Considerações sobre a estrutura
O código segue uma abordagem modular, onde funções reativas permitem a atualização dinâmica dos dados conforme o usuário interage com a interface. As variáveis de entrada e as funções reativas são bem definidas, garantindo que o processamento seja eficiente e que os resultados exibidos no mapa e na tabela sejam consistentes com as escolhas do usuário. Além disso, a utilização de pacotes como sf, leaflet e ggplot2 permite uma visualização rica e interativa dos dados espaciais, facilitando a análise dos acidentes ferroviários nos EUA.
Esse processamento e estruturação eficiente dos dados visam proporcionar ao analista uma interface interativa e intuitiva para explorar os dados, filtrando e visualizando os acidentes ferroviários de maneira detalhada, seja por estado, ano ou tipo de acidente.
Considerações finais
A aplicação Shiny proporciona uma ferramenta eficaz para explorar tendências e identificar padrões em acidentes ferroviários nos Estados Unidos. A interface interativa permite ao usuário visualizar os dados de forma dinâmica, facilitando a análise e interpretação dos dados. A combinação de gráficos interativos, filtros e mapas geográficos oferece uma experiência rica e informativa, destacando a segurança crescente no transporte ferroviário e os avanços tecnológicos no setor.