Esse material foi desenvolvido para o primeiro meetup (online) da R-Ladies de Ribeirão Preto (@RLadiesRP). As instruções nesse documento são baseadas, em parte, nas postagens de Jeff Leek chamada “Organizing a data analysis” e de Jenny Bryan chamada “Project-oriented workflow”.
Os objetivos desse workshop são:
Identificar as vantagens de um projeto be organizado
Desenvolver um estilo de programação, including nomeação consistente (i.e., não variável) de arquivos e pastas
Diferenciar entre processo e produto da análise de dados
Apesar de R ter seu próprio ambiente de desenvolvimento integrado (IDE - integrated development environment), RStudio é amplamente adotado como a IDE preferida de muitos cientistas de dados. Os motivos para tanto são muitos. Em geral, o propósito de uma IDE é facilitar o processo de escrever código oferencendo um ambiente que integra um editor de texto (onde o código é escrito e editado), o console (onde o código é rodado), e outras ferramentas de supporte.
Por que usar RStudio?
O IDE que o RStudio oferece facilita o processo de análise de dados, porque contain as seguintes features:
RStudio é gratuíto e open source.
O editor do RStudio é completamente integrado no IDE, com auto preenchimento (tab-completion)
RStudio é igual não importa qual plataforma você usa (Windows, Linux, Mac, Cloud)
É possivel criar Projects com RStudio que facilitam a organização de projetos de análise de dados
Instruções de instalação do R e do RStudio:
Baixe e instale R do site https://cran.r-project.org (Se você usa Windows, primeiro determine se você tem Windows de 32 ou 64 bits)
Baixe e instale RStudio do site https://rstudio.com/products/rstudio/download/#download
Uma pergunta comum é com que frequência se deve atualizar o R e o RStudio. É importante ter sempre a última versão de R, RStudio, e seus pacotes de R, para garantir que se código não tenha nenhum erros.
Abra seu RStudio
No console, entre sessionInfo()
para verificar sua versão de R e seu sistema operacional
No menu do seu RStudio, click em Tools/Ferramentas
e escolha Check for Packages Updates...
pra verificar se existe alguma atualização disponível pra pacotes que você tem instalado no seu computador
O principal motivo pra organizar um projeto de análise de dados é reprodutibilidade. Já acontenceu de você ter que abrir um script de R para re-rodar uma análise e você ter que passar um tempo tentando entender o que você mesmo fez seis meses atrás? Pois é, seja gentil com você mesmo, e organize seus projetos pra que no futuro você possa recriar seus resultados com sucesso.
Além disso, se todos os colaboradores de um projeto tem as mesmas expectativas de organização, a colaboração se torna um processo mais fácil e sua análise fica mais robusta (menores chances de erros). Nos EUA, pesquisadores estão cada vez mais disponibilizando seus códigos e dados de suas análises para ajudar com estudos de replicação e transparência em geral. Em alguns anos, será esperado esse tipo de transparência na maioria de publicações científicas sérias.
Vamos usar dados de eBird Brazilian Birdwatching Observations retirados do Kgggle.
Crie uma pasta chamada raw_data
dentro de seu Projeto. Mova e renomeie o arquivo que você baixou do Kaggle pra essa pasta.
Crie um novo R script com o nome de 01-data_wrangling.R
.
Certifique-se de que seu projeto consegue “ver” o arquivo de dados.
# check work environment
getwd()
## [1] "/Users/adriana/Desktop/workshops/organizando_projeto"
# list contents of current folder
dir()
## [1] "figures" "index.html"
## [3] "index.Rmd" "organizando_projeto.Rproj"
## [5] "processed_data" "raw_data"
## [7] "test.pdf" "test.Rmd"
list.files()
## [1] "figures" "index.html"
## [3] "index.Rmd" "organizando_projeto.Rproj"
## [5] "processed_data" "raw_data"
## [7] "test.pdf" "test.Rmd"
# list contents of raw_data folder
dir("raw_data")
## [1] "ebird_brazil.csv"
list.files("raw_data")
## [1] "ebird_brazil.csv"
Antes de começarmos, precisamos dos seguintes pacotes de R.
install.packages("tidyverse")
install.packages("janitor")
install.packages("skimr")
Depois de instalar/atualizar os pacotes tidyverse
, é necessário carregar esses pacotes com a função library()
.
# load libraries
library(tidyverse)
## ── Attaching packages ───────────────────────────────────────────────────────────────── tidyverse 1.3.0 ──
## ✓ ggplot2 3.3.2 ✓ purrr 0.3.4
## ✓ tibble 3.0.3 ✓ dplyr 1.0.2
## ✓ tidyr 1.1.2 ✓ stringr 1.4.0
## ✓ readr 1.3.1 ✓ forcats 0.5.0
## ── Conflicts ──────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
library(janitor)
##
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
##
## chisq.test, fisher.test
library(skimr)
Existem muitas funções que lêem dados no R, minha preferida é a família read_csv()
, read_tsv()
, etc.
# read data in
bird_data <- read_tsv("raw_data/ebird_brazil.csv")
## Parsed with column specification:
## cols(
## .default = col_character(),
## gbifID = col_double(),
## infraspecificEpithet = col_logical(),
## verbatimScientificNameAuthorship = col_logical(),
## occurrenceStatus = col_logical(),
## individualCount = col_double(),
## decimalLatitude = col_double(),
## decimalLongitude = col_double(),
## coordinateUncertaintyInMeters = col_logical(),
## coordinatePrecision = col_logical(),
## elevation = col_logical(),
## elevationAccuracy = col_logical(),
## depth = col_logical(),
## depthAccuracy = col_logical(),
## eventDate = col_datetime(format = ""),
## day = col_double(),
## month = col_double(),
## year = col_double(),
## taxonKey = col_double(),
## speciesKey = col_double(),
## recordNumber = col_logical()
## # ... with 7 more columns
## )
## See spec(...) for full column specifications.
## Warning: 276 parsing failures.
## row col expected actual file
## 438282 locality delimiter or quote , 'raw_data/ebird_brazil.csv'
## 438282 locality delimiter or quote J 'raw_data/ebird_brazil.csv'
## 438282 locality delimiter or quote , 'raw_data/ebird_brazil.csv'
## 438282 locality delimiter or quote J 'raw_data/ebird_brazil.csv'
## 438282 locality delimiter or quote , 'raw_data/ebird_brazil.csv'
## ...... ........ .................. ...... ...........................
## See problems(...) for more details.
Sempre inspecione seus dados.
# inspect data
glimpse(bird_data)
## Rows: 3,587,953
## Columns: 50
## $ gbifID <dbl> 181559517, 181560025, 181560303, 181…
## $ datasetKey <chr> "4fa7b334-ce0d-4e88-aaae-2e0c138d049…
## $ occurrenceID <chr> "URN:catalog:CLO:EBIRD:OBS54999031",…
## $ kingdom <chr> "Animalia", "Animalia", "Animalia", …
## $ phylum <chr> "Chordata", "Chordata", "Chordata", …
## $ class <chr> "Aves", "Aves", "Aves", "Aves", "Ave…
## $ order <chr> "Passeriformes", "Passeriformes", "P…
## $ family <chr> "Icteridae", "Icteridae", "Icteridae…
## $ genus <chr> "Molothrus", "Molothrus", "Molothrus…
## $ species <chr> "Molothrus bonariensis", "Molothrus …
## $ infraspecificEpithet <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ taxonRank <chr> "SPECIES", "SPECIES", "SPECIES", "SP…
## $ scientificName <chr> "Molothrus bonariensis (Gmelin, 1789…
## $ verbatimScientificName <chr> "Molothrus bonariensis", "Molothrus …
## $ verbatimScientificNameAuthorship <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ countryCode <chr> "BR", "BR", "BR", "BR", "BR", "BR", …
## $ locality <chr> "PN do Iguaçu", "Foz do Iguazu and P…
## $ stateProvince <chr> "Paraná", "Paraná", "Goiás", "Goiás"…
## $ occurrenceStatus <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ individualCount <dbl> 1, 1, 1, 1, 2, NA, 4, NA, NA, NA, NA…
## $ publishingOrgKey <chr> "e2e717bf-551a-4917-bdc9-4fa0f342c53…
## $ decimalLatitude <dbl> -25.642455, -25.584063, -18.260979, …
## $ decimalLongitude <dbl> -54.43829, -54.58131, -52.88840, -52…
## $ coordinateUncertaintyInMeters <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ coordinatePrecision <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ elevation <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ elevationAccuracy <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ depth <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ depthAccuracy <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ eventDate <dttm> 2006-10-17, 2006-10-19, 2006-10-25,…
## $ day <dbl> 17, 19, 25, 26, 27, 26, 11, 21, 22, …
## $ month <dbl> 10, 10, 10, 10, 10, 7, 8, 7, 7, 4, 4…
## $ year <dbl> 2006, 2006, 2006, 2006, 2006, 2001, …
## $ taxonKey <dbl> 2484396, 2484396, 2484396, 2484396, …
## $ speciesKey <dbl> 2484396, 2484396, 2484396, 2484396, …
## $ basisOfRecord <chr> "HUMAN_OBSERVATION", "HUMAN_OBSERVAT…
## $ institutionCode <chr> "CLO", "CLO", "CLO", "CLO", "CLO", "…
## $ collectionCode <chr> "EBIRD", "EBIRD", "EBIRD", "EBIRD", …
## $ catalogNumber <chr> "OBS54999031", "OBS55048662", "OBS55…
## $ recordNumber <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ identifiedBy <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ dateIdentified <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ license <chr> "CC0_1_0", "CC0_1_0", "CC0_1_0", "CC…
## $ rightsHolder <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ recordedBy <chr> "obsr16810", "obsr16810", "obsr16810…
## $ typeStatus <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ establishmentMeans <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ lastInterpreted <dttm> 2019-09-20 22:54:20, 2019-09-20 22:…
## $ mediaType <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, …
## $ issue <chr> "COORDINATE_ROUNDED", "COORDINATE_RO…
Os nomes das colunas estão em camelCase, a minha preferência pessoal é snake_case. A função clean_names()
, cujo default é “snake”.
# standardize column names to snake_case
bird_data <- bird_data %>%
clean_names()
Sempre cheque seus dados pra verificar se as mudanças tiveram efeito.
# inspect data
glimpse(bird_data)
## Rows: 3,587,953
## Columns: 50
## $ gbif_id <dbl> 181559517, 181560025, 181560303, …
## $ dataset_key <chr> "4fa7b334-ce0d-4e88-aaae-2e0c138d…
## $ occurrence_id <chr> "URN:catalog:CLO:EBIRD:OBS5499903…
## $ kingdom <chr> "Animalia", "Animalia", "Animalia…
## $ phylum <chr> "Chordata", "Chordata", "Chordata…
## $ class <chr> "Aves", "Aves", "Aves", "Aves", "…
## $ order <chr> "Passeriformes", "Passeriformes",…
## $ family <chr> "Icteridae", "Icteridae", "Icteri…
## $ genus <chr> "Molothrus", "Molothrus", "Moloth…
## $ species <chr> "Molothrus bonariensis", "Molothr…
## $ infraspecific_epithet <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ taxon_rank <chr> "SPECIES", "SPECIES", "SPECIES", …
## $ scientific_name <chr> "Molothrus bonariensis (Gmelin, 1…
## $ verbatim_scientific_name <chr> "Molothrus bonariensis", "Molothr…
## $ verbatim_scientific_name_authorship <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ country_code <chr> "BR", "BR", "BR", "BR", "BR", "BR…
## $ locality <chr> "PN do Iguaçu", "Foz do Iguazu an…
## $ state_province <chr> "Paraná", "Paraná", "Goiás", "Goi…
## $ occurrence_status <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ individual_count <dbl> 1, 1, 1, 1, 2, NA, 4, NA, NA, NA,…
## $ publishing_org_key <chr> "e2e717bf-551a-4917-bdc9-4fa0f342…
## $ decimal_latitude <dbl> -25.642455, -25.584063, -18.26097…
## $ decimal_longitude <dbl> -54.43829, -54.58131, -52.88840, …
## $ coordinate_uncertainty_in_meters <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ coordinate_precision <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ elevation <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ elevation_accuracy <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ depth <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ depth_accuracy <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ event_date <dttm> 2006-10-17, 2006-10-19, 2006-10-…
## $ day <dbl> 17, 19, 25, 26, 27, 26, 11, 21, 2…
## $ month <dbl> 10, 10, 10, 10, 10, 7, 8, 7, 7, 4…
## $ year <dbl> 2006, 2006, 2006, 2006, 2006, 200…
## $ taxon_key <dbl> 2484396, 2484396, 2484396, 248439…
## $ species_key <dbl> 2484396, 2484396, 2484396, 248439…
## $ basis_of_record <chr> "HUMAN_OBSERVATION", "HUMAN_OBSER…
## $ institution_code <chr> "CLO", "CLO", "CLO", "CLO", "CLO"…
## $ collection_code <chr> "EBIRD", "EBIRD", "EBIRD", "EBIRD…
## $ catalog_number <chr> "OBS54999031", "OBS55048662", "OB…
## $ record_number <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ identified_by <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ date_identified <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ license <chr> "CC0_1_0", "CC0_1_0", "CC0_1_0", …
## $ rights_holder <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ recorded_by <chr> "obsr16810", "obsr16810", "obsr16…
## $ type_status <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ establishment_means <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ last_interpreted <dttm> 2019-09-20 22:54:20, 2019-09-20 …
## $ media_type <lgl> NA, NA, NA, NA, NA, NA, NA, NA, N…
## $ issue <chr> "COORDINATE_ROUNDED", "COORDINATE…
skim(bird_data)
Name | bird_data |
Number of rows | 3587953 |
Number of columns | 50 |
_______________________ | |
Column type frequency: | |
character | 23 |
logical | 16 |
numeric | 9 |
POSIXct | 2 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
dataset_key | 0 | 1.00 | 36 | 36 | 0 | 1 | 0 |
occurrence_id | 0 | 1.00 | 33 | 43 | 0 | 3587953 | 0 |
kingdom | 0 | 1.00 | 8 | 8 | 0 | 1 | 0 |
phylum | 0 | 1.00 | 8 | 8 | 0 | 1 | 0 |
class | 0 | 1.00 | 4 | 4 | 0 | 1 | 0 |
order | 0 | 1.00 | 10 | 19 | 0 | 29 | 0 |
family | 0 | 1.00 | 7 | 17 | 0 | 87 | 0 |
genus | 170 | 1.00 | 3 | 16 | 0 | 661 | 0 |
species | 16621 | 1.00 | 9 | 33 | 0 | 1661 | 0 |
taxon_rank | 0 | 1.00 | 5 | 7 | 0 | 3 | 0 |
scientific_name | 0 | 1.00 | 11 | 83 | 0 | 1682 | 0 |
verbatim_scientific_name | 0 | 1.00 | 9 | 33 | 0 | 1687 | 0 |
country_code | 0 | 1.00 | 2 | 2 | 0 | 1 | 0 |
locality | 0 | 1.00 | 1 | 58590386 | 0 | 35367 | 0 |
state_province | 0 | 1.00 | 4 | 19 | 0 | 27 | 0 |
publishing_org_key | 0 | 1.00 | 36 | 36 | 0 | 1 | 0 |
basis_of_record | 0 | 1.00 | 17 | 17 | 0 | 1 | 0 |
institution_code | 0 | 1.00 | 3 | 3 | 0 | 1 | 0 |
collection_code | 0 | 1.00 | 5 | 14 | 0 | 28 | 0 |
catalog_number | 0 | 1.00 | 11 | 12 | 0 | 3587953 | 0 |
license | 0 | 1.00 | 7 | 7 | 0 | 1 | 0 |
recorded_by | 0 | 1.00 | 8 | 11 | 0 | 4380 | 0 |
issue | 759244 | 0.79 | 17 | 41 | 0 | 5 | 0 |
Variable type: logical
skim_variable | n_missing | complete_rate | mean | count |
---|---|---|---|---|
infraspecific_epithet | 3587953 | 0 | NaN | : |
verbatim_scientific_name_authorship | 3587953 | 0 | NaN | : |
occurrence_status | 3587953 | 0 | NaN | : |
coordinate_uncertainty_in_meters | 3587953 | 0 | NaN | : |
coordinate_precision | 3587953 | 0 | NaN | : |
elevation | 3587953 | 0 | NaN | : |
elevation_accuracy | 3587953 | 0 | NaN | : |
depth | 3587953 | 0 | NaN | : |
depth_accuracy | 3587953 | 0 | NaN | : |
record_number | 3587953 | 0 | NaN | : |
identified_by | 3587953 | 0 | NaN | : |
date_identified | 3587953 | 0 | NaN | : |
rights_holder | 3587953 | 0 | NaN | : |
type_status | 3587953 | 0 | NaN | : |
establishment_means | 3587953 | 0 | NaN | : |
media_type | 3587953 | 0 | NaN | : |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
gbif_id | 0 | 1.00 | 1813228035.28 | 431160839.15 | 145802518.00 | 1404613188.00 | 2056711849.00 | 2153281655.00 | 2234213761.00 | ▁▁▂▃▇ |
individual_count | 807329 | 0.77 | 4.18 | 84.33 | 1.00 | 1.00 | 2.00 | 3.00 | 100000.00 | ▇▁▁▁▁ |
decimal_latitude | 0 | 1.00 | -17.90 | 7.83 | -35.01 | -23.44 | -20.91 | -12.14 | 4.50 | ▁▇▃▂▁ |
decimal_longitude | 0 | 1.00 | -49.35 | 6.27 | -73.67 | -55.91 | -48.08 | -45.13 | -30.02 | ▁▃▇▇▁ |
day | 0 | 1.00 | 15.55 | 8.62 | 1.00 | 8.00 | 15.00 | 23.00 | 31.00 | ▇▇▇▇▆ |
month | 0 | 1.00 | 7.35 | 3.08 | 1.00 | 5.00 | 8.00 | 10.00 | 12.00 | ▃▃▅▆▇ |
year | 0 | 1.00 | 2014.82 | 4.95 | 1821.00 | 2015.00 | 2017.00 | 2018.00 | 2018.00 | ▁▁▁▁▇ |
taxon_key | 0 | 1.00 | 3485101.83 | 1836972.64 | 5286.00 | 2482675.00 | 2488622.00 | 5228629.00 | 9819034.00 | ▁▇▂▁▁ |
species_key | 16621 | 1.00 | 3376727.66 | 1717728.62 | 2474332.00 | 2482212.00 | 2488572.00 | 2498402.00 | 9819034.00 | ▇▂▁▁▁ |
Variable type: POSIXct
skim_variable | n_missing | complete_rate | min | max | median | n_unique |
---|---|---|---|---|---|---|
event_date | 0 | 1 | 1821-09-01 00:00:00 | 2018-12-31 00:00:00 | 2017-01-04 00:00:00 | 8654 |
last_interpreted | 0 | 1 | 2019-09-20 14:59:53 | 2019-09-21 04:27:35 | 2019-09-20 22:51:19 | 1575926 |
Nesse ponto, você pode decidir que variáveis manter na sua análise inicial. Use select()
para selecionar variáveis.
bird_data_narrower <- bird_data %>%
select(occurrence_id, order, family, taxon_rank:verbatim_scientific_name,
locality, state_province, recorded_by, event_date:year)
Sempre cheque seus dados pra verificar se as mudanças tiveram efeito.
# inspect data
skim(bird_data_narrower)
Name | bird_data_narrower |
Number of rows | 3587953 |
Number of columns | 13 |
_______________________ | |
Column type frequency: | |
character | 9 |
numeric | 3 |
POSIXct | 1 |
________________________ | |
Group variables | None |
Variable type: character
skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
---|---|---|---|---|---|---|---|
occurrence_id | 0 | 1 | 33 | 43 | 0 | 3587953 | 0 |
order | 0 | 1 | 10 | 19 | 0 | 29 | 0 |
family | 0 | 1 | 7 | 17 | 0 | 87 | 0 |
taxon_rank | 0 | 1 | 5 | 7 | 0 | 3 | 0 |
scientific_name | 0 | 1 | 11 | 83 | 0 | 1682 | 0 |
verbatim_scientific_name | 0 | 1 | 9 | 33 | 0 | 1687 | 0 |
locality | 0 | 1 | 1 | 58590386 | 0 | 35367 | 0 |
state_province | 0 | 1 | 4 | 19 | 0 | 27 | 0 |
recorded_by | 0 | 1 | 8 | 11 | 0 | 4380 | 0 |
Variable type: numeric
skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
---|---|---|---|---|---|---|---|---|---|---|
day | 0 | 1 | 15.55 | 8.62 | 1 | 8 | 15 | 23 | 31 | ▇▇▇▇▆ |
month | 0 | 1 | 7.35 | 3.08 | 1 | 5 | 8 | 10 | 12 | ▃▃▅▆▇ |
year | 0 | 1 | 2014.82 | 4.95 | 1821 | 2015 | 2017 | 2018 | 2018 | ▁▁▁▁▇ |
Variable type: POSIXct
skim_variable | n_missing | complete_rate | min | max | median | n_unique |
---|---|---|---|---|---|---|
event_date | 0 | 1 | 1821-09-01 | 2018-12-31 | 2017-01-04 | 8654 |
Agora que temos um data frame menor, fica mais fácil focar na análise. Vamos salvar esses dados em um novo arquivo em uma pasta chamada processed_data
.
# save data to disk
write_csv(bird_data_narrower, "processed_data/bird_data_narrower.csv")
No começo do segundo arquivo, com a análise de dados inicial, eu preparo o script pra ser rodado sem ter a necessidade de rodar o primeiro script (01-data_wrangling.R
).
# load libraries
library(tidyverse)
# read data in
bird_data_narrower <- read_csv("processed_data/bird_data_narrower.csv")
Geralmente contagens em geral é uma boa maneira de explorar seus dados.
# how many observations per year
bird_data_narrower %>%
count(year)
## # A tibble: 48 x 2
## year n
## <dbl> <int>
## 1 1821 2
## 2 1964 3
## 3 1965 8
## 4 1973 94
## 5 1974 159
## 6 1975 291
## 7 1977 112
## 8 1978 1098
## 9 1979 435
## 10 1980 84
## # … with 38 more rows
# plot the count above
bird_data_narrower %>%
count(year) %>%
ggplot(aes(x = year, y = n)) +
geom_point()
Pelo plot acima, podemos filtrar os dados por ano maior que 1950
# plot the count above
bird_data_narrower %>%
filter(year > 1950) %>%
count(year) %>%
ggplot(aes(x = year, y = n)) +
geom_point()
E por estado, o que temos?
# how many observations per state
bird_data_narrower %>%
count(state_province) %>%
ggplot(aes(y = reorder(state_province, n),
x = n)) +
geom_col()
# save plot in figures folder
ggsave("figures/observations_per_state.png")
## Saving 7 x 5 in image
Looks good.
# how many observations per taxon_rank and verbatim_scientific_name
bird_data_narrower %>%
distinct(taxon_rank, verbatim_scientific_name) %>%
count(taxon_rank) %>%
arrange(-n)
## # A tibble: 3 x 2
## taxon_rank n
## <chr> <int>
## 1 SPECIES 1676
## 2 GENUS 10
## 3 FAMILY 1
# what's in GENUS?
bird_data_narrower %>%
filter(taxon_rank == "GENUS") %>%
count(verbatim_scientific_name)
## # A tibble: 10 x 2
## verbatim_scientific_name n
## <chr> <int>
## 1 Celeus ochraceus 1040
## 2 Dryobates affinis 1947
## 3 Dryobates cassini 537
## 4 Dryobates maculifrons 1181
## 5 Dryobates mixtus 194
## 6 Dryobates passerinus 5593
## 7 Dryobates spilogaster 5470
## 8 Machaeropterus striolatus 13
## 9 Myrmoborus lophotes 58
## 10 Myrmothera subcanescens 418
# what's in FAMILY?
bird_data_narrower %>%
filter(taxon_rank == "FAMILY") %>%
count(verbatim_scientific_name)
## # A tibble: 1 x 2
## verbatim_scientific_name n
## <chr> <int>
## 1 Oneillornis salvini 170
Depois de explorar os dados, decida o que manter.
# save clean/filtered data
bird_data_narrower %>%
filter(year > 1950) %>%
write_csv("processed_data/bird_data_clean.csv")
Para relatórios, R Markdown permite a integração de prosa e código R no mesmo arquivo. É possível construir relatórios em HTML (como essa página que você está lendo) sem instalar nenhum software ou pacote extra. Para relatórios em pdf, é necessário instalar o pacote TinyText
.
install.packages("tinytext")
tinytex::install_tinytex()
Algumas coisas para considerar. Primeiro, formatação de texto:
# A level-one heading
## A level-two heading
### A level-two heading
*italics* or _italics_
**bold** or __bold__
`code`
[link description](http://webaddress.com)
- bullet list item
* bullet list item
1. numbered list item
1. second numbered list item (numbers are incremented automatically in the output)
> A block quote.
>
> > A block quote within a block quote.
Você pode acessar a R Markdown Cheat Sheet clicando em Help
e depois Cheatsheets
.
Segunda coisa a considerar é code chunk options
:
include = FALSE/TRUE: define se os resultados aparecem no documento final. O R Markdown executa o código, independentemente do booleano, e os resultados podem ser usados por outros chunks.
echo = FALSE/TRUE: define se o código, mas não os resultados, aparecerá no documento final.
message = FALSE/TRUE: define se as mensagens geradas pelo código aparecem no documento final.
warning = FALSE/TRUE: define se as mensagens de aviso geradas pelo código aparecem no documento final.
# read in clean/filtered data
bird_data_clear <- read_csv("processed_data/bird_data_clean.csv")
## Parsed with column specification:
## cols(
## occurrence_id = col_character(),
## order = col_character(),
## family = col_character(),
## taxon_rank = col_character(),
## scientific_name = col_character(),
## verbatim_scientific_name = col_character(),
## locality = col_character(),
## state_province = col_character(),
## recorded_by = col_character(),
## event_date = col_datetime(format = ""),
## day = col_double(),
## month = col_double(),
## year = col_double()
## )
Um estilo de programação refere-se a como você nomeia seus objetos e funções, como você comenta seu código, como você usa espaçamento, etc. Se seu estilo de codificação for consistente, seu código será mais fácil de ler e depurar no futuro. Aqui estão alguns guias para que você possa desenvolver seu próprio estilo de codificação:
Meu livro favorito de R para ciência de dados é gratuíto e está disponível online: