-
Notifications
You must be signed in to change notification settings - Fork 7
/
052-readr.Rmd
243 lines (153 loc) · 10.1 KB
/
052-readr.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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
## O pacote readr {#readr}
```{r, include=FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
fig.align = "center",
cache = TRUE,
message = FALSE,
warning = FALSE
)
```
O pacote `{readr}` do tidyverse é utilizado para importar arquivos de texto, como `.txt` ou `.csv`, para o R. Para carregá-lo, rode o código:
```{r}
library(readr)
```
O `{readr}` transforma arquivos de textos em `tibbles` usando as funções:
- `read_csv()`: para arquivos separados por vírgula.
- `read_tsv()`: para arquivos separados por tabulação.
- `read_delim()`: para arquivos separados por um delimitador genérico. O argumento `delim=` indica qual caractere separa cada coluna no arquivo de texto.
- `read_table()`: para arquivos de texto tabular com colunas separadas por espaço.
- `read_fwf()`: para arquivos compactos que devem ter a largura de cada coluna especificada.
- `read_log()`: para arquivos padrões de log.
Vamos mostrar na próxima seção como importar as extensões mais comuns: `.csv` e `.txt`.
### Lendo arquivos de texto
Como exemplo, utilizaremos uma base de filmes do IMDB, gravada em diversos formatos. O download dos arquivos pode ser realizado [clicando aqui](https://github.com/curso-r/livro-material/raw/master/assets/data/imdb.zip).
Primeiro, vamos ler a base em formato `.csv`.
```{r, eval=FALSE}
imdb_csv <- read_csv(file = "imdb.csv")
```
```{r, echo=FALSE, message=TRUE, warning=TRUE}
imdb_csv <- read_csv(file = "assets/data/imdb.csv")
```
A mensagem retornada pela função indica qual classe foi atribuída para cada coluna. Repare que o argumento `file=` representa o caminho até o arquivo. Se o arquivo a ser lido não estiver no diretório de trabalho da sua sessão, você precisa especificar o caminho até o arquivo.
```{r, eval=FALSE}
# Se o arquivo estiver dentro de uma pasta chamada dados.
imdb_csv <- read_csv(file = "dados/imdb.csv")
```
A maioria das funções de leitura do `{readr}` possuem argumentos muito úteis para resolver problemas de importação:
- `col_names=`: indica se a primeira linha da base contém ou não o nome das colunas. Também pode ser utilizado para (re)nomear colunas.
- `col_types=`: caso alguma coluna seja importada com a classe errada (uma coluna de números foi importada como texto, por exemplo), você pode usar esse argumento para especificar a classe das colunas.
- `locale=`: útil para tratar problema de *encoding*.
- `skip=`: pula linhas no começo do arquivo antes de iniciar a importação. Útil para quando o arquivo a ser importado vem com metadados ou qualquer tipo de texto nas primeiras linhas, antes da base.
- `na=`: indica quais *strings* deverão ser considaras `NA` na hora da importação.
Em alguns países, como o Brasil, as vírgulas são utilizadas para separar as casas decimais dos números, inviabilizando o uso de arquivos `.csv`. Nesses casos, quando a vírgula é o separador de decimal, os arquivos `.csv` passam a ser separados por ponto-e-vírgula. Para importar bases de arquivos separados por ponto-e-vírgula no R, basta usar a função `read_csv2()`.
```{r, eval=FALSE}
imdb_csv2 <- read_csv2("dados/imdb2.csv")
```
Arquivos `.txt` em geral podem ser lidos com a função `read_delim()`. Além do caminho até o arquivo, você também precisa indicar qual é o caractere utilizado para separar as colunas da base. Um arquivo separado por tabulação, por exemplo, pode ser lido utilizando a o código abaixo. O código `\t` é uma forma textual de representar a tecla TAB.
```{r, eval=FALSE}
imdb_txt <- read_delim("dados/imdb.txt", delim = "\t")
```
Repare que a sintaxe é igual a da função `read_csv()`. Em geral, as funções de importação do `{tidyverse}` terão sintaxe e comportamento muito parecidos.
A seguir, vamos falar das funções `parse_()`, muito úteis para tratar problemas na classe das variáveis na hora da importação.
### Locale
Muitas funções de importação e formatação possuem um argumento `locale`. Esse argumento é utilizado para definir opções de formatação próprias de uma certa localidade, como idioma, formato de data e hora, fuso horário, separador de decimal e milhar ou encoding.
O pacote `{readr}` possui uma função chamada `locale()`, que pode ser utilizada para definir todos esses atributos. Para saber quais são os padrões atualmente definidos na sua sessão, basta rodar:
```{r}
locale()
```
Em geral, teremos padrões norte-americanos. Se quisermos que os nomes de dias e meses fiquem em português, podemos fazer:
```{r}
locale(date_names = "pt")
```
Ou trocar o separador de decimal de ponto para vírgula, caso a base a ser importada esteja nesse formato.
```{r}
locale(decimal_mark = ",")
```
A função `locale()` deve ser utilizada dentro das funções `read_()`, no argumento `locale`. Uma utilização muito comum é a definição do *encoding* do arquivo. O encoding se refere a como o computador traduz os caracteres que vemos na tela para os valores binários que ele utiliza internamente. Existem vários tipos de encoding e isso é um problema principalmente porque o Windows utiliza um encoding diferente do Linux/Mac. Você saberá que tem um problema de encoding quando letras com acento ou outros caracteres especiais ficarem desconfigurados após importar uma base para o R.
```{r}
# Vamos produzir um problema de encoding
frase_com_acentos <- "Você comerá uma maçã amanhã à tarde"
# Vendo encoding. UTF-8 é o padrão do Linux/Mac
Encoding(frase_com_acentos)
# Forçando um novo encoding.
# latin1 é um dos padrões que funcionam no Windows.
Encoding(frase_com_acentos) <- "latin1"
# Agora temos um problema de encoding
frase_com_acentos
# Obs: esse código foi rodado em um computador que utiliza o encoding UTF-8.
```
Quando estivermos enfrentando esse problema, devemos dizer à função `read_()` qual o encoding deve ser utilizado no arquivo.
```{r, eval = FALSE}
read_csv("base_que_veio_do_windows.csv", locale = locale(encoding = "latin1"))
```
O `latin1` é apenas um dos encodings que podem funcionar em arquivos do Windows. Outras sugestões são: `windows-1250`, `windows-1252`, `ISO-8859-2` e `ISO-8859-1`. Se você estiver lendo um arquivo criado no Linux/Mac no Windows, basta usar o encoding `UTF-8`.
> Eu consegui resolver 99% dos meus problemas de encoding quando passei a fingir que o Windows não existe. --- Julio Trecenti
Na seção a seguir, mostramos mais alguns exemplos da função `locale()`.
### Parseando valores
O pacote `{readr}` possui algumas funções muito úteis para parsear valores. Parsear é um termo muito utilizado em programação e tem o sentido de *arrumar* ou *formatar*. Se estamos parseando um número, por exemplo, estamos pegando um texto que é muito parecido com um número e o transforando em um número de fato.
```{r}
parse_number(c("5", "5.0", "5,0", "R$5.00", "5 a"))
```
```{r, fig.cap=Sys.getenv("cap_alisson_horst"), echo=FALSE}
knitr::include_graphics("assets/img/importacao/parse_number.png")
```
Veja que podemos usar o argumento `locale` para especificar coordenadas para o parseamento
```{r}
parse_number("5,0", locale = locale(decimal_mark = ","))
```
ou o idioma usado em datas
```{r}
# Inglês
parse_date(
"01/June/2010",
format = "%d/%B/%Y"
)
# Português
parse_date(
"01/Junho/2010",
format = "%d/%B/%Y",
locale = locale(date_names = "pt")
)
```
Você também pode especificar `NAs` utilizando o argumento `na`.
```{r}
parse_number(c("5", "5.0", "5,0", "R$5.00", "5 a"), na = "5 a")
```
Outras funções de parseamento úteis são:
- `readr::parse_integer()`, para parsear números inteiros.
- `readr::parse_character()`, para parsear strings
- `readr::parse_date()`, `readr::parse_time()`, `readr::parse_datetime()`para parsear datas, horas e data/horas.
Todas essas funções são utilizadas nas colunas de uma base quando utilizamos as funções de importação do `{readr}`. Assim, se algum valor foi modificado incorretamente durante a importação, você pode testar importar tudo como texto (`character`) e usar essas funções para reproduzir a transformação que o `{readr}` fez.
### Escrevendo arquivos de texto
Para a maioria das funções `read_`, existe uma respectiva função `write_`. Essas funções servem para salvar bases em um formato específico de arquivo. Além do caminho/nome do arquivo a ser criado, você também precisa passar o objeto que será escrito. Para o arquivo criado funcionar corretamente, você precisa especificar a extensão correta no nome do arquivo.
```{r, eval=FALSE}
# Arquivo .csv
write_csv(x = mtcars, path = "data/mtcars.csv")
# Base separada por tabulação
write_delim(x = mtcars, path = "data/mtcars.txt", delim = "\t")
```
### Arquivos .rds
A linguagem R tem uma extensão própria de arquivos binários chamada `RDS` ou `.rds`. Essa extensão pode ser utilizada para guardar qualquer tipo de objeto do R, inclusive bases de dados. Temos duas principais vantagens ao utilizarmos essa extensão para salvarvamos as nossas bases:
- ela salva as classes especificadas para as colunas;
- ela pode ser compactada, gerando arquivos muito menores.
A desvantagem é que ela só poderá ser lida dentro do R.
Para criar um arquivo `.rds`, utilize a função `write_rds()`.
```{r, eval=FALSE}
write_rds(mtcars, path = "mtcars.rds", compress = "gz")
```
O argumento `compress` é opcional e indica qual o tipo de compactação deve ser feito. O padrão é não compactar.
Para ler um arquivo `.rds` de volta para o R, utilizamos a função `read_rds()`. Repare que essa função não possui outros argumentos, pois o objeto importado será exatamente igual ao objeto que foi gravado no arquivo.
```{r, eval=FALSE}
imdb_rds <- read_rds(path = "imdb.rds")
```
### Exercícios {-}
**1.** Qual a diferença entre as funções `read_csv()` e `read_csv2()`?
**2.** Leia o arquivo `imdb.csv` utilizando a função `read_delim()`.
**3.** Escreva a base mtcars em um arquivo `mtcars.csv` que não contenha o nome das colunas.
**4.** Use a função `write_rds()` para salvar em arquivos
- **a)** Um número.
- **b)** Um vetor de strings.
- **c)** Uma lista com valores númericos, textuais e lógicos.
- **d)** As 3 primeiras colunas da base `mtcars`.
**5.** Utilize a função `read_rds()` para importar de volta para o R os arquivos criados no exercício 4.