Ocorrências Aeronáuticas na Aviação Civil Brasileira - Códigos - Thiago Marques
Instalando e carregando as bibliotecas
Importando os banco de dados
- Já facilitaremos transformando em fatores as variáveis strings e também limpando/tratando os diferentes tipos de representação de informações faltantes (NA) que foram utilizados no banco.
#Carregando o arquivo em formato CSV
= read.csv("aeronave.csv",h=T,encoding = "UTF-8",na.strings = c("", "***", "****", "NULL"),stringsAsFactors = T) aeronave
#Carregando o arquivo em formato CSV
= read.csv("ocorrencia.csv",h=T,encoding = "UTF-8",na.strings = c("", "***", "****", "NULL"),stringsAsFactors = T) ocorrencia
Unindo as tabelas (Fazendo o Join)
- Unindo a tabela aeronaves a tabela ocorrências para identificar as ocorrências de cada aeronave, por meio da chave primária “codigo_ocorrencia” que liga ambas unicamente.
= merge(x = ocorrencia, y = aeronave, by = "codigo_ocorrencia", all = T) uniao_join
- Fazendo a mesma coisa usando o tidyverse
= full_join(ocorrencia,aeronave, by="codigo_ocorrencia") uniao_join_tidyverse
Agora com todas as informações em mãos sobre as aeronaves e respectivas ocorrências, podemos partir para a fase do data quality
Vamos excluir a tabela uniao_join_tidyverse para evitar redundâncias e otimizar o espaço na memória.
Excluindo a tabela uniao_join_tidyverse
remove(uniao_join_tidyverse)
Data Quality
Verificando as variáveis faltantes de forma visual
- Por meio desse gráfico, adotamos que o corte de menores que 50% de
faltantes seriam as melhores variáveis a se trabalhar, então não vale à
pena trabalharmos com as seguintes variáveis:
Observalções Faltantes:
- relatorio_publicado (51%) ;
- dia_publicacao (51%) ;
- origem_voo (54,3%) ;
- destino_voo (58,9%) ;
- aerodromo (60,2%) ;
- saida_pista (87,5%) ;
- quantidade_fatalidades (82,6%) ;
Vamos filtrar o banco então sem essas variáveis:
= uniao_join %>% select(-c("relatorio_publicado",
uniao_join_filtrado "dia_publicacao",
"origem_voo",
"destino_voo",
"aerodromo",
"saida_pista",
"quantidade_fatalidades"
) )
Verificando se foi aplicado corretamente o filtro
dim(uniao_join_filtrado)[2]
## [1] 33
- Agora ficamos com 33 variáveis, em vez de 40 para analisarmos
Transformando variáveis
- Nessa etapa vamos analisar se é necessário transformar strings em fatores, informações de data que possam ter sido interpretadas como string e assim vai..
class(uniao_join_filtrado$dia_ocorrencia)
## [1] "factor"
- Conforme vimos a variável dia_ocorrencia está como fator e não como data, logo iremos transformá-la usando o pacote lubridate, melhor pacote do R para se trabalhar com datas.
$dia_ocorrencia_data = as_date(uniao_join_filtrado$dia_ocorrencia) uniao_join_filtrado
- Verificando se funcionou
class(uniao_join_filtrado$dia_ocorrencia_data)
## [1] "Date"
Fazendo um resumo geral das 33 variáveis que restaram
summary(uniao_join_filtrado)
## codigo_ocorrencia classificacao tipo
## Min. :25799 ACIDENTE :1484 FALHA DO MOTOR EM VOO :377
## 1st Qu.:38840 INCIDENTE GRAVE: 559 PERDA DE CONTROLE NO SOLO :325
## Median :45564 PERDA DE CONTROLE EM VOO :311
## Mean :43962 COLISÃO EM VOO COM OBSTÁCULO:142
## 3rd Qu.:50354 COM TREM DE POUSO :130
## Max. :65312 OUTROS TIPOS : 87
## (Other) :671
## localidade uf pais dia_ocorrencia
## RIO DE JANEIRO: 65 SP :442 ARGENTINA : 1 2012-09-24: 6
## SÃO PAULO : 50 RS :170 BRASIL :2035 2009-08-26: 5
## GOIÂNIA : 42 MT :154 COLÔMBIA : 1 2013-02-16: 5
## BRASÍLIA : 31 PR :154 INGLATERRA: 1 2010-09-15: 4
## MANAUS : 29 MG :152 PARAGUAI : 2 2011-02-05: 4
## BELO HORIZONTE: 26 (Other):969 PERU : 1 2011-09-17: 4
## (Other) :1800 NA's : 2 URUGUAI : 2 (Other) :2015
## horario sera_investigada comando_investigador status_investigacao
## 20:30:00: 55 NÃO : 4 SERIPA-4:486 ATIVA : 768
## 20:00:00: 53 SIM :1833 SERIPA-5:372 FINALIZADA:1065
## 17:00:00: 45 NA's: 206 SERIPA-6:350 REABERTA : 1
## 13:00:00: 42 SERIPA-3:267 NA's : 209
## 18:00:00: 42 SERIPA-2:182
## 12:00:00: 41 SERIPA-1:166
## (Other) :1765 (Other) :220
## numero_relatorio quantidade_recomendacoes aeronaves_envolvidas
## A DEFINIR : 436 Min. : 0.000 Min. :1.000
## ENCERRADA NO RAI : 55 1st Qu.: 0.000 1st Qu.:1.000
## IG-041/CENIPA/2014: 4 Median : 0.000 Median :1.000
## A-026/CENIPA/2013 : 3 Mean : 1.169 Mean :1.019
## A-035/CENIPA/2013 : 3 3rd Qu.: 1.000 3rd Qu.:1.000
## (Other) :1333 Max. :83.000 Max. :4.000
## NA's : 209
## dia_extracao.x codigo_aeronave matricula codigo_operador
## 2016-07-30:2043 Min. : 4 PPGBC : 4 Min. : 13
## 1st Qu.: 9061 PPGMA : 4 1st Qu.:1821
## Median :11267 PPGMR : 4 Median :3992
## Mean :12301 PPGOB : 4 Mean :3156
## 3rd Qu.:13602 PROAF : 4 3rd Qu.:3992
## Max. :39147 PPDLF : 3 Max. :6270
## (Other):2020
## equipamento fabricante modelo
## AVIÃO :1603 NEIVA INDUSTRIA AERONAUTICA:388 AB-115 : 111
## HELICÓPTERO: 264 CESSNA AIRCRAFT :354 EMB-202 : 78
## ULTRALEVE : 151 PIPER AIRCRAFT :157 EMB-201A: 72
## PLANADOR : 11 EMBRAER :155 EMB-810C: 61
## ANFÍBIO : 6 AERO BOERO :126 EMB-810D: 38
## (Other) : 3 (Other) :753 (Other) :1668
## NA's : 5 NA's :110 NA's : 15
## tipo_motor quantidade_motores peso_maximo_decolagem quantidade_assentos
## JATO : 117 Min. :0.000 Min. : 0 Min. : 0.000
## PISTÃO :1601 1st Qu.:1.000 1st Qu.: 844 1st Qu.: 2.000
## SEM TRAÇÃO: 10 Median :1.000 Median : 1633 Median : 4.000
## TURBOEIXO : 148 Mean :1.244 Mean : 5330 Mean : 8.929
## TURBOÉLICE: 139 3rd Qu.:2.000 3rd Qu.: 2155 3rd Qu.: 6.000
## NA's : 28 Max. :4.000 Max. :285990 Max. :301.000
## NA's :9 NA's :18
## ano_fabricacao pais_registro categoria_registro categoria_aviacao
## Min. : 0 BRASIL :2000 TPP :760 PARTICULAR :760
## 1st Qu.:1975 ESTADOS UNIDOS: 22 PRI :359 INSTRUÇÃO :370
## Median :1986 PARAGUAI : 7 TPX :272 TÁXI AÉREO :272
## Mean :1902 PORTUGAL : 2 SAE-AG :196 EXPERIMENTAL:202
## 3rd Qu.:1999 ÁFRICA DO SUL : 1 PET :193 AGRÍCOLA :196
## Max. :2015 ALEMANHA : 1 (Other):254 (Other) :218
## NA's :4 (Other) : 10 NA's : 9 NA's : 25
## fase_operacao tipo_operacao nivel_dano
## POUSO :391 PRIVADA :775 DESTRUÍDA : 352
## DECOLAGEM :352 INSTRUÇÃO :366 LEVE : 261
## CRUZEIRO :237 TÁXI AÉREO :273 NENHUM : 168
## CORRIDA APÓS POUSO:189 AGRÍCOLA :266 SUBSTANCIAL:1193
## ESPECIALIZADA :115 EXPERIMENTAL:153 NA's : 69
## INDETERMINADA :103 (Other) :184
## (Other) :656 NA's : 26
## dia_extracao.y dia_ocorrencia_data
## 2016-07-30:2043 Min. :2006-01-02
## 1st Qu.:2009-10-11
## Median :2012-01-22
## Mean :2011-09-19
## 3rd Qu.:2013-12-01
## Max. :2015-12-31
##
Visualização de dados
Quantidade de ocorrências por ano:
#Tabela com as ocorrências por ano
<- as.data.frame(table(year(ocorrencia$dia_ocorrencia))) ocorrencias_ano
## Warning: tz(): Don't know how to compute timezone for object of class factor;
## returning "UTC". This warning will become an error in the next major version of
## lubridate.
ggplot(data = ocorrencias_ano, aes(x = Var1,y = Freq)) +
geom_bar(aes(fill = Var1),stat = "identity", show.legend = F) +
xlab("Ano") +
ylab("Quantidade de ocorrências") +
ggtitle("Quantidade de ocorrências de acidentes e incidentes aeronáticos - 2006 a 2015
Total: 2027 Ocorrências") +
geom_text(aes(label = Freq), vjust=-0.2, color="black") +
scale_fill_brewer(palette="BrBG")
- A quantidade de acidentes e incidentes graves aparenta ter uma tendência crescente de 2006 a 2012 e decresce a partir de 2013 a 2015, tendo seu pico em 2012, chegando a 287 acidentes, o que correponde a 14,15 % do total de acidentes no período estudado.
Quais são os tipos de classificação de ocorrências mais comuns?
- Vamos fazer um gráfico de pizza para visualizá-las, uma vez que há poucas categorias.
=table(ocorrencia$classificacao)
df_pizza_tab= data.frame(df_pizza_tab)
df_pizza
<- c('rgb(0,204,204)', 'rgb(102,51,0)')
colors
= plot_ly(df_pizza,
grafico_pizza_iterativo labels = ~Var1,
values = ~Freq,
marker = list(colors = colors),
type = 'pie') %>%
layout(title = 'Classificação dos tipos de ocorrências mais comuns (%) ')
grafico_pizza_iterativo
Quais são os equipamentos são mais comuns?
- Vamos fazer um gráfico de pizza para visualizá-las, uma vez que há poucas categorias.
=table(uniao_join_filtrado$equipamento)
df_pizza_tab= data.frame(df_pizza_tab) %>% top_n(3) df_pizza
## Selecting by Freq
<- c('rgb(0,204,204)', 'rgb(102,51,0)')
colors
= plot_ly(df_pizza,
grafico_pizza_iterativo labels = ~Var1,
values = ~Freq,
marker = list(colors = colors),
type = 'pie') %>%
layout(title = 'top 3 Classificação dos tipos de equipamento aéreo (%) ')
grafico_pizza_iterativo
Quais são os Status de investigação existentes?
=table(uniao_join_filtrado$status_investigacao)
df_pizza_tab= data.frame(df_pizza_tab)
df_pizza
<- c('rgb(0,204,204)', 'rgb(102,51,0)')
colors
= plot_ly(df_pizza,
grafico_pizza_iterativo labels = ~Var1,
values = ~Freq,
marker = list(colors = colors),
type = 'pie') %>%
layout(title = 'Status de investigação (%) ')
grafico_pizza_iterativo
- Número de Ocorrências por UF
#tabela da quantidade de ocorrências totais por UF
= uniao_join_filtrado %>% select(uf) %>%
dados_uf group_by(uf) %>%
summarise(quantidade = n()) %>%
arrange(desc(quantidade)) %>%
head(10)
$uf_fator = factor(dados_uf$uf,
dados_uflevels = c("SP",
"RS",
"MT",
"PR",
"MG",
"GO",
"RJ",
"PA",
"BA",
"AM"
#"MT",
#"RO",
#"CE",
#"MS",
#"PB",
#"RN",
#"PI",
#"MA",
#"DF",
#"PA",
#"AL",
#"TO",
#"SE",
#"AC",
#"RR",
#"AM",
#"AP")
)
)
= ggplot(data=dados_uf, aes(x=uf_fator, y=quantidade, fill=uf_fator)) +
grafico_barras_uf geom_bar(stat="identity", position=position_dodge(), colour="black") +
ggtitle("Top 10 Total de ocorrências por UF") +
xlab("UF") + ylab("Total de ocorrências") +
theme(axis.text.x = element_text(angle = -90, vjust = 0.5, hjust=1)) +
scale_fill_brewer(palette="BrBG")
ggplotly(grafico_barras_uf)
Ocorrências por tipo de problema
<- ocorrencia%>%
tipooco group_by(tipo)%>%
count(tipo)
#Ordenação
$tipo <- factor(tipooco$tipo,
tipoocolevels = tipooco$tipo[order(tipooco$n, decreasing = F)])
%>%
tipoocofilter(n > 120)%>%
ggplot(aes(x = tipo, y = n)) + coord_flip() +
geom_bar(aes(fill = tipo),stat = "identity", show.legend = F) +
xlab("Tipos de ocorrência") + ylab("Quantidade de ocorrências") +
ggtitle("Ocorrências por tipo de problema") +
geom_text(aes(label = n), vjust= 0.4, hjust = 0.6, color="black")+
theme(axis.text.y = element_text(size = 6))+
scale_fill_brewer(palette="BrBG")
<- ocorrencia%>%
tipooco group_by(tipo)%>%
count(tipo)
#Ordenação
$tipo_fator <- factor(tipooco$tipo,
tipoocolevels = tipooco$tipo[order(tipooco$n, decreasing = T)])
#Gráfico de Pareto dos acidentes por tipo de pista
::ggplot(tipooco, aes(x = tipo_fator, y = n)) +
ggplot2::stat_pareto(
ggQCpoint.color = "red",
point.size = 3,
line.color = "black",
bars.fill = c("blue", "orange")
+
) theme(axis.text.x = element_text(
angle = 90,
hjust = 1,
vjust = 0.5
+
))scale_fill_brewer(palette="BrBG")
## Warning in RColorBrewer::brewer.pal(n, pal): n too large, allowed maximum for palette BrBG is 11
## Returning the palette you asked for with that many colors
Gráfico de linhas - Peso máximo decolagem por ano
=
grafico_linhas ggplot(uniao_join_filtrado, aes(x=dia_ocorrencia_data,y=peso_maximo_decolagem)) +
geom_line(col="red") +
#geom_hline(yintercept = c(6000,10000))+
xlab("Data") +
ylab("Peso máximo na decolagem") +
ggtitle("Peso máximo na decolagem por ano") +
#geom_text(aes(label = peso_maximo_decolagem), vjust=-0.2, color="black") +
scale_fill_brewer(palette="BrBG")
grafico_linhas
Gráfico de linhas - Peso máximo decolagem por ano com limites 2 sigma
# Criando limites inferiores e superiores (3 Sigma)
=mean(uniao_join_filtrado$peso_maximo_decolagem)-3*sd(uniao_join_filtrado$peso_maximo_decolagem)
l1
=mean(uniao_join_filtrado$peso_maximo_decolagem)+3*sd(uniao_join_filtrado$peso_maximo_decolagem)
l2
ggplot(uniao_join_filtrado, aes(x=dia_ocorrencia_data,y=peso_maximo_decolagem)) +
geom_line(col="red") +
geom_hline(yintercept = c(l1,l2))+
xlab("Data") +
ylab("Peso máximo na decolagem") +
ggtitle("Série de pesos máximos na decolagem por ano") +
#geom_text(aes(label = peso_maximo_decolagem), vjust=-0.2, color="black") +
scale_fill_brewer(palette="BrBG")
grafico_linhas
Criando categorias em classes
=min(uniao_join_filtrado$peso_maximo_decolagem)
minimo
=quantile(uniao_join_filtrado$peso_maximo_decolagem,0.5)
q2
=quantile(uniao_join_filtrado$peso_maximo_decolagem,0.75)
q3
=max(uniao_join_filtrado$peso_maximo_decolagem)
maximo
$peso_classes=
uniao_join_filtradocut(uniao_join_filtrado$peso_maximo_decolagem, breaks = c(minimo,q2,q3,maximo),
labels = c("min -|Q2", "Q2-|Q3", "Q3-|max"),
include.lowest = F)
Contabilizando as frequências por classe na Pizza
=table(uniao_join_filtrado$peso_classes)
df_pizza_tab<<- data.frame(df_pizza_tab)
df_pizza
<- c('rgb(0,204,204)', 'rgb(102,51,0)')
colors
= plot_ly(df_pizza,
grafico_pizza_iterativo labels = ~Var1,
values = ~Freq,
marker = list(colors = colors),
type = 'pie') %>%
layout(title = 'Peso máximo decolagem (%) ')
grafico_pizza_iterativo
Box-plot do peso máximo por quartis
= ggplot(uniao_join_filtrado %>% na.omit, aes(x=peso_classes, y=peso_maximo_decolagem,fill=peso_classes)) +
grafico_boxplot geom_boxplot()+
ggtitle("Gráfico de Box-plot do peso máximo na decolagem por quartis")+
xlab("Label quartis") +
ylab("Peso máximo na decolagem")+
scale_fill_brewer(palette="BrBG")
grafico_boxplot
Selecionando as ocorrências que ficaram acima de 3 sigma de peso máximo decolagem
= uniao_join_filtrado %>% filter (peso_maximo_decolagem >l2) uniao_join_filtrado_acima3sigma_peso_decolagem
- Observamos que filtramos 28 ocorrências a serem analisadas
Fazendo o resumo da base reduzida
= summary(uniao_join_filtrado_acima3sigma_peso_decolagem)
s 1:7,2:10] s[
## classificacao tipo
## ACIDENTE :11 CAUSADO POR FENÔMENO METEOROLÓGICO EM VOO:7
## INCIDENTE GRAVE:17 OUTROS TIPOS :5
## COM TREM DE POUSO :2
## FALHA DE SISTEMA / COMPONENTE :2
## FALHA DO MOTOR EM VOO :2
## PERDA DE CONTROLE NO SOLO :2
## (Other) :8
## localidade uf pais dia_ocorrencia
## GUARULHOS : 6 SP :11 ARGENTINA : 0 2006-01-08: 1
## RIO DE JANEIRO : 4 RJ : 4 BRASIL :26 2006-02-21: 1
## BRASÍLIA : 3 DF : 3 COLÔMBIA : 1 2006-03-28: 1
## SÃO PAULO : 2 EX : 2 INGLATERRA: 0 2006-06-16: 1
## ÁGUAS INTERNACIONAIS: 1 AM : 1 PARAGUAI : 0 2006-09-29: 1
## CAMPINAS : 1 (Other): 6 PERU : 1 2006-10-31: 1
## (Other) :11 NA's : 1 URUGUAI : 0 (Other) :22
## horario sera_investigada comando_investigador
## 00:00:00: 2 NÃO : 0 CENIPA :22
## 01:05:00: 1 SIM :26 SERIPA-4: 4
## 01:30:00: 1 NA's: 2 SERIPA-3: 1
## 02:00:00: 1 SERIPA-5: 1
## 02:35:00: 1 EXTERIOR: 0
## 02:55:00: 1 SERIPA-1: 0
## (Other) :21 (Other) : 0