Introdução

Este projeto tem o objetivo de extrair informações sobre os bombardeios ocorridos durante a segunda guerra mundial e informações referente ao clima naquele período. Conforme o site Kaggle o conjunto de dados da segunda guerra mundial consiste em relatórios digitalizados de missões da Segunda Guerra Mundial. Cada registro inclui a data, conflito, localização geográfica e outros elementos que podem ser usados para formar uma sequência de fatos sobre guerra aérea de 1939 a 1945. Os registros incluem dados dos EUA e da Força Aérea Real, além de alguns australianos, Nova Zelândia e missões da força aérea Sul-Africana. Os dados foram disponibilizados pelo tenente-coronel Jenns Robertson, da Força Aérea dos EUA, que desenvolveu os Relatórios Históricos dos Centros de Operações (THOR) e os publicou on-line após receber a aprovação do departamento de defesa.

Os dados referente ao clima contém informações referente às condições climáticas registradas todos os dias em várias estações meteorológicas ao redor do mundo no período de 1940 a 1945. As informações incluem precipitação, queda de neve, temperaturas, velocidade do vento e se o dia incluiu tempestades com trovões ou outras condições climáticas ruins. Os dados disponibilziados no Kaggle foram obtidos no site da Administração Nacional Oceânica e Atmosférica dos Estados Unidos.

Começaremos com a descrição e a limpeza dos dados, depois visualizaremos nossos dados para entender melhor sua estrutura. Atrvavés da análise exploratória dos dados iremos analisar infoemações referente ao clima que algumas estações recolheram, frequência dos ataques aéreos.

Dicionário de Dados

Bombardeio aéreo

Coluna Descrição
Mission Date Data da Missão
Theater of Operations região em que operações militares ativas estão em andamento; “o exército estava em campo aguardando ação”; Exemplo: “ele serviu no teatro do Vietnã por três anos”
Country País que faz missão ou operação como EUA
Air Force Nome ou ID da unidade da força aérea como 5AF
Aircraft Series modelo ou tipo de aeronave como B24
Callsign Antes do ataque à bomba, mensagem, código, anúncio ou sintonia transmitida por rádio.
Takeoff Base nome do aeroporto de decolagem como o Ponte Olivo Airfield
Takeoff Location região da decolagem Sicília
Takeoff Latitude latitude da região de decolagem
Takeoff Longitude Longitude da região de decolagem
Target Country país de destino como a Alemanha
Target City cidade de destino como Berlim
Target Type tipo de destino como área da cidade
Target Industry indústria alvo, como cidade ou urbano
Target Priority segmente como 1 (a maioria)
Target Latitude latitude do alvo
Target Longitude Longitude do alvo

Localização das estações meteorológicas

Coluna Descrição
WBAN Número da estação meteorológica
NAME Nome da estação meteorológica
STATE/COUNTRY ID acrônimo de países
Latitude latitude
Longitude longitude

Clima

Coluna Descrição
STA número da estação meteorológica (WBAN)
Date Data da medição da temperatura
MeanTemp Média da temperatura
Precip Volume de chuva em mm
Poorweather Indica a ocorrência de algum mal tempo durante o dia analisado, podendo ser trovões, tempestade de areia, entre outros

Pacotes Necessários

Para este projeto, a maioria dos pacotes usados são os padrão para coletar, arrumar e analisar dados.

Os pacotes usados com menos frequência são o stringr que foi usado para tratar strings usando regex (expressão regular) e o ggmap usado para plotar os mapas usados no projeto

library(ggplot2) # Visualização por gráficos dos dados
suppressMessages(library(ggmap))  # Usado para visualizar os mapas
library(readr)  
suppressMessages(library(plyr))
suppressMessages(library(dplyr)) #cria/modifica colunas
suppressMessages(library(tidyverse)) #requerido pelo lubridate
suppressMessages(library(lubridate)) #trabalhar com datas
library(stringr) # Tratamento de strings.
library(DT) # apresentar dados como tabelas

Carregando os dados

Os dados usados nas análises foram encontrados no Kaggle. Os dados dos bombadeios aéreos (Force, n.d.) e condições climáticas (Smith, n.d.) no perído da segunda guerra mundial. Os dados referente ao clima está dividido em dois arquivos *.csv, onde um deles tem informações referentes à análise meteorológica enquanto o outro tem informações referente às estações meteorológica.

Todos os 3 conjuntos de dados estão no formato csv e para importá-los será usado o pacote redr. Abaixo é realizado a leitura dos arquivos usados no projeto

Bombardeio Aéreo

aerial <- read_csv("../ww2/operations.csv",
                          col_types="icccccccccccdccccccddddiiiiiddccddcdddcddddcci",
                          progress = FALSE)

Os dados de operações da segunda guerra mundial contém 178281 observações e 46 variáveis. Conforme pode ser visto ao lado: 178281, 46. Abaixo a estrutura do dataset:

datatable(head(aerial), options = list(searching = F, paging = T, scrollX = T))

Estações Meteorológicas

weather_station_location <- read_csv("../weather/Weather Station Locations.csv",
                          col_types="iccccidd",
                          progress = FALSE)

Os dados referentes à localização das estações meteorológicas possuem 161 observações e 8 variáveis, conforme pode ser visto ao lado: 161, 8 Abaixo a estrutura do dataset:

datatable(weather_station_location[1:15,], options = list(searching = F, paging = T, scrollX = T))

Clima

weather <- read.csv("../weather/Summary of Weather.csv", header = T, na.strings = "", strip.white = T, stringsAsFactors=FALSE)

Os dados referentes à localização às estações meteorológicas possuem 119040 observações e 31 variáveis, conforme pode ser visto ao lado: 119040, 31 Abaixo a estrutura do dataset:

datatable(weather[1:15,], options = list(searching = F, paging = T, scrollX = T))

Preparação dos Dados

Ajustando as variáveis (podendo ser chamado de coluna) dos datasets utilizados, removendo espaços entre os nomes das variáveis e deixando todos em minúsculo:

names(aerial) <- gsub('[()]', '', gsub(' ', '_', str_to_lower(names(aerial))))

names(weather_station_location) <- gsub('[()]', '', gsub(' ', '_', str_to_lower(names(weather_station_location))))

names(weather) <- gsub('[()]', '', gsub(' ', '_', str_to_lower(names(weather))))

Acima é usado a função gsub e str_to_lower presente no pacote stingr para fazer a limpeza.

Removendo colunas que estão sem dados e não vão ser usadas na análise:

Dataset Aerial

dropCol<- c("aircraft_returned", "aircraft_failed", "aircraft_damaged", "aircraft_lost", "callsign", "takeoff_base","high_explosives_weight_pounds","incendiary_devices","fragmentation_devices_weight_pounds", "time_over_target", "bomb_damage_assessment")

aerial <- aerial[,!(names(aerial)%in% dropCol)]

Removendo dados onde as cidades, latitude/longitude tanto dos alvos quanto da base aérea são nulas:

aerial <- aerial[!is.na(aerial$country),]

aerial <- aerial[!is.na(aerial$target_longitude),]
aerial$target_longitude <- as.numeric(aerial$target_longitude)

#gsub("aA:zZ", '',aerial$takeoff_latitude)


aerial <- aerial[!is.na(aerial$target_latitude),]
aerial$target_latitude <- as.numeric(aerial$target_latitude)

#Ao Tentar fazer o cast para inteiro, foi verificado que possuiam dados que não eram compostsos de números, removendo os dados conforme abaixo

aerial[aerial$takeoff_latitude %in% c("TUNISIA", "NEW GUINEA"), "takeoff_latitude"] <- NA

aerial <- aerial[!is.na(aerial$takeoff_latitude),]
aerial$takeoff_latitude <- as.numeric(aerial$takeoff_latitude)

aerial <- aerial[!is.na(aerial$takeoff_longitude),]

aerial$takeoff_longitude <- as.numeric(aerial$takeoff_longitude)

Para ficar mais fácil de lidar com datas, usaremos o pacote lubridate para transformar os dados da coluna mission_date em Date e criar a coluna que irá guardar o ano:

aerial <- aerial %>%
    mutate(mission_date = mdy(mission_date),
    mission_year=year(mission_date))

Dataset Weather

weather <- weather[,0:19]
dropCol <- c("windgustspd", "dr", "spd", "max", "min", "mea", "ft", "snd", "fb", "fti", "ith", "pgt", "sd3", "rhx", "rhn", "rvg", "wte")

weather <- weather[,!(names(weather)%in% dropCol)]

Os dados presentes na variável precip do dataframe weather não foi possível importar como se fosse numérico, pois possuem caracteres que não conseguem ser transformado em número

typeof(weather$precip)
## [1] "character"
unique(weather$precip)
##   [1] "1.016"   "0"       "2.54"    "T"       "3.556"   "0.508"   "0.254"  
##   [8] "1.778"   "3.302"   "0.762"   "5.588"   "5.08"    "2.032"   "25.654" 
##  [15] "40.132"  "19.05"   "23.876"  "4.064"   "12.192"  "2.794"   "33.274" 
##  [22] "19.304"  "47.752"  "6.35"    "3.048"   "8.382"   "10.16"   "27.178" 
##  [29] "30.48"   "45.212"  "10.668"  "15.494"  "57.658"  "58.166"  "11.43"  
##  [36] "31.242"  "17.78"   "26.924"  "26.67"   "6.604"   "5.334"   "4.826"  
##  [43] "7.62"    "8.636"   "7.874"   "12.446"  "90.932"  "13.462"  "11.938" 
##  [50] "5.842"   "4.318"   "6.096"   "9.144"   "4.572"   "9.906"   "9.652"  
##  [57] "1.524"   "13.97"   "17.272"  "33.528"  "1.27"    "13.716"  "8.128"  
##  [64] "22.352"  "39.116"  "36.068"  "98.044"  "3.81"    "14.986"  "78.232" 
##  [71] "146.304" "14.732"  "21.844"  "120.904" "42.164"  "23.368"  "21.082" 
##  [78] "44.958"  "2.286"   "50.038"  "17.526"  "51.054"  "7.112"   "25.4"   
##  [85] "7.366"   "16.256"  "46.736"  "8.89"    "24.638"  "11.684"  "17.018" 
##  [92] "144.78"  "18.034"  "50.8"    "106.426" "36.576"  "53.34"   "34.798" 
##  [99] "12.954"  "26.416"  "85.598"  "47.498"  "12.7"    "11.176"  "59.182" 
## [106] "33.782"  "40.894"  "28.194"  "24.892"  "14.478"  "71.628"  "102.108"
## [113] "31.496"  "36.322"  "37.846"  "35.56"   "31.75"   "49.022"  "69.85"  
## [120] "36.83"   "19.558"  "127.508" "64.77"   "105.156" "16.002"  "75.184" 
## [127] "143.51"  "60.96"   "68.58"   "55.88"   "23.622"  "126.238" "70.358" 
## [134] "6.858"   "16.764"  "24.13"   "52.832"  "25.146"  "74.676"  "16.51"  
## [141] "65.024"  "51.816"  "13.208"  "30.226"  "29.972"  "215.9"   "21.336" 
## [148] "76.962"  "29.464"  "9.398"   "15.748"  "45.974"  "41.148"  "48.514" 
## [155] "33.02"   "10.414"  "18.796"  "14.224"  "68.326"  "80.264"  "70.866" 
## [162] "35.814"  "22.86"   "30.988"  "20.828"  "34.036"  "20.066"  "27.432" 
## [169] "62.23"   "37.338"  "55.372"  "73.66"   "18.288"  "114.808" "56.388" 
## [176] "273.558" "27.686"  "111.506" "101.346" "120.142" "116.586" "66.294" 
## [183] "32.766"  "55.118"  "30.734"  "46.228"  "68.072"  "62.484"  "72.644" 
## [190] "203.708" "15.24"   "61.214"  "48.768"  "10.922"  "54.61"   "81.788" 
## [197] "38.1"    "37.592"  "18.542"  "49.784"  "32.258"  "94.488"  "67.818" 
## [204] "41.402"  "22.606"  "43.434"  "27.94"   "61.468"  "25.908"  "54.102" 
## [211] "52.578"  "46.99"   "177.8"   "28.956"  "119.38"  "44.45"   "85.344" 
## [218] "95.758"  "91.948"  "38.354"  "39.624"  "80.01"   "40.386"  "35.306" 
## [225] "88.646"  "65.786"  "136.398" "77.978"  "116.84"  "75.438"  "69.596" 
## [232] "42.672"  "39.37"   "20.574"  "39.878"  "42.926"  "38.608"  "155.448"
## [239] "140.716" "148.336" "19.812"  "60.706"  "97.028"  "57.912"  "72.898" 
## [246] "65.532"  "71.882"  "21.59"   "22.098"  "34.29"   "35.052"  "43.18"  
## [253] "50.546"  "20.32"   "70.612"  "67.31"   "28.448"  "32.004"  "48.006" 
## [260] "76.2"    "37.084"  "48.26"   "43.942"  "76.708"  "52.07"   "52.324" 
## [267] "120.396" "80.518"  "63.5"    "125.984" "116.332" "46.482"  "76.454" 
## [274] "34.544"  "42.418"  "29.21"   "81.28"   "24.384"  "58.674"  "108.204"
## [281] "173.736" "49.53"   "225.298" "206.248" "162.052" "87.122"  "88.138" 
## [288] "103.632" "82.804"  "93.726"  "28.702"  "99.06"   "61.976"  "51.308" 
## [295] "110.998" "93.98"   "107.442" "23.114"  "92.456"  "57.15"   "84.074" 
## [302] "40.64"   "62.738"  "41.656"  "32.512"  "50.292"  "26.162"  "53.848" 
## [309] "73.914"  "64.516"  "38.862"  "84.836"  "103.886" "41.91"   "56.896" 
## [316] "82.042"  "66.548"  "60.198"  "53.086"  "54.356"  "45.72"   "29.718" 
## [323] "43.688"  "67.056"  "70.104"  "69.342"  "86.868"  "86.106"  "58.42"  
## [330] "74.168"  "68.834"  "97.79"   "44.704"  "63.754"  "56.134"  "66.04"  
## [337] "85.852"  "64.262"  "85.09"   "122.936" "44.196"  "231.648" "83.058" 
## [344] "121.666" "56.642"  "51.562"  "113.538" "75.946"  "102.362" "54.864" 
## [351] "78.994"  "75.692"  "94.742"  "47.244"  "74.422"  "152.4"   "71.374" 
## [358] "79.248"  "130.048" "97.536"  "99.314"  "238.76"  "102.87"  "82.296" 
## [365] "94.234"  "125.73"  "59.436"  "112.014" "182.372" "127"     "88.392" 
## [372] "211.328" "82.55"   "107.696" "73.406"  "124.46"  "163.83"  "107.95" 
## [379] "62.992"  "118.618" "136.652" "55.626"  "101.092" "90.424"  "57.404" 
## [386] "98.552"  "90.678"  "95.504"  "159.512" "103.378" "139.446" "234.95" 
## [393] "133.35"  "100.33"  "63.246"  "73.152"  "81.534"  "157.48"  "64.008" 
## [400] "77.47"   "77.216"  "59.69"   "71.12"   "124.206" "59.944"  "104.394"
## [407] "253.238" "86.614"  "49.276"  "77.724"  "123.698" "106.68"  "97.282" 
## [414] "45.466"  "126.492" "53.594"  "123.952" "65.278"  "92.71"   "79.756" 
## [421] "166.624" "74.93"   "95.25"   "61.722"  "148.59"  "248.92"  "100.584"
## [428] "147.828" "257.048" "307.34"  "184.15"  "87.376"  "134.874" "206.756"
## [435] "110.744" "79.502"  "67.564"  "81.026"  "89.408"  "164.338" "101.854"
## [442] "90.17"   "134.62"  "58.928"  "83.82"   "121.92"  "69.088"  "91.694" 
## [449] "60.452"  "105.41"  "143.002" "137.922" "87.884"  "88.9"    "112.776"
## [456] "78.486"  "72.136"  "194.564" "112.522" "134.112" "128.778" "83.312" 
## [463] "96.774"  "168.656" "78.74"   "117.348" "80.772"  "125.222" "182.626"
## [470] "132.588" "209.804" "116.078" "89.154"  "129.54"  "96.266"  "86.36"  
## [477] "117.602" "83.566"  "92.964"  "109.982" "92.202"  "149.352" "66.802" 
## [484] "122.174" "233.172" "200.406" "124.968" "89.916"  "139.954" "184.404"
## [491] "91.44"   "89.662"  "100.838" "101.6"   "119.634" "98.298"  "94.996" 
## [498] "132.842" "84.328"  "130.556" "99.822"  "109.728" "91.186"  "96.52"  
## [505] "106.172" "72.39"   "104.648" "238.506" "139.192" "132.334" "113.03" 
## [512] "175.006" "124.714" "150.114" "125.476" "119.888" "133.858" "167.386"
## [519] "114.554" "115.316" "84.582"  "185.166" "104.902" "111.252" "164.846"
## [526] "118.872" "167.64"  "163.322" "111.76"  "104.14"  "194.31"  "140.208"
## [533] "110.236" "153.162" "165.1"   "242.316" "154.686" "105.918" "133.096"
## [540] "161.036"

