forked from paulofelipe/livro_intro_r
-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy path05-limpando_dados.Rmd
executable file
·226 lines (145 loc) · 9.1 KB
/
05-limpando_dados.Rmd
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# Limpando dados
No dia a dia de quem trabalha com dados, infelizmente, é muito comum se deparar com dados formatados de um jeito bastante complicado de se manipular. Isso acontece pois a forma de se trabalhar com dados é muito diferente da forma de se apresentar ou visualizar dados. Resumindo: "olhar" dados requer uma estrutura bem diferente de "mexer" com dados. Limpeza de dados também é considerada parte da manipulação de dados.
## O formato "ideal" dos dados
É importante entender um pouco mais sobre como os dados podem ser estruturados antes de entrarmos nas funções de limpeza. O formato ideal para analisar dados, visualmente, é diferente do formato ideal para analisá-los de forma sistemática. Observe as duas tabelas a seguir:
```{r 05-limpando-dados-1, echo=FALSE, fig.cap='Tabela wide'}
knitr::include_graphics("imagens/dados_wide.png")
```
```{r 05-limpando-dados-2, echo=FALSE, fig.cap='Tabela long'}
knitr::include_graphics("imagens/dados_long.png")
```
A primeira tabela é mais intuitiva para análise visual, pois faz uso de cores e propõe uma leitura natural, da esquerda para a direita. Utiliza, ainda, elementos e estruturas que guiam seus olhos por uma análise de forma simples. Já a segunda tabela é um pouco árida para se interpretar "no olho".
Há uma espécie de regra geral a qual diz que um dado bem estruturado deve conter uma única variável em uma coluna e uma única observação em uma linha.
Observando-se a primeira tabela, com essa regra em mente, podemos perceber que as observações de ano estão organizadas em colunas. Apesar de estar num formato ideal para análise visual, esse formato dificulta bastante certas análises sistemáticas. O melhor a se fazer é converter a primeira tabela a um modelo mais próximo o possível da segunda tabela.
Infelizmente, não temos como apresentar um passo a passo padrão para limpeza de dados, pois isso depende completamente do tipo de dado que você receber, da análise que você quer fazer e da sua criatividade em manipulação de dados. Mas conhecer os pacotes certos ajuda muito nessa tarefa.
Lembre-se: é muito mais fácil trabalhar no R com dados "bem estruturados", onde **_cada coluna deve ser uma única variável_** e **_cada linha deve ser uma única observação_**.
Na contramão da limpeza de dados, você provavelmente terá o problema contrário ao final da sua análise. Supondo que você organizou seus dados perfeitamente, conseguiu executar os modelos que gostaria, gerou diversos gráficos interessantes e está satisfeito com o resultado, você ainda precisará entregar relatórios finais da sua análise em forma de tabelas sumarizadas e explicativas, de modo que os interessados possam entender facilmente, apenas com uma rápida análise visual. Neste caso, que tipo de tabela seria melhor produzir? Provavelmente, quem for ler seus relatórios entenderá mais rapidamente as tabelas mais próximas do primeiro exemplo mostrado.
É importante aprender a estruturar e desestruturar tabelas de todas as formas possíveis.
Para exemplificar, veja algumas tabelas disponíveis no pacote `tidyverse`, ilustrando os diferentes tipos de organização nos formatos wide e long. Todas as tabelas possuem os mesmos dados e informações:
```{r 05-limpando-dados-3, message=FALSE, warning=FALSE}
library(tidyverse)
```
```{r 05-limpando-dados-4}
table1
```
```{r 05-limpando-dados-5}
table2
```
```{r 05-limpando-dados-6}
table3
```
```{r 05-limpando-dados-7}
table4a
```
```{r 05-limpando-dados-8}
table4b
```
```{r 05-limpando-dados-9}
table5
```
## Pacote tidyr
Apesar de existirem diversas possibilidades de situações que necessitem de limpeza de dados, a conjugação de três pacotes consegue resolver a grande maioria dos casos: `dplyr`, `tidyr`, `stringr`.
O pacote `tidyr` é mais um dos pacotes criados por Hadley Wickham. Este fato, por si só, já traz algumas vantagens: ele se integra perfeitamente com o `dplyr`, usando o conector `%>%`, e tem a sintaxe de suas funções bastante intuitiva.
```{r 05-limpando-dados-10, echo = FALSE, message = FALSE}
library(tidyr)
```
```{r 05-limpando-dados-11, eval = FALSE}
install.packages("tidyr")
library(tidyr)
?tidyr
```
O `tidyr` também tem suas funções organizadas em pequenos verbetes, onde cada um representa uma tarefa para organizar os dados. Os verbetes básicos que abordaremos são os seguintes:
* `pivot_longer()`
* `pivot_wider()`
* `separate()`
* `spread()`
* `unite()`
* `separate_rows()`
```{r 05-limpando-dados-12, echo=FALSE, fig.cap='Tabela long'}
knitr::include_graphics("imagens/tidyr.png")
```
```{block 05-limpando-dados-13, type='rmdtip'}
<strong>Referências:</strong>
[Site do pacote `tidyr`](https://tidyr.tidyverse.org)
```
### pivot_longer()
A função `pivot_longer()`, antiga `gather()`, serve para agrupar duas ou mais colunas e seus respectivos valores (conteúdos) em pares. Assim, o resultado após o agrupamento é sempre duas colunas. A primeira delas possui observações cujos valores chave eram as colunas antigas e a segunda possui os valores respectivos relacionados com as colunas antigas. Na prática, a função gather diminui o número de colunas e aumenta o número de linhas de nossa base de dados.
Usaremos dados disponíveis no R base para exemplificar:
```{r 05-limpando-dados-14}
relig_income
```
Para transformar a tabela acima do formato wide para o long, usamos a função:
```{r 05-limpando-dados-15}
relig_income %>%
pivot_longer(
# o argumento cols controla quais colunas serão (ou não serão) transformadas
cols = -religion,
#names_to controla o nome da nova coluna que irá receber os nomes das colunas transpostas
names_to = "renda",
# values_to controla o nome da nova coluna que irá recebebr os valores das colunas transpostas
values_to = "quantidade")
```
```{block 05-limpando-dados-16, type='rmdtip'}
<strong>Referências:</strong>
[Documentação da função `pivot_longer()`](https://tidyr.tidyverse.org/reference/pivot_longer.html)
```
### pivot_wider()
É a operação antagônica do `pivot_longer()`. Ela espalha os valores de duas colunas em diversos campos para cada registro: os valores de uma coluna viram o nome das novas colunas, e os valores de outra viram valores de cada registro nas novas colunas. O output tem mais colunas e menos linhas.
```{r 05-limpando-dados-17}
us_rent_income
```
```{r 05-limpando-dados-18}
us_rent_income %>%
pivot_wider(
#names_from controla de qual coluna serão criados os nomes das novas colunas
names_from = variable,
# values_from controla as colunas cujos valores serão os valores das novas colunas
values_from = c(estimate, moe)
)
```
```{block 05-limpando-dados-19, type='rmdtip'}
<strong>Referências:</strong>
[Documentação da função `pivot_wider()`](https://tidyr.tidyverse.org/reference/pivot_wider.html)
```
### separate
O `separate()` é usado para separar duas variáveis que estão em uma mesma coluna. Lembre-se: cada coluna deve ser apenas uma única variável! É muito normal virem variáveis juntas em uma única coluna, mas nem sempre isso é prejudicial, cabe avaliar quando vale a pena separá-las.
Usaremos o exemplo da `table3` para investigar:
```{r 05-limpando-dados-20}
table3.wide <- table3 %>%
separate(rate, into = c("cases", "population"), sep='/')
head(table3.wide)
```
```{block 05-limpando-dados-21, type='rmdtip'}
<strong>Referências:</strong>
[Documentação da função `separate`](https://tidyr.tidyverse.org/reference/separate.html)
```
### unite
A operação `unite()` é o oposto da `separate()`, ela pega duas colunas (variáveis) e transforma em uma só. É muito utilizada para montar relatórios finais ou tabelas para análise visual. Aproveitemos o exemplo em `table2` para montarmos uma tabela final comparando a "case" e "population" de cada país, em cada ano.
```{r 05-limpando-dados-22}
table2.relatorio <- table2 %>%
unite(type_year, type, year) %>%
spread(key = type_year, value = count, sep = '_')
table2.relatorio
```
```{block 05-limpando-dados-23, type='rmdtip'}
<strong>Referências:</strong>
[Documentação da função `unite`](https://tidyr.tidyverse.org/reference/unite.html)
```
O primeiro parâmetro é a coluna que desejamos criar, os próximos são as colunas que desejamos unir e, por fim, temos o `sep`, que representa algum símbolo opcional para ficar entre os dois valores na nova coluna.
### separate_rows
Do mesmo modo que `separate()` quebra uma coluna em várias, `separate_rows()` quebra uma linha em várias de acordo com um separador. Essa função é muito útil para lidar com dados sujos. Observe o exemplo:
```{r 05-limpando-dados-24}
# criar dataframe de exemplo
exemplo <- tibble(grupo = c("a", "a", "b","b"),
y = c("1, 2", "3;4", "1,2,3", "4"))
exemplo %>%
separate_rows(y, sep = ",")
```
```{block 05-limpando-dados-25, type='rmdtip'}
<strong>Referências:</strong>
[Documentação da função `separate_rows`](https://tidyr.tidyverse.org/reference/separate_rows.html)
```
## Exercicios
1. Transforme a table1 para a table2 usando pivot_longer()
2. Transforme a table2 para a table1 usando pivot_wider()
3. Transforme a table5 para a table1 e para a table2