Modelos Estatísticos - BICT/MAR - UNIFESP
Aula 2 - Análise exploratória de dados - Parte I
Introdução
Trabalharemos nesta aula com a base de dados storms disponível no pacote do R dplyr.Este banco de dados é um dos vários conjuntos de dados disponíveis no National Hurricane Center (NHC) Data Archive, que faz parte da National Oceanic and Atmospheric Administration (NOAA).
Pacotes necessários
Utilizaremos os pacotes dplyr e ggplot2
# instalando os pacotes
# install.packages(c("dplyr", "ggplot2"))# carrega os pacotes
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(ggplot2)Dados de furacão do Atlântico
# visualiza a base de dados
storms
## # A tibble: 19,066 x 13
## name year month day hour lat long status categ~1 wind press~2
## <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <dbl> <int> <int>
## 1 Amy 1975 6 27 0 27.5 -79 tropical dep~ NA 25 1013
## 2 Amy 1975 6 27 6 28.5 -79 tropical dep~ NA 25 1013
## 3 Amy 1975 6 27 12 29.5 -79 tropical dep~ NA 25 1013
## 4 Amy 1975 6 27 18 30.5 -79 tropical dep~ NA 25 1013
## 5 Amy 1975 6 28 0 31.5 -78.8 tropical dep~ NA 25 1012
## 6 Amy 1975 6 28 6 32.4 -78.7 tropical dep~ NA 25 1012
## 7 Amy 1975 6 28 12 33.3 -78 tropical dep~ NA 25 1011
## 8 Amy 1975 6 28 18 34 -77 tropical dep~ NA 30 1006
## 9 Amy 1975 6 29 0 34.4 -75.8 tropical sto~ NA 35 1004
## 10 Amy 1975 6 29 6 34 -74.8 tropical sto~ NA 40 1002
## # ... with 19,056 more rows, 2 more variables:
## # tropicalstorm_force_diameter <int>, hurricane_force_diameter <int>, and
## # abbreviated variable names 1: category, 2: pressureVocê pode encontrar algumas descrições técnicas de tempestades dando uma olhada em seu manual (ou documentação de ajuda): ?storms.
Storms é um objeto tibble com dados em formato tabular.
A forma como os tibbles são impressos é
muito interessante. O número de linhas exibidas é limitado a 10; também,
dependendo da largura do espaço de impressão, você verá apenas algumas
colunas mostradas para caber nessa largura. Observe que abaixo do nome
de cada coluna há uma abreviação de três letras entre colchetes
angulares, essa abreviação indica o tipo de dado usado pelo R para
armazenar os valores. Por exemplo, o nome da primeira coluna tem o tipo
Aqui está uma descrição completa de todas as colunas:
name: Nome da Tempestade
year, month e day: Data do relatório
hour: Hora do relatório (em UTC)
lat: Latitude
long: Longitude
status: Classificação de tempestade (Depressão Tropical, Tempestade Tropical ou Furacão)
category: categoria de tempestade Saffir-Simpson (estimada a partir da velocidade do vento. -1 = Depressão Tropical, 0 = Tempestade Tropical)
wind: velocidade máxima sustentada do vento da tempestade (em nós)
pressure: pressão do ar no centro da tempestade (em milibares)
tropicalstorm_force_diameter: Diâmetro da área com ventos fortes de tempestade tropical (34 nós ou acima)
hurricane_force_diameter: Diâmetro da área com ventos fortes de furacão (64 nós ou acima)
Analise exploratória
Funções pull() e select()
Nossa primeira pergunta é: qual a cobertura temporal (período em anos) do banco de dados?
Para responder a essa pergunta, precisamos trabalhar com anos de coluna. Existem várias maneiras em R de manipular uma coluna de um objeto tabular. Usando “dplyr”, existem dois tipos básicos de funções para extrair variáveis: pull() e select().
Podemos usar a função pull() que puxa ou extrai uma coluna inteira. Como existem 10.010 elementos em anos, vamos também usar unique() para descobrir o conjunto de valores únicos de ano nos dados. Primeiro, extraímos o ano e depois identificamos ocorrências únicas:
# visualiza a base de dados
unique(pull(storms, year))
## [1] 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989
## [16] 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004
## [31] 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019
## [46] 2020 2021A mesma operação pode ser realizada com select(). A diferença entre pull() e select() está na maneira como a saída é tratada. A função select() retorna a saída em um formato de tabela, enquanto pull() retorna a saída como um vetor R:
unique(select(storms, year))
## # A tibble: 47 x 1
## year
## <dbl>
## 1 1975
## 2 1976
## 3 1977
## 4 1978
## 5 1979
## 6 1980
## 7 1981
## 8 1982
## 9 1983
## 10 1984
## # ... with 37 more rowsQue tal aplicar os mesmos comandos para a variável month e day
unique(pull(storms, month))
## [1] 6 7 8 9 10 11 5 12 4 1
# Nesse caso, seria melhor se os classificássemos:
sort(unique(pull(storms, month)))
## [1] 1 4 5 6 7 8 9 10 11 12
# para os dias
sort(unique(pull(storms, day)))
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
## [26] 26 27 28 29 30 31Função filter()
Vamos nos concentrar nas tempestades registradas em 1975. Como as selecionamos? Computacionalmente, esta operação inclui uma condição lógica: year == 1975. Esta condição significa que, de todos os valores de ano disponíveis, obtemos aqueles que correspondem a 1975. Isso é feito através da função “dplyr” filter()
storms75 <- filter(storms, year == 1975)
storms75
## # A tibble: 238 x 13
## name year month day hour lat long status categ~1 wind press~2
## <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <dbl> <int> <int>
## 1 Amy 1975 6 27 0 27.5 -79 tropical dep~ NA 25 1013
## 2 Amy 1975 6 27 6 28.5 -79 tropical dep~ NA 25 1013
## 3 Amy 1975 6 27 12 29.5 -79 tropical dep~ NA 25 1013
## 4 Amy 1975 6 27 18 30.5 -79 tropical dep~ NA 25 1013
## 5 Amy 1975 6 28 0 31.5 -78.8 tropical dep~ NA 25 1012
## 6 Amy 1975 6 28 6 32.4 -78.7 tropical dep~ NA 25 1012
## 7 Amy 1975 6 28 12 33.3 -78 tropical dep~ NA 25 1011
## 8 Amy 1975 6 28 18 34 -77 tropical dep~ NA 30 1006
## 9 Amy 1975 6 29 0 34.4 -75.8 tropical sto~ NA 35 1004
## 10 Amy 1975 6 29 6 34 -74.8 tropical sto~ NA 40 1002
## # ... with 228 more rows, 2 more variables: tropicalstorm_force_diameter <int>,
## # hurricane_force_diameter <int>, and abbreviated variable names 1: category,
## # 2: pressureAlgumas análises possíveis a partir dos dados de 1975. Por exemplo o uso da função distinct() para saber os nomes dos furacões em 1975.
unique(pull(storms75, name))
## [1] "Amy" "Blanche" "Caroline" "Doris" "Eloise" "Faye" "Gladys"
## [8] "Hallie"
distinct(storms75, name)
## # A tibble: 8 x 1
## name
## <chr>
## 1 Amy
## 2 Blanche
## 3 Caroline
## 4 Doris
## 5 Eloise
## 6 Faye
## 7 Gladys
## 8 HalliePodemos contar o número de linhas ou registros para cada evento e obter as frequencias absolutas (n).
count(storms75, name)
## # A tibble: 8 x 2
## name n
## <chr> <int>
## 1 Amy 31
## 2 Blanche 20
## 3 Caroline 33
## 4 Doris 29
## 5 Eloise 46
## 6 Faye 19
## 7 Gladys 46
## 8 Hallie 14Mais alguns usos da função filter()
# registros entre 1975 e 1976
storms75and76 <- filter(storms, year == 1975 | year == 1976)
storms75and76
## # A tibble: 364 x 13
## name year month day hour lat long status categ~1 wind press~2
## <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <dbl> <int> <int>
## 1 Amy 1975 6 27 0 27.5 -79 tropical dep~ NA 25 1013
## 2 Amy 1975 6 27 6 28.5 -79 tropical dep~ NA 25 1013
## 3 Amy 1975 6 27 12 29.5 -79 tropical dep~ NA 25 1013
## 4 Amy 1975 6 27 18 30.5 -79 tropical dep~ NA 25 1013
## 5 Amy 1975 6 28 0 31.5 -78.8 tropical dep~ NA 25 1012
## 6 Amy 1975 6 28 6 32.4 -78.7 tropical dep~ NA 25 1012
## 7 Amy 1975 6 28 12 33.3 -78 tropical dep~ NA 25 1011
## 8 Amy 1975 6 28 18 34 -77 tropical dep~ NA 30 1006
## 9 Amy 1975 6 29 0 34.4 -75.8 tropical sto~ NA 35 1004
## 10 Amy 1975 6 29 6 34 -74.8 tropical sto~ NA 40 1002
## # ... with 354 more rows, 2 more variables: tropicalstorm_force_diameter <int>,
## # hurricane_force_diameter <int>, and abbreviated variable names 1: category,
## # 2: pressure
# outra forma
filter(storms, year %in% c(1975, 1976))
## # A tibble: 364 x 13
## name year month day hour lat long status categ~1 wind press~2
## <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <dbl> <int> <int>
## 1 Amy 1975 6 27 0 27.5 -79 tropical dep~ NA 25 1013
## 2 Amy 1975 6 27 6 28.5 -79 tropical dep~ NA 25 1013
## 3 Amy 1975 6 27 12 29.5 -79 tropical dep~ NA 25 1013
## 4 Amy 1975 6 27 18 30.5 -79 tropical dep~ NA 25 1013
## 5 Amy 1975 6 28 0 31.5 -78.8 tropical dep~ NA 25 1012
## 6 Amy 1975 6 28 6 32.4 -78.7 tropical dep~ NA 25 1012
## 7 Amy 1975 6 28 12 33.3 -78 tropical dep~ NA 25 1011
## 8 Amy 1975 6 28 18 34 -77 tropical dep~ NA 30 1006
## 9 Amy 1975 6 29 0 34.4 -75.8 tropical sto~ NA 35 1004
## 10 Amy 1975 6 29 6 34 -74.8 tropical sto~ NA 40 1002
## # ... with 354 more rows, 2 more variables: tropicalstorm_force_diameter <int>,
## # hurricane_force_diameter <int>, and abbreviated variable names 1: category,
## # 2: pressure
# outra forma
filter(storms, year %in% 1975:1976)
## # A tibble: 364 x 13
## name year month day hour lat long status categ~1 wind press~2
## <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <dbl> <int> <int>
## 1 Amy 1975 6 27 0 27.5 -79 tropical dep~ NA 25 1013
## 2 Amy 1975 6 27 6 28.5 -79 tropical dep~ NA 25 1013
## 3 Amy 1975 6 27 12 29.5 -79 tropical dep~ NA 25 1013
## 4 Amy 1975 6 27 18 30.5 -79 tropical dep~ NA 25 1013
## 5 Amy 1975 6 28 0 31.5 -78.8 tropical dep~ NA 25 1012
## 6 Amy 1975 6 28 6 32.4 -78.7 tropical dep~ NA 25 1012
## 7 Amy 1975 6 28 12 33.3 -78 tropical dep~ NA 25 1011
## 8 Amy 1975 6 28 18 34 -77 tropical dep~ NA 30 1006
## 9 Amy 1975 6 29 0 34.4 -75.8 tropical sto~ NA 35 1004
## 10 Amy 1975 6 29 6 34 -74.8 tropical sto~ NA 40 1002
## # ... with 354 more rows, 2 more variables: tropicalstorm_force_diameter <int>,
## # hurricane_force_diameter <int>, and abbreviated variable names 1: category,
## # 2: pressure
# outra forma
filter(storms, year < 1976)
## # A tibble: 238 x 13
## name year month day hour lat long status categ~1 wind press~2
## <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <dbl> <int> <int>
## 1 Amy 1975 6 27 0 27.5 -79 tropical dep~ NA 25 1013
## 2 Amy 1975 6 27 6 28.5 -79 tropical dep~ NA 25 1013
## 3 Amy 1975 6 27 12 29.5 -79 tropical dep~ NA 25 1013
## 4 Amy 1975 6 27 18 30.5 -79 tropical dep~ NA 25 1013
## 5 Amy 1975 6 28 0 31.5 -78.8 tropical dep~ NA 25 1012
## 6 Amy 1975 6 28 6 32.4 -78.7 tropical dep~ NA 25 1012
## 7 Amy 1975 6 28 12 33.3 -78 tropical dep~ NA 25 1011
## 8 Amy 1975 6 28 18 34 -77 tropical dep~ NA 30 1006
## 9 Amy 1975 6 29 0 34.4 -75.8 tropical sto~ NA 35 1004
## 10 Amy 1975 6 29 6 34 -74.8 tropical sto~ NA 40 1002
## # ... with 228 more rows, 2 more variables: tropicalstorm_force_diameter <int>,
## # hurricane_force_diameter <int>, and abbreviated variable names 1: category,
## # 2: pressureUsar uma condição considerando dois fatores (nome e ano)
filter(storms, year == 1975 & name == "Caroline")
## # A tibble: 33 x 13
## name year month day hour lat long status categ~1 wind press~2
## <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <dbl> <int> <int>
## 1 Caroline 1975 8 24 12 22.4 -69.8 tropical ~ NA 25 1011
## 2 Caroline 1975 8 24 18 21.9 -71.1 tropical ~ NA 25 1011
## 3 Caroline 1975 8 25 0 21.6 -72.5 tropical ~ NA 25 1010
## 4 Caroline 1975 8 25 6 21.2 -73.8 tropical ~ NA 25 1010
## 5 Caroline 1975 8 25 12 20.9 -75.1 tropical ~ NA 25 1011
## 6 Caroline 1975 8 25 18 20.6 -76.4 tropical ~ NA 25 1011
## 7 Caroline 1975 8 26 0 20.4 -77.7 tropical ~ NA 25 1011
## 8 Caroline 1975 8 26 6 20.3 -79 tropical ~ NA 25 1011
## 9 Caroline 1975 8 26 12 20.2 -80.3 tropical ~ NA 25 1012
## 10 Caroline 1975 8 26 18 20.2 -81.6 tropical ~ NA 25 1012
## # ... with 23 more rows, 2 more variables: tropicalstorm_force_diameter <int>,
## # hurricane_force_diameter <int>, and abbreviated variable names 1: category,
## # 2: pressure
filter(storms, name == "Caroline" & year == 1975)
## # A tibble: 33 x 13
## name year month day hour lat long status categ~1 wind press~2
## <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <fct> <dbl> <int> <int>
## 1 Caroline 1975 8 24 12 22.4 -69.8 tropical ~ NA 25 1011
## 2 Caroline 1975 8 24 18 21.9 -71.1 tropical ~ NA 25 1011
## 3 Caroline 1975 8 25 0 21.6 -72.5 tropical ~ NA 25 1010
## 4 Caroline 1975 8 25 6 21.2 -73.8 tropical ~ NA 25 1010
## 5 Caroline 1975 8 25 12 20.9 -75.1 tropical ~ NA 25 1011
## 6 Caroline 1975 8 25 18 20.6 -76.4 tropical ~ NA 25 1011
## 7 Caroline 1975 8 26 0 20.4 -77.7 tropical ~ NA 25 1011
## 8 Caroline 1975 8 26 6 20.3 -79 tropical ~ NA 25 1011
## 9 Caroline 1975 8 26 12 20.2 -80.3 tropical ~ NA 25 1012
## 10 Caroline 1975 8 26 18 20.2 -81.6 tropical ~ NA 25 1012
## # ... with 23 more rows, 2 more variables: tropicalstorm_force_diameter <int>,
## # hurricane_force_diameter <int>, and abbreviated variable names 1: category,
## # 2: pressureOperações de agrupamento (group_by())
Outra tarefa comum ao explorar dados tem a ver com cálculos aplicados a determinados grupos ou categorias de dados. “dplyr” fornece a função group_by() que recebe uma tabela de dados e especificamos a(s) coluna(s) nas quais as linhas serão agrupadas. Na maioria das vezes, você usará group_by() com a função summarise(), que como seu nome indica, permite que você calcule um determinado resumo nas colunas especificadas.
# calcular médias dos ventos e pressão para cada furacão
summarise(
group_by(storms75, name),
avg_wind = mean(wind),
avg_pressure = mean(pressure)
)
## # A tibble: 8 x 3
## name avg_wind avg_pressure
## <chr> <dbl> <dbl>
## 1 Amy 46.5 995.
## 2 Blanche 45 999.
## 3 Caroline 38.9 1002.
## 4 Doris 67.1 988.
## 5 Eloise 45 999.
## 6 Faye 68.4 988.
## 7 Gladys 66.3 986.
## 8 Hallie 34.6 1005.
# outra forma
avg_wind_pressure_75 <- summarise(
group_by(storms75, name),
avg_wind = mean(wind),
avg_pressure = mean(pressure)
)
avg_wind_pressure_75
## # A tibble: 8 x 3
## name avg_wind avg_pressure
## <chr> <dbl> <dbl>
## 1 Amy 46.5 995.
## 2 Blanche 45 999.
## 3 Caroline 38.9 1002.
## 4 Doris 67.1 988.
## 5 Eloise 45 999.
## 6 Faye 68.4 988.
## 7 Gladys 66.3 986.
## 8 Hallie 34.6 1005.Organizar operações (arrange())
Além das operações group_by(), outro tipo comum de manipulação é a organização de linhas com base nos valores de uma ou mais colunas. Em “dplyr”, isso pode ser facilmente obtido com a função arrange(). A maneira como essa função funciona é passando o nome da tabela e, em seguida, especificando uma ou mais colunas para ordenar as linhas com base em tais valores.
arrange(avg_wind_pressure_75, avg_wind)
## # A tibble: 8 x 3
## name avg_wind avg_pressure
## <chr> <dbl> <dbl>
## 1 Hallie 34.6 1005.
## 2 Caroline 38.9 1002.
## 3 Blanche 45 999.
## 4 Eloise 45 999.
## 5 Amy 46.5 995.
## 6 Gladys 66.3 986.
## 7 Doris 67.1 988.
## 8 Faye 68.4 988.
arrange(avg_wind_pressure_75, avg_pressure)
## # A tibble: 8 x 3
## name avg_wind avg_pressure
## <chr> <dbl> <dbl>
## 1 Gladys 66.3 986.
## 2 Faye 68.4 988.
## 3 Doris 67.1 988.
## 4 Amy 46.5 995.
## 5 Eloise 45 999.
## 6 Blanche 45 999.
## 7 Caroline 38.9 1002.
## 8 Hallie 34.6 1005.
arrange(avg_wind_pressure_75, desc(avg_wind))
## # A tibble: 8 x 3
## name avg_wind avg_pressure
## <chr> <dbl> <dbl>
## 1 Faye 68.4 988.
## 2 Doris 67.1 988.
## 3 Gladys 66.3 986.
## 4 Amy 46.5 995.
## 5 Blanche 45 999.
## 6 Eloise 45 999.
## 7 Caroline 38.9 1002.
## 8 Hallie 34.6 1005.