Analisando os dados vemos que a coluna que possui uma letra ao invés de número é T, segundo Oblack (2019) vemos que a palavra trace é usada para descrever uma quantidade muito pequena de precipitação que não é possível mensurar utilizando os instrumentos climático. Oblack (2019) afirma que:

“As quantidades vestigiais da precipitação são abreviadas pela letra maiúscula”T“, geralmente colocada entre parênteses (T). Se você precisar converter um ‘trace’ em um valor numérico, será igual a 0,00”.

Com as informações acima trocamos os caracteres T para 0.00 e transformamos a coluna para numérico

weather[which(weather$precip=="T"), "precip"] <- 0.00
weather$precip <- as.numeric(weather$precip)
typeof(weather$precip)
## [1] "double"
unique(weather$snowfall)
##  [1] "0"       NA        "22.86"   "33.02"   "30.48"   "2.54"    "5.08"   
##  [8] "10.16"   "7.62"    "20.32"   "15.24"   "17.78"   "12.7"    "25.4"   
## [15] "27.94"   "43.18"   "38.1"    "45.72"   "53.34"   "58.42"   "66.04"  
## [22] "76.2"    "81.28"   "73.66"   "63.5"    "50.8"    "48.26"   "60.96"  
## [29] "55.88"   "35.56"   "78.74"   "40.64"   "86.36"   "83.82"   "68.58"  
## [36] "#VALUE!"

Podemos ver que há valores que não se encaixam em tipos numéricos assim como a variável snowfall, que contém informações divergente do esperado. Ppodemos assumir que caso houvesse caído neve nesse período os dados estariam válidos, com isso podemos substituir os dados por 0.

weather[which(weather$snowfall=="#VALUE!"), "snowfall"] <- 0.00

weather[is.na(weather$snowfall), "snowfall"] <- 0.00

weather$snowfall <- as.numeric(weather$snowfall)

Para ficar mais fácil de lidar com datas, usaremos o pacote lubridate para transformar os dados da coluna date em Date:

weather <- weather %>%
    mutate(date = ymd(date),
    year=year(date))

Como pode ser visto abaixo a variável que indica mal tempo no dataset é a que apresenta mais problemas, pois, os dados possuem mais de uma informação conforme descrito abaixo:

Thunder; Sleet; Hail; Dust or Sand; Smoke or Haze; Blowing Snow; Rain; Snow; Glaze; Fog; 0 = No, 1 = Yes

TSHDSBRSGF -> forma como os dados são salvos, 1 para o tipo de mal tempo descrito acima 0 caso não tenha tido nenhuma ocorrência.

unique(weather$poorweather)
##  [1] NA           "1"          "1     1"    "1 1"        "1     1  1"
##  [6] "1  1"       "1        1" "0"          "1   1 1"    "1    1"    
## [11] "1     0"    "1000"       "1001"       "100000"     "1000001000"
## [16] "101000"     "101001"     "1000001001" "1000101001" "100001"    
## [21] "1000000000" "1000101000" "1010001000" "1000100000" "1000100001"
## [26] "1010001001" "10001001"   "11"         "11 1"       "11    1"   
## [31] "1100000"    "1 1  1"     "1 0  1"     "1 0"        "1   1 1  1"
## [36] "1000000"    "1101000"    "1101001"    "1   1"
weather %>% 
    select(poorweather) %>% 
    group_by(poorweather) %>% 
    summarize(total = n()) %>%
    arrange(desc(total)) %>%
  datatable(options = list(searching = F, paging = T, scrollX = T))
## `summarise()` ungrouping output (override with `.groups` argument)

Conforme visto acima, temos que tratar os dados da tabela acima, pois temos mais de uma informação por variável. Para essa análise iremos contar a quantidade de ocorrências de 1 e criaremos uma nova variável informando a “frequência” de intempéries.

#Tratar NA como 0
weather[is.na(weather$poorweather), "poorweather"] <- 0



length(grep("1", weather$poorweather))
## [1] 33367
weather <- weather %>%
  transform(bad_time = str_count(weather$poorweather, "1"))

unique(weather$bad_time)
## [1] 0 1 2 3 4

Após inserção da nova coluna, temos os seguintes valores:

weather %>% 
    select(bad_time) %>% 
    group_by(bad_time) %>% 
    summarize(total = n()) %>%
    arrange(desc(total)) %>%
  datatable(options = list(searching = F, paging = T, scrollX = T))
