class: center, middle, inverse, title-slide # Limpando e trabalhando os dados ###
Renata Oliveira --- layout: true <div class="my-footer"> <span> <a href="https://places.education" target="_blank">https://places.education</a> </span> </div> --- class: center, middle ## Retrospecto --- ## Modelo conceitual da análise de dados ![Modelo de Data Science](https://retaoliveira.github.io/relements/figures/dataR.png) --- ## Tipos de dados - Os tipos de dados mais comuns são `character`, `numeric`, `factor`e `logical`. ## Tipos de classes de objetos no R - As classes de organização dos dados mais comuns são `vector`, `list`, `matrix` e `dataframe`. --- ## RMarkdown <img src="img/render.png" width="100%" style="display: block; margin: auto;" /> .footnote[ Alison Hill [Teaching in Production](https://rstudio-education.github.io/teaching-in-production/slides/index.html#1) ] --- ## Tidy data >As famílias infelizes são todas iguais; cada família infeliz é infeliz à sua própria maneira. > >Leo Tolstoy --- .pull-left[ **Características dos dados tidy:** - Cada variável forma uma coluna. - Cada observação forma uma linha. - Livre de linhas/colunas duplicadas. - Livre de erros de ortografia - Relevante (por exemplo, livre de caracteres especiais) - O tipo de dados apropriado para análise - Livre de outliers (ou só contém outliers que tenham sido identificados/entendidos), e ] -- .pull-right[ **Características dos dados untidy:** !@#$%^&*() ] --- ## .question[ O que faz com que estes dados não estejam arrumados? ] <img src="img/hyperwar-airplanes-on-hand.png" width="70%" style="display: block; margin: auto;" /> .footnote[ Source: [Army Air Forces Statistical Digest, WW II](https://www.ibiblio.org/hyperwar/AAF/StatDigest/aafsd-3.html) ] --- .question[ O que faz com que estes dados não estejam arrumados? ] <br> <img src="img/hiv-est-prevalence-15-49.png" width="70%" style="display: block; margin: auto;" /> .footnote[ Source: [Gapminder, Estimated HIV prevalence among 15-49 year olds](https://www.gapminder.org/data) ] --- .question[ O que faz com que estes dados não estejam arrumados? ] <br> <img src="img/us-general-economic-characteristic-acs-2017.png" width="85%" style="display: block; margin: auto;" /> .footnote[ Source: [US Census Fact Finder, General Economic Characteristics, ACS 2017](https://factfinder.census.gov/faces/tableservices/jsf/pages/productview.xhtml?pid=ACS_17_5YR_DP03&src=pt) ] --- ## Exibição vs. resumo de dados .panelset[ .panel[.panel-name[Saída] .pull-left[ ``` ## # A tibble: 87 x 3 ## name height mass ## <chr> <int> <dbl> ## 1 Luke Skywalker 172 77 ## 2 C-3PO 167 75 ## 3 R2-D2 96 32 ## 4 Darth Vader 202 136 ## 5 Leia Organa 150 49 ## 6 Owen Lars 178 120 ## # ... with 81 more rows ``` ] .pull-right[ ``` ## # A tibble: 3 x 2 ## gender avg_ht ## <chr> <dbl> ## 1 feminine 165. ## 2 masculine 177. ## 3 <NA> 181. ``` ] ] .panel[.panel-name[Código] .pull-left[ ```r starwars %>% select(name, height, mass) ``` ] .pull-right[ ```r starwars %>% group_by(gender) %>% summarize( avg_ht = mean(height, na.rm = TRUE) ) ``` ] ] ] --- class: middle # Gramática do data wrangling --- ## Gramática do data wrangling Com base nos conceitos de funções como verbos que permitem a manipulação de dataframes .pull-left[ <img src="img/dplyr-part-of-tidyverse.png" width="70%" style="display: block; margin: auto;" /> ] .pull-right[ .small[ - `select`: seleção de colunas pelo nome - `arrange`: reorganização das colunas - `slice`: seleção de linhas pelo index(es) - `filter`: seleção de linhas segundo algum critério - `distinct`: aplica um filtro para que não haja colunas duplicadas - `mutate`: adição de novas variáveis - `summarise`: redução de variáveis a valores - `group_by`: operações em agrupamentos - ... (many more) ] ] --- ## Regras das funções **dplyr** - O primeiro argumento é **sempre** um dataframe - Os argumentos subseqüentes dizem o que fazer com esse dataframe - A saída é sempre um dataframe - Não modifica os dados originais --- ## Dados: Reservas de hotéis - Dados de dois hotéis: um resort e um hotel urbano - Observações: Cada linha representa uma reserva de hotel - Objetivo para a coleta de dados originais: Desenvolvimento de modelos de previsão para classificar a probabilidade de uma reserva de hotel ser cancelada ([Antonia et al., 2019](https://www.sciencedirect.com/science/article/pii/S2352340918315191#bib5)) [Dados](https://cefetmgbr-my.sharepoint.com/:x:/g/personal/renataoliveira_cefetmg_br/EUrBw09_G6BAhuASz0wyAEwBCl_pm5aHc5Ok8m4oAilz8w?e=qieY4H) ```r library(readr) hotels <- read_csv("./data/hotels.csv") ``` .footnote[ Source: [TidyTuesday](https://github.com/rfordatascience/tidytuesday/blob/master/data/2020/2020-02-11/readme.md) ] --- ## Primeiro olhar: Variáveis .small[ ```r names(hotels) ``` ``` ## [1] "hotel" ## [2] "is_canceled" ## [3] "lead_time" ## [4] "arrival_date_year" ## [5] "arrival_date_month" ## [6] "arrival_date_week_number" ## [7] "arrival_date_day_of_month" ## [8] "stays_in_weekend_nights" ## [9] "stays_in_week_nights" ## [10] "adults" ## [11] "children" ## [12] "babies" ## [13] "meal" ## [14] "country" ## [15] "market_segment" ## [16] "distribution_channel" ## [17] "is_repeated_guest" ## [18] "previous_cancellations" ... ``` ] --- ## Segundo olhar: Visão geral .small[ ```r glimpse(hotels) ``` ``` ## Rows: 119,390 ## Columns: 32 ## $ hotel <chr> "Resort Hotel", "Resort ~ ## $ is_canceled <dbl> 0, 0, 0, 0, 0, 0, 0, 0, ~ ## $ lead_time <dbl> 342, 737, 7, 13, 14, 14,~ ## $ arrival_date_year <dbl> 2015, 2015, 2015, 2015, ~ ## $ arrival_date_month <chr> "July", "July", "July", ~ ## $ arrival_date_week_number <dbl> 27, 27, 27, 27, 27, 27, ~ ## $ arrival_date_day_of_month <dbl> 1, 1, 1, 1, 1, 1, 1, 1, ~ ## $ stays_in_weekend_nights <dbl> 0, 0, 0, 0, 0, 0, 0, 0, ~ ## $ stays_in_week_nights <dbl> 0, 0, 1, 1, 2, 2, 2, 2, ~ ## $ adults <dbl> 2, 2, 1, 1, 2, 2, 2, 2, ~ ## $ children <dbl> 0, 0, 0, 0, 0, 0, 0, 0, ~ ## $ babies <dbl> 0, 0, 0, 0, 0, 0, 0, 0, ~ ## $ meal <chr> "BB", "BB", "BB", "BB", ~ ## $ country <chr> "PRT", "PRT", "GBR", "GB~ ## $ market_segment <chr> "Direct", "Direct", "Dir~ ## $ distribution_channel <chr> "Direct", "Direct", "Dir~ ... ``` ] --- ## Selecione uma única coluna Ver apenas `lead_time` (número de dias entre a reserva e a data de chegada): ```r select(hotels, lead_time) ``` ``` ## # A tibble: 119,390 x 1 ## lead_time ## <dbl> ## 1 342 ## 2 737 ## 3 7 ## 4 13 ## 5 14 ## 6 14 ## # ... with 119,384 more rows ``` --- ## Selecione uma única coluna .pull-left[ ```r *select( hotels, lead_time ) ``` ] .pull-right[ - Comece com a função (um verbo): `select()` ] --- ## Selecione uma única coluna .pull-left[ ```r select( * hotels, lead_time ) ``` ] .pull-right[ - Comece com a função (um verbo): `select()` - Primeiro argumento: dataframe com o qual estamos trabalhando, `hotels`. ] --- ## Select a single column .pull-left[ ```r select( hotels, * lead_time ) ``` ] .pull-right[ .pull-right[ - Comece com a função (um verbo): `select()` - Primeiro argumento: dataframe com o qual estamos trabalhando, `hotels`. - Segundo argumento: variável que queremos acessar, `lead_time` ] --- ## Select a single column .pull-left[ ```r select( hotels, lead_time ) ``` ``` ## # A tibble: 119,390 x 1 ## lead_time ## <dbl> ## 1 342 ## 2 737 ## 3 7 ## 4 13 ## 5 14 ## 6 14 ## # ... with 119,384 more rows ``` ] .pull-right[ - Comece com a função (um verbo): `select()` - Primeiro argumento: dataframe com o qual estamos trabalhando, `hotels`. - Segundo argumento: variável que queremos acessar, `lead_time` - Resultado: data frame com 119390 linhas e 1 coluna ] --- .tip[ dplyr funções precisam de um data frame como entrada e entregam um data frame. ] ```r select(hotels, lead_time) ``` ``` ## # A tibble: 119,390 x 1 ## lead_time ## <dbl> ## 1 342 ## 2 737 ## 3 7 ## 4 13 ## 5 14 ## 6 14 ## # ... with 119,384 more rows ``` --- ## Selecione várias colunas Veja apenas o tipo de `hotel` e o `lead_time`: -- .pull-left[ ```r select(hotels, hotel, lead_time) ``` ``` ## # A tibble: 119,390 x 2 ## hotel lead_time ## <chr> <dbl> ## 1 Resort Hotel 342 ## 2 Resort Hotel 737 ## 3 Resort Hotel 7 ## 4 Resort Hotel 13 ## 5 Resort Hotel 14 ## 6 Resort Hotel 14 ## # ... with 119,384 more rows ``` ] -- .pull-right[ .question[ E se quiséssemos selecionar estas colunas, e depois organizar os dados em ordem decrescente conforme data? ] ] --- ## Data wrangling, passo-a-passo .pull-left[ Selecione: ```r hotels %>% select(hotel, lead_time) ``` ``` ## # A tibble: 119,390 x 2 ## hotel lead_time ## <chr> <dbl> ## 1 Resort Hotel 342 ## 2 Resort Hotel 737 ## 3 Resort Hotel 7 ## 4 Resort Hotel 13 ## 5 Resort Hotel 14 ## 6 Resort Hotel 14 ## # ... with 119,384 more rows ``` ] -- .pull-right[ Selecione, depois organize: ```r hotels %>% select(hotel, lead_time) %>% arrange(desc(lead_time)) ``` ``` ## # A tibble: 119,390 x 2 ## hotel lead_time ## <chr> <dbl> ## 1 Resort Hotel 737 ## 2 Resort Hotel 709 ## 3 City Hotel 629 ## 4 City Hotel 629 ## 5 City Hotel 629 ## 6 City Hotel 629 ## # ... with 119,384 more rows ``` ] --- class: middle # Pipes --- ## O que é um pipe? Na programação, `pipe` é uma técnica para passar informações de um processo para outro. -- .pull-left[ - Comece com o dataframe `hotels`, e utilize a função `select()`, ] .pull-right[ .small[ ```r *hotels %>% select(hotel, lead_time) %>% arrange(desc(lead_time)) ``` ``` ## # A tibble: 119,390 x 2 ## hotel lead_time ## <chr> <dbl> ## 1 Resort Hotel 737 ## 2 Resort Hotel 709 ## 3 City Hotel 629 ## 4 City Hotel 629 ## 5 City Hotel 629 ## 6 City Hotel 629 ## # ... with 119,384 more rows ``` ] ] --- ## O que é um pipe? Na programação, `pipe` é uma técnica para passar informações de um processo para outro. .pull-left[ - Comece com o dataframe `hotels`, e utilize a função `select()`, - e então, selecione `hotel` and `lead_time`, ] .pull-right[ .small[ ```r hotels %>% * select(hotel, lead_time) %>% arrange(desc(lead_time)) ``` ``` ## # A tibble: 119,390 x 2 ## hotel lead_time ## <chr> <dbl> ## 1 Resort Hotel 737 ## 2 Resort Hotel 709 ## 3 City Hotel 629 ## 4 City Hotel 629 ## 5 City Hotel 629 ## 6 City Hotel 629 ## # ... with 119,384 more rows ``` ] ] --- ## O que é um pipe? Na programação, `pipe` é uma técnica para passar informações de um processo para outro. .pull-left[ - Comece com o dataframe `hotels`, e utilize a função `select()`, - e então, selecione `hotel` and `lead_time`, - e então, organize de maneira decrescente conforme o `lead_time`. ] .pull-right[ .small[ ```r hotels %>% select(hotel, lead_time) %>% * arrange(desc(lead_time)) ``` ``` ## # A tibble: 119,390 x 2 ## hotel lead_time ## <chr> <dbl> ## 1 Resort Hotel 737 ## 2 Resort Hotel 709 ## 3 City Hotel 629 ## 4 City Hotel 629 ## 5 City Hotel 629 ## 6 City Hotel 629 ## # ... with 119,384 more rows ``` ] ] --- ## Além O pipe é implementado no pacote **magrittr**, embora não precisemos carregar este pacote explicitamente, pois **tidyverse** faz isto por nós. -- .question[ Algum palpite sobre o porquê do pacote ser chamado de magrittr? ] -- .pull-left[ <img src="img/magritte.jpg" width="90%" style="display: block; margin: auto;" /> ] .pull-right[ <img src="img/magrittr.jpg" width="100%" style="display: block; margin: auto;" /> ] --- ## Como funciona o pipe? - Você pode pensar na seguinte seqüência de ações - encontrar chaves, destravar o carro, ligar o carro, dirigir para o trabalho, estacionar. -- - Expresso como um conjunto de funções aninhadas no pseudo-código R, isto pareceria: ```r park(drive(start_car(find("keys")), to = "work")) ``` -- - Escrevê-lo usando pipes dá-lhe uma estrutura mais natural (e mais fácil de ler): ```r find("keys") %>% start_car() %>% drive(to = "work") %>% park() ``` --- ## Uma nota sobre pipes e estratificação - utilizado principalmente em **dplyr** pipelines, *canalizamos a saída da linha de código anterior como a primeira entrada da próxima linha de código*. -- - O `+` utilizado em **ggplot2** é utilizado para "estratificação", *criamos a parcela em camadas, separadas por `+`* --- ## dplyr .midi[ ❌ ```r hotels + select(hotel, lead_time) ``` ``` ## Error in select(hotel, lead_time): objeto 'hotel' não encontrado ``` ✅ ```r hotels %>% select(hotel, lead_time) ``` .midi[ ``` ## # A tibble: 119,390 x 2 ## hotel lead_time ## <chr> <dbl> ## 1 Resort Hotel 342 ## 2 Resort Hotel 737 ## 3 Resort Hotel 7 ... ``` ] ] --- ## ggplot2 .midi[ ❌ ```r ggplot(hotels, aes(x = hotel, fill = deposit_type)) %>% geom_bar() ``` ``` ## Error in `validate_mapping()`: ## ! `mapping` must be created by `aes()` ## Did you use %>% instead of +? ``` ✅ ```r ggplot(hotels, aes(x = hotel, fill = deposit_type)) + geom_bar() ``` <img src="index_files/figure-html/unnamed-chunk-28-1.png" width="25%" style="display: block; margin: auto;" /> ] --- ## Estilo de código Muitos dos princípios de estilo são consistentes entre `%>%` e `+`: - sempre um espaço antes - sempre uma quebra de linha depois (para dutos com mais de 2 linhas) ❌ ```r ggplot(hotels,aes(x=hotel,y=deposit_type))+geom_bar() ``` ✅ ```r ggplot(hotels, aes(x = hotel, y = deposit_type)) + geom_bar() ```