## `summarise()` ungrouping output (override with `.groups` argument)

Temos que tratar os dados que estão vazios, usando as variáveis precip e snowfall que dizem a quantidade de chuva e neve que caíram, respectivamente.

mask <- which((weather$precip > 4) & (weather$precip <= 9) & (weather$bad_time < 1))
weather[mask, "bad_time"] <- 1

mask <- which(((weather$precip > 9) & (weather$precip <= 27) & (weather$bad_time < 2)))
weather[mask, "bad_time"] <- 2

mask <- which((weather$precip > 27) & (weather$precip <= 63) & (weather$bad_time < 3))
weather[mask, "bad_time"] <- 3

mask <- which((weather$precip > 63) & (weather$bad_time < 4))
weather[mask, "bad_time"] <- 4


weather %>% 
    select(bad_time) %>% 
    group_by(bad_time) %>% 
    summarize(total = n()) %>%
    arrange(desc(total)) %>%
  datatable(options = list(searching = F, paging = T, scrollX = T))
## `summarise()` ungrouping output (override with `.groups` argument)
mask <- which((weather$snowfall > 8) & (weather$snowfall <= 14) & (weather$bad_time < 1))
weather[mask, "bad_time"] <- 1

mask <- which(((weather$snowfall > 14) & (weather$snowfall <= 30) & (weather$bad_time < 2)))
weather[mask, "bad_time"] <- 2

mask <- which((weather$snowfall > 30) & (weather$snowfall <= 61) & (weather$bad_time < 3))
weather[mask, "bad_time"] <- 3

mask <- which((weather$snowfall > 61) & (weather$bad_time < 4))
weather[mask, "bad_time"] <- 4


weather %>% 
    select(bad_time) %>% 
    group_by(bad_time) %>% 
    summarize(total = n()) %>%
    arrange(desc(total)) %>%
  datatable(options = list(searching = F, paging = T, scrollX = T))
## `summarise()` ungrouping output (override with `.groups` argument)

Dataset Weather Station Location

dropCol <- c("elev")

weather_station_location <- weather_station_location[,!(names(weather_station_location)%in% dropCol)]

Filtrando latitude e longitude que estão dentro dos valores usuais

str(weather)
## 'data.frame':    119040 obs. of  15 variables:
##  $ sta        : int  10001 10001 10001 10001 10001 10001 10001 10001 10001 10001 ...
##  $ date       : Date, format: "1942-07-01" "1942-07-02" ...
##  $ precip     : num  1.02 0 2.54 2.54 0 ...
##  $ maxtemp    : num  25.6 28.9 26.1 26.7 26.7 ...
##  $ mintemp    : num  22.2 21.7 22.2 22.2 21.7 ...
##  $ meantemp   : num  23.9 25.6 24.4 24.4 24.4 ...
##  $ snowfall   : num  0 0 0 0 0 0 0 0 0 0 ...
##  $ poorweather: chr  "0" "0" "0" "0" ...
##  $ yr         : int  42 42 42 42 42 42 42 42 42 42 ...
##  $ mo         : int  7 7 7 7 7 7 7 7 7 7 ...
##  $ da         : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ prcp       : chr  "0.04" "0" "0.1" "0.1" ...
##  $ snf        : chr  "0" "0" "0" "0" ...
##  $ year       : num  1942 1942 1942 1942 1942 ...
##  $ bad_time   : num  0 0 0 0 0 0 0 0 0 0 ...
weather_station_location <-  weather_station_location[((weather_station_location$latitude <= 90) &
                                (weather_station_location$latitude >= -90)) &
                                ((weather_station_location$longitude <= 180) &
                                (weather_station_location$longitude >= -180)),]

Juntando os dataframes de clima e localização das estações meteorológicas

weather_location <- merge(x=weather, y=weather_station_location, by.x="sta", by.y="wban", all=T)

Análise Exploratória dos Dados

Bombardeio Aéreo

Centro de Operações

Na tabela abaixo temos a quantidade de missões que cada centro de operações realizou. Podemos verificar que os Estados Unidos que fazia parte do Centro de Operações do Mediterrâneo (MTO) foi o país que mais realizou missões aéreas durante a segunda guerra mundial.

aerial %>% 
    select(theater_of_operations, country) %>% 
    group_by(theater_of_operations, country) %>% 
    summarize(total = n()) %>%
    arrange(desc(total)) %>%
  datatable(options = list(searching = F, paging = T, scrollX = T))
## `summarise()` regrouping output by 'theater_of_operations' (override with `.groups` argument)

Ano vs Bombardeio Aéreo (País)

Os dados dos países que participaram da missão de vôo estão representados neste gráfico. Este gráfico é feito principalmente, Com base no número de bombardeios por cada base de operações das Forças Aliadas. Após uma análise mais aprofundada, cada gráfico de barras é dividido não apenas por base de operações, mas por país em cada base de operações. Segundo esses dados, a Base Europeia de Operações teve a atividade mais alta, o que faz sentido, já que a maior parte da Segunda Guerra Mundial ocorreu na Europa.

De acordo com Overy (2011), a principal causa da vitória do poder aliado, como afirma Joachim von Ribbentrop, ministro das Finanças da Alemanha nazista, foi o sucesso das missões aéreas conduzido pelas Forças Aliadas.

Abaixo podemos ver a quantidade de ataques que ocorreram agrupadas pelos centros de operação

#Legenda
#European Theater of Operations (ETO)
#Pacific Theater of Operations (PTO)
#Mediterranean Theater of Operations (MTO)
#China Burma India Theater (CBI)

ggplot(aerial, aes(mission_year, fill = theater_of_operations)) + geom_bar() + theme_classic() + labs(x = "Ano", y = "Bombardeamento Aéreo")

E Aqui temos a contagem de missões por ano

ggplot(aerial, aes(x = mission_year)) + geom_bar(aes(fill=mission_year)) + labs(x = "Ano", y = "Quantidade de Missões")

Podemos ver que no ano de 1943 houve o pico dos ataques aéreos, período em que houve uma declaração de guerra com todos os países do mundo.

NAF

Este gráfico indica o número de bombardeios aéreos, por cada esquadrão da Força Aérea Numerada, também conhecido como esquadrão usado em ataques aéreos. Com o passar dos anos, o número de vários NAF aumenta à medida que mais países estão envolvidos/sendo atraídos para o W2. Os NAF mais eventualmente são as Forças Aliadas.

ggplot(aerial, aes(x =mission_year)) + geom_bar(aes(fill=air_force)) + labs(x = "Ano", y = "Quant. Ataques Aéreos") 

ggplot(aerial, aes(x = mission_year)) + geom_bar(aes(fill=country)) + labs(x = "Ano", y = "Quant. Ataques Aéreos") 

Abaixo podemos ver os ataques

ggplot(aerial, aes(x = mission_year, fill = target_priority)) + geom_bar() + facet_wrap(~aerial$theater_of_operations, scales = "fixed") + theme(legend.background = element_rect(fill="lightblue", size=0.5, linetype="solid")) + labs(x = "Ano", y = "Bombardeamento Aéreo")
## Warning: position_stack requires non-overlapping x intervals

Aeronave mais utilizada

Abaixo temos uma tabela mostrando as aeronaves utilizadas ordenadas da maior para a menos. E podemos ver que a mais utilizada foi o modelo A36

#ggplot(aerial, aes(x = air_force)) + geom_bar(aes(fill=aircraft_series)) + labs(x = "Year", y = "# Aerial Bombings") 

aerial %>% 
    select(aircraft_series) %>% 
    group_by(aircraft_series) %>% 
    summarize(total= n()) %>%
    arrange(desc(total)) %>%
    datatable()
## `summarise()` ungrouping output (override with `.groups` argument)
aerial %>% 
  count(aircraft_series) %>% 
  mutate(pct = n) %>%
  ggplot(aes(x = reorder(aircraft_series, -pct), y = pct)) +
  geom_bar(aes(fill=aircraft_series), stat = 'identity') +
  theme(axis.text.x=element_text(angle = -45, hjust = 0)) +
  labs(title="Quantidade de Aeronaves por série", y="Quantidade", x="Série", fill="Série")

Países mais atacadas

Abaixo temos um gráfico mostrando os 10 países mais atacados durante o período da segunda guerra mundial

aero <- aerial %>% filter(theater_of_operations != '') %>% group_by(target_country) %>% summarise(Missions = n(),Tons = sum(aerial$total_weight_pounds))
## `summarise()` ungrouping output (override with `.groups` argument)
topCountries <- aero %>% group_by(target_country) %>% summarise(Missions = sum(Missions)) %>% mutate(rank = rank(-Missions)) %>% filter(rank <= 10) %>% arrange(rank)
## `summarise()` ungrouping output (override with `.groups` argument)
ggplot(topCountries, aes(x = reorder(target_country,-Missions), y = Missions)) + 
  geom_bar(stat = "identity", position = "dodge", fill = "blue") + 
  geom_text(aes(label=Missions), vjust=-0.5, color="black", position = position_dodge(0.9), size=3.5) +
  scale_fill_brewer(palette="Paired") + 
  theme(axis.text.x=element_text(angle = 45, vjust = 0.5)) +
  theme(plot.title = element_text(hjust = 0.5)) +
  ggtitle("10 países ") +
  labs(x = "Paíeses", y="Missões")

Abaixo temos os 10 maiores tipos de locais que estão sendo atacados

## `summarise()` ungrouping output (override with `.groups` argument)

Mapas

Mapa que mostra os alvos dos ataques aéreos por ano.

worldmap + 
geom_point(data = aerial, aes(target_longitude_recenter, target_latitude,color=mission_year), pch = 19, size = 1, alpha = .4)
## Warning: Removed 1 rows containing missing values (geom_point).

Mapa que mostra os de onde saíram os aviões agrupados por centro de operações.

worldmap + 
  geom_point(data=aerial, aes(takeoff_longitude, takeoff_latitude, col = theater_of_operations), size = 1.6, pch = 25, bg = "grey",  alpha = .4)
## Warning: Removed 443 rows containing missing values (geom_point).

Clima

Analisando a distribuição dos valores de mau tempo, podemos ver se os dados estão próximos do esperado, com base na experiência de observações em tempo real no mundo real.

ggplot(weather, aes(x = bad_time)) + geom_bar(aes(fill=bad_time)) + labs(x = "Intensidade do Tempo Ruim", y = "Quantidade") 

Baseado na variável criada bad_time, uma distribuição da quantidade de medições climáticas baseados no intervalo de 0 à 4, onde 0 não houve tempo ruim, com base no cálculo que fizemos (e nas colunas análisadas: precipitação e quantidade de neve)

Em seguida temos a visualização da posição das estações meteorológicas

worldmap +
  geom_point(data=weather_station_location, aes(longitude, latitude, col =wban), pch = 19, size = 1.6, alpha = 1)
## Warning: Removed 70 rows containing missing values (geom_point).

Temperatura média

Abaixo temos a temperatura média para a estação de nome Bindukuri:

bindukuri <- weather_location[weather_location$name == 'BINDUKURI',]

bindukuri  %>%
  group_by(latitude, longitude) %>%
  ggplot() +
    geom_line(aes(x =date , y = meantemp), fill=date)
## Warning: Ignoring unknown parameters: fill

Onde podemos ver a média de temperatura medida para a estação, podemos ver que as séries temporais apresentam variações sazonais, ou seja, são pertinentes à estação do ano, onde, no verão, a temperatura média é mais alta e no inverno a temperatura média é mais baixa a cada ano.

Conclusão

Com os dados analisados tivemos um pequeno levantamento dos dados referente aos ataques aéreos ocorridos no período da segunda guerra mundial. Os dados referente ao clima estavam com bastante ruído o que impactou um pouco no levantamento dos dados. Mas, conforme pode ser visto na última análise em alguns locais, como “BINDUKURI” o clima segue um padrão já esperado, dentro das variações sazonais.

Trabalhos Futuro

Em trabalhos futuros podemos fazer uma relação dos ataques e clima, analisando se na data do ataque as condições de voô estavam ruins, tendo algum impecilho para que fosse realizado o ataque. Pode-se fazer uma análise do tipo ARIMA (modelo auto-regressivo integrado de médias móveis) para entender melhor a relação dos 2 datasets (weather_location e aerial).

Referências

Force, United States Air. n.d. “Aerial Bombing Operations in World War Ii.” Edited by United States Air Force. https://www.kaggle.com/usaf/world-war-ii.

Oblack, Rachelle. 2019. “What Is a "Trace" of Precipitation?” July 3, 2019. https://www.thoughtco.com/what-is-trace-of-precipitation-3444238.

Overy, Richard. 2011. “World War Two: How the Allies Won.” February 17, 2011. http://www.bbc.co.uk/history/worldwars/wwtwo/how_the_allies_won_01.shtml.

Smith, Shane. n.d. “Weather Conditions in World War Two.” Edited by Shane Smith. https://www.kaggle.com/smid80/weatherww2.