-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path03-import_export.Rmd
621 lines (450 loc) · 24.3 KB
/
03-import_export.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
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
```{r setup, cache = F}
#-- Opção para deixar possível visualizar erros
knitr::opts_chunk$set(error = TRUE)
```
# Importando e Exportando Dados
## Base
### Importando com `read.*`
Como vimos anteriormente, na maioria dos casos, iremos usar data frames par lidar com dados em R, sendo assim, podemos utilizar os seguintes modos de leitura:
- `read.csv`
- `read.csv2`
- `read.table`
Vamos ler alguns dados usando `read.table`. Para saber o que a função faz, use `?read.table`.
Os argumentos da função são:
```{r}
args(read.table)
```
O terceiro argumento é `sep`, definido como `""` por padrão. Esse argumento indica para o R qual o tipo de separador utilizado entre as colunas dos dados.
```{r}
df <- read.table("dados/NOXIPEN2014.txt")
```
Lembre-se que as funções `head` e `tail` permitem que você veja as primeiras ou últimas linhas do data frame.
```{r}
head(df)
tail(df)
```
Vamos tentar ler outra versão dos mesmos dados utilizando a mesma função `read.table`:
```{r}
df2 <- read.table("dados/NOXIPEN2014v2.txt")
```
Apareceu uma mensagem de erro, <span style="color:blue">você saberia dizer o porquê?</span>
**Caso você trabalhe com algum banco de dados em formato .txt e quiser abrir no R... Abra-os no bloco de notas primeiro!**
Vamos dar uma olhada em alguns dados, o primeiro tem uma cara assim:
```{r echo = FALSE}
knitr::include_graphics("figuras/f1.png")
```
Já o segundo arquivo é assim:
```{r echo = FALSE}
knitr::include_graphics("figuras/f2.png")
```
Você notou a diferença? Como vimos anteriormente, para importar os dados no R é super importante que você especifique o tipo de separador utilizado. Como o segundo arquivo é separado por ";", precisamos espercificar o argumento `sep` na hora de usar o comando `read.table`:
```{r}
df2 <- read.table("dados/NOXIPEN2014v2.txt", sep = ";")
head(df2)
tail(df2)
```
Além desses comandos, vocês também pode utilizar a opção **Import Dataset** do RStudio, permitindo que você tenha um "preview" dos dados - como no Excel, mas melhor!
Para mais informações sobre importar dados no R, dê uma olha nesse [webnário](https://www.rstudio.com/resources/webinars/importing-data-into-r/).
### Exportando com `write.table`
Exportar é bem facil. Vamos dar uma olhada nos argumentos da função `write.table`:
```{r}
args(write.table)
```
Se temos um data frame com colunas de classe character, `quote = TRUE` quer dizer que o arquivo de texto resultante vai ter aspas nas colunas de caractere. Novamente, o argumento `sep` indica como podemos separar as colunas. Se você quiser abrir esses dados no excel, uma boa opção é utilizar os separadores ","/";"/" "/"\t", sendo o último o separador que indica o espaçamento criado pela tecla TAB.
Já o argumento `eol` quer dizer _end of line_, e é uma forma de dizer ao R que a linha acaba ali.
Por padrão, a opção `row.names` vem com a opção TRUE, mas sempre coloque a opção FALSE, caso contrário, será adicionada uma coluna com os índices das linhas. O argumento `col.names` indica se você quer nomear as suas colunas, o que é sempre uma boa ideia.
***
<span style="color:red">**Exercício**: Usando o conjunto de dados `mtcars` da base do R, exporte-o de uma forma que ele possa ser lido em algum Excel genérico. Não esqueça de usar o que foi ensinado acima.
***
### Exportando objetos com `save`
Podemos salvar objetos do R com o comando `save`. Ele permite que você recarregue o objeto mais tarde.
```{r}
args(save)
```
Essa função salva o objeto com a extensão .rda sendo que para carregá-lo de volta usamos a função `load`
```{r}
args(load)
```
Muito cuidado ao utilizar esse comando, pois é bem possível cometer alguns deslizes, como trocar o nome do objeto. Veja esse exemplo abaixo:
```{r eval=FALSE}
#Primeiro vamos ler os dados do dia 01/06/2016 para uma estação automática do INMET de Paracatu:
paracatu <- read.csv(file = "dados/paracatu.csv", sep = ",") #lendo como csv
# Vamos dizer que queremos salvar apenas a coluna correspondente à temperatura máxima horária:
paracatu_temp <- paracatu$temp_max
#Agora vamos salvar o objeto do tipo numeric com o nome especificado:
save(paracatu_temp, file = "Temp_max.rda")
```
Passado um tempo, queremos acessar de volta esse objeto, mas não lembramos se salvamos a temperatura máxima ou mínima, vamos confiar que foi a mínima:
```{r eval = FALSE}
load("Temp_min.rda")
```
E assim descobrimos que não era... O que nos ensina a sempre guardar na memória quais variáveis que salvamos no ambiente R. O bom dessa função é que ela permite salvar com tipos de compressão, por exemplo `compress = "xz"`.
### Exportando objetos com `saveRDS`
Esta é uma das minhas funçoes favoritas no R, veja só o porquê:
```{r eval = FALSE}
saveRDS(paracatu_temp, "Temperatura.rds")
```
```{r eval = FALSE}
frenteQ <- readRDS("Temperatura.rds")
```
Você pode salvar seu objeto R de forma serializada e compactada com o argumento `compress` e na hora de chamar o objeto de volta é só usar `readRDS` e colocar o nome que você quiser.
### Processando nossa data frame {#processing_dfs}
Vamos revisar a classe de cada coluna do nosso data-frame com a função `sapply`, que será explicada em outro capítulo. Lembre-se, qualquer dúvida é só usar `?sapply`.
```{r}
sapply(df, class)
```
Quando trabalhamos com séries temporais, é importante ter a variável tempo reconhecida como "tempo", especificamente como classe "POSIXct". Porém, a classe do tipo Data é "factor" assim como a Hora, o que pode ser ruim. Então, vamos criar uma variável de tempo mais padronizada com o formato `r Sys.time()`.
Para isso temos que juntar as variáveis Data e Hora. Faremos isso numa nova varável chamada "tempo_char", adicionando-a diretamente no data frame com o cifrão ("$"). Podemos fazer isso com as funções `paste` ou `paste0`.
```{r}
df$tempo_char <- paste(df$Data, df$Hora)
head(df$tempo_char)
class(df$tempo_char)
```
Melhorou, mas ainda tem clase `r class(df$tempo_char)`.
Para converter a nossa classe para POSIXct podemos usar a função `as.POSIXct` (olhe
`?as.POSIXct`). Seus argumentos são:
```{r}
args(as.POSIXct)
```
Então, vamos criar outra variável tempo com o formato POSIXct:
```{r}
df$tempo <- as.POSIXct(x = df$tempo_char, tz = "America/Sao_Paulo",
format = "%d/%m/%Y %H:%M")
head(df$tempo)
class(df$tempo)
```
Agora, vamos extrair os dias da semana do tempo, mes e dia juliano:
```{r}
df$weekdays <- format(df$tempo, "%A")
head(df$weekdays)
df$mes <- format(df$tempo, "%B")
head(df$mes)
df$diajuliano <- julian(df$tempo)
head(df$diajuliano)
df$ano <- format(df$tempo, "%Y")
```
Pronto! Agora temos o tempo no formato que desejamos.
#### `aggregate`
Vamos dar uma olhada no nosso data frame:
```{r}
head(df)
```
Com a função `aggregate`, podemos agregar os dados de diversas formas. Por exemplo, a média horaria por dia da semana é:
```{r}
dff <- aggregate(df$MediaHoraria, by = list(df$weekdays), mean, na.rm = T)
names(dff) <- c("dias", "MediaHoraria")
dff
```
E o desvio-padrão é:
```{r}
dff$sd <- aggregate(df$MediaHoraria, by = list(df$weekdays), sd, na.rm = T)$x
dff
```
***
<span style="color:red">**Exercício**: **Em média**, como o NOx varia ao longo do dia de acordo com esses dados? Qual a amplitude diária?</span>
***
#### `subset`
Como podemos escolher só o mês de janeiro??
```{r}
#[ LINHAS , COLUNAS ]
head(df[df$mes == "janeiro", ]) #TODAS AS COLUNAS
```
Só que agora temos só a média horária para esse mês, que retorna um vetor numérico:
```{r}
names(df)
head(df[df$mes == "janeiro", 10])
head(df[df$mes == "janeiro", "MediaHoraria"])
class(df[df$mes == "janeiro", "MediaHoraria"])
```
***
<span style="color:red">**Exercício**: **Em média**, como o NOx varia ao longo do dia em Julho? E em Dezembro?</span>
***
Vamos salvar nosso data frame para depois fazer gráficos:
```{r}
saveRDS(df, "dados/df.rds")
```
### Data.Table e mais
O data.table é um pacote que apresenta a classe `data.table`, que é como uma versão melhorada da classe `data.frame` O termo especifico é que `data.table` tem um "parentesco" (inherits) com a classe `data.frame`.
Vamos ver como funciona data.table lendo os dois arquivos e comparar quanto tempo demora cada um. A função de leitura do data.table é `fread`.
```{r}
df1 <- print(system.time(read.table("dados/NOXIPEN2014.txt", h = T)))
```
```{r}
library(data.table)
df2 <- print(system.time(fread("dados/NOXIPEN2014.txt", h = T)))
```
## Tidyverse {#tidyverse}
Um método mais recente (e muito interessante!) de tratar data frames é usando os pacotes dentro do [Tidyverse](https://www.tidyverse.org/).
Usando diversas funções dos pacotes **readr**, **tidyr** e **dplyr**, por exemplo, é possível ler e processar dados de uma maneira mais *user-friendly* devido à sintaxe das funções e de como elas podem ser usadas em conjunto.
Assim como o data.table tem uma classe própria, as funções dentro do tidyverse costumam trabalhar com sua própria classe, que é o `tibble` (ou `tbl_df`) - *que segundo [os desenvolvedores](https://github.com/tidyverse/tibble) são `data.frames` preguiçosos e mal-humorados. Isso pode parecer ruim, mas na verdade é bom pois exige funções "mais espertas" para lidar com eles*. Ainda assim é possível trabalhar com data frames sem dificuldades.
Note que muitas das funções usadas abaixo podem ser encontradas em Base ou em outros pacotes associados.
### Importando dados
Todas as funções de leitura possuem a mesma estrutura:
```{r, eval = F}
read_*(arquivo,
col_names = TRUE,
col_types = NULL,
locale = default_locale(),
na = c("", "NA"),
quoted_na = TRUE,
comment = "",
trim_ws = TRUE,
skip = 0,
n_max = Inf,
guess_max = min(1000, n_max), progress = interactive())
```
*Dica/Lembrete: Quando a descrição de uma função mostra os argumentos já definidos (`col_names = TRUE`), isso significa que esses são os valores padrão e que você não precisa escrever os argumentos se não quiser mudá-los*
Assim, todas as funções de leitura só precisam do nome do arquivo!
Então como ler diferentes arquivos? Usando diferentes funções.
- `read_csv` lê arquivos .csv **separados por $,$**
- `read_csv2` lê arquivos .csv **separados por $;$**
- `read_delim` lê arquivos **com outros separadores** (definidos com o argumento `delim`)
- `read_fwf` lê arquivos **com delimitação fixa** (definidos com o argumento `col_positions`)
- `read_xl` lê arquivos **Excel** (.xls e .xlsx)
Assim, para ler os dados de Paracatu do INMET:
```{r, message=F}
library(tidyverse)
paracatu <- read_csv("dados/paracatu.csv")
glimpse(paracatu)
```
### Leitura `%>%` Processamento
Existem funções de leitura e modificação de data frames. Muitas vezes, você precisa lidar com dados "brutos" e que precisam de um certo processamento antes de serem utilizados em cálculos e gráficos. Como vimos anteriormente, isso exige no mínimo duas funções em duas linhas de código (uma para ler e outra para modificar), mas em geral esse processo precisa de bem mais do que isso.
O operador [`%>%`](http://r4ds.had.co.nz/pipes.html)) (chamada de *pipe*) está dentro do pacote magnittr (dentro do Tidyverse) e é muito útil nesse processo! ([Leia um pouco sobre ele aqui](https://www.datacamp.com/community/tutorials/pipe-r-tutorial))
Como ele funciona?
> variável %>% função1(., faz a modificação 1) %>% função2(., faz a modificação 2) %>% ... %>% funçãon(., faz a modificação n)
O ponto (.) acima indica que a função será aplicada na versão da variável que chega nela.
Em notação matemática, podemos dizer que $x \ \ \%>\% \ \ f(y) = f(x,y)$.
Por exemplo, observe o código abaixo:
```{r, message=F}
library("tidyverse")
seq(1, 10) %>% order(., decreasing = T) %>% paste(., "n")
```
O vetor (que não precisa necessariamente ser definido como uma variável) é primeiro ordenado de forma decrescente e, a partir dessa modificação, é transformado em um vetor de caracteres ao colar a string "n" a ele.
Uma forma de fazer isso sem usar `%>%` seria:
```{r}
paste(order(seq(1, 10), decreasing = T), "n")
```
<span style="color:blue">**Pergunta**: Na sua opinião, qual é o código mais fácil e rápido de ser entendido?</span>
Como isso pode ser aplicado a data frames?
Voltando aos dados de Paracatu, vamos supor que você ainda não tenha lido esses dados, mas já saiba que o dia e a hora estão em colunas separadas e que você precisa juntá-los para calcular médias em períodos específicos. Além disso, você quer comparar a temperatura instantânea "temp_inst" com a média entre temperatura máxima "temp_max" e mínima "temp_min". Então, precisamos:
1. Ler os dados
2. Juntas as colunas "data" e "hora"
3. Transformar a coluna resultante em `POSIXct`
4. Calcular a média entre "temp_max" e "temp_min"
5. Comparar o que foi calculado com "temp_inst"
Sem `%>%`:
```{r, message=F}
library(tidyverse)
paracatu <- read_csv("dados/paracatu.csv") #-- 1.
paracatu <- mutate(paracatu, data_completa = paste(data, hora, sep = "-")) #-- 2.
paracatu <- mutate(paracatu, data_completa = as.POSIXct(data_completa, format = "%d/%m/%Y-%H")) #-- 3.
paracatu <- mutate(paracatu, temp_med = (temp_max + temp_min)/2) #-- 4.
paracatu <- mutate(paracatu, temp_residuo = temp_inst - temp_med) #-- 5.
summary(paracatu)
```
Note que sempre se mostra necessário salvar cada passo em uma nova variável ou, nesse caso, reciclar a mesma variável. Foi preciso uma linha para cada operação.
Já com `%>%`:
```{r, message=F}
library(tidyverse)
paracatu <- read_csv("dados/paracatu.csv") %>% #-- 1.
mutate(., data_completa = paste(data, hora, sep = "-")) %>% #-- 2.
mutate(., data_completa = as.POSIXct(data_completa, format = "%d/%m/%Y-%H")) %>% #-- 3.
mutate(., temp_med = (temp_max + temp_min)/2) %>% #-- 4.
mutate(., temp_residuo = temp_inst - temp_med) %>% #-- 5.
glimpse()
```
O código pode estar separado por linhas, mas perceba que, ao rodar qualquer linha desse conjunto, todo ele é rodado de uma vez!
Assim, adicionar um passo fica fácil. Por exemplo, as colunas "data" e "hora" não são mais necessárias:
```{r, message=F}
library(tidyverse)
paracatu <- read_csv("dados/paracatu.csv") %>% #-- 1.
mutate(., data_completa = paste(data, hora, sep = "-")) %>% #-- 2.
mutate(., data_completa = as.POSIXct(data_completa, format = "%d/%m/%Y-%H")) %>% #-- 3.
mutate(., temp_med = (temp_max + temp_min)/2) %>% #-- 4.
mutate(., temp_residuo = temp_inst - temp_med) %>% #-- 5.
select(., -c(data, hora)) %>% #-- 6.
glimpse()
```
<span style="color:blue">**Pergunta**: E agora? Na sua opinião, qual é o código mais fácil e rápido de ser entendido?</span>
***
<span style="color:red">**Exercício**: Crie um data frame dos dados de Paracatu com a data no formato `POSIXct` e os resíduos de temperatura e pressão. Em geral, qual grandeza tem maior resíduo?</span>
***
## Outros Tipos de Dados
### NetCDF
O NetCDF (Network Common Data Form) é um conjunto de bibliotecas de software e formatos de dados independentes de máquina e autodescritivos com suporte para criação, acesso e compartilhamento de dados científicos orientados a matrizes. Arquivos NetCDF (criado por essa biblioteca ou por programas que utilizam essa biblioteca) são arquivos compostos por dados, atributos e metadados.
O pacote `ncdf4` é um exemplo de interface do R com a biblioteca NetCDF 4, os comandos abaixo instalam e carregam esse pacote:
```{r }
#install.packages("ncdf4") # instala o pacote
library("ncdf4") # carrega o pacote
nc_version() # versão da biblioteca
```
Um exemplo de NetCDF:
```{r, eval=F}
edgar <- nc_open(filename = "dados/v431_v2_REFERENCE_CO_2010_10_AGR.0.1x0.1.nc")
```
O objeto `edgar` contém algumas informações sobre o conteúdo do arquivo, com um `print(edgar)` ou simplesmente `edgar` visualizamos o conteúdo do arquivo:
```{r, eval=F}
class(edgar)
edgar
```
Isso mostra o nome do arquivo (e versão da biblioteca usada para criar), número de variáveis (1 variável neste exemplo), uma descrição de cada variável (incluindo atributos) as dimensões (2 para esse arquivo) e atributos globais.
Agora vamos abrir alguma variável:
```{r, eval=F}
names(edgar$var)
co <- ncdf4::ncvar_get(edgar, "emi_co")
class(co)
```
Como o NetCDF é organizado para guardar matrizes (arrays), só sabemos que a variável `emi_co` é um array
```{r, eval=F}
ncatt_get(edgar,"emi_co") # ou ncatt_get(edgar,"emi_co",verbose = T)
```
repete a informação do print anterior, mas sem os atributos globais:
```
# $standard_name
# [1] "tendency_of_atmosphere_mass_content_of_carbon_monoxide_due_to_emission"
# $long_name
# [1] "Emissions of CO - "
# $units
# [1] "kg m-2 s-1"
# $cell_method
# [1] "time: mean (interval: 1 month, 31 days)"
# $total_emi_co
# [1] " 6.32889e+009 kg/month"
# $comment
# [1] " (see http://edgar.jrc.ec.europa.eu/methodology.php#12sou for the definitions of the single sources)"
```
A latitude de cada ponto de grade, assim como longitude níveis (tempo em outros casos) o podem ser extraídas:
```{r, eval=F}
lat <- ncvar_get(wrf, "lat")
lon <- ncvar_get(wrf, "lon")
```
O metadado de Longitude também pode conter informações úteis:
```{r, eval=F}
ncatt_get(edgar,"lon")
# $standard_name
# [1] "longitude"
# $long_name
# [1] "longitude"
# $units
# [1] "degrees_east"
# $comment
# [1] "center_of_cell"
```
e Latitude:
```{r, eval=F}
ncatt_get(edgar,"lat")
# $standard_name
# [1] "latitude"
# $long_name
# [1] "latitude"
# $units
# [1] "degrees_north"
# $comment
# [1] "center_of_cell"
```
e também os atributos globais podem ser acessados separadamante:
```{r, eval=F}
ncatt_get(edgar,varid = 0)
# $Conventions
# [1] "CF-1.0"
# $title
# [1] "Monthly Mean (October) Emissions of CO - "
# $institution
# [1] "European Commission, Joint Research Centre"
# $source
# [1] "http://edgar.jrc.ec.europa.eu/"
# $history
# [1] "Created from original data (0.1x0.1 degrees) using IDL program (edgar_ascii_to_ncdf.pro) on Wed Jun 29 13:29:58 2016"
# $references
# [1] "European Commission, Joint Research Centre (JRC)/Netherlands Environmental Assessment Agency (PBL). Emission Database for Global Atmospheric Research (EDGAR),http://edgar.jrc.ec.europe.eu"
# $copyright_notice
# [1] "Reproduction of the data is authorized, except for commercial purposes, provided the source is fully acknowledged in the from\"Source: European Commission, Joint Research Centre (JRC)/Netherlands Environmental Assessment Agency (PBL). Emission Databasefor Global Atmospheric Research (EDGAR), http://edgar.jrc.ec.europe.eu\". Where reproduction is on a web-site,at least one link to http://edgar.jrc.ec.europa.eu, should be provided and maintained. Where prior permission must be obtained for thereproduction or use of textual and multimedia information (sound, images, software, etc.), such permission shall cancel the above-mentionedgeneral permission and shall clearly indicate any restrictions on use."
# $contact
# [1] "[email protected]"
```
Da mesma forma com que podemos acessar variáveis e atributos com `ncvar_get` e `ncatt_get`, podemos modificar estes valores com `ncvar_put` e `ncatt_put`. Outras operações como renomear (`ncvar_rename`) e trocar o valor de missval (`ncvar_change_missval`) também estão disponíveis.
*DICA*: `ncatt_get` e `ncatt_put` acessam e alteram os atributos de váriaveis e também atributos globais do NetCDF usando o argumento `varid=0` como no código mostrado anteriormente.
Para salvar as alterações e/ou liberar o acesso ao arquivo use a função `nc_close` (ou a função `nc_sync` que sincroniza o NetCDF mas não fecha a conexão com o arquivo).
```{r, eval=F}
nc_close(edgar) # ou nc_sync(edgar)
```
O pacote possue ainda funções mais específicas para a criação de arquivos em NetCDF como `nc_create`, funções que definem dimenções como `ncdim_def` e funções para colocar e tirar o arquivo de modo de definição `nc_redef` e `nc_enddef`.
*DICA*: o NetCDF no R funciona de forma parecida com ouma lista ou data frame, podemos "ver" ou selecionar suas sub-partes (sub-sub-partes...) com "$" e TAB.
### Dados Binários
O `R` lê e escreve dados binários usando as funções `readBin` e `writeBin`, respectivamente.
**Ler dados binários no R**
Em meteorologia, frequentemente os dados estão em formato binário. A maior "dificuldade" em ler estes dados está em conhecer como eles foram gerados. Neste curso, o arquivo binário que vamos abrir como exemplo contém dados de temperatura de brilho obtidas com o satélite GOES-13 (informações em: https://disc.gsfc.nasa.gov/datasets/GPM_MERGIR_1/summary).
Lembrem-se de baixar o dado em: https://github.com/iagdevs/cursoR/tree/master/dados
Repare que a função `readBin` requer alguns argumentos para ler estes dados da forma correta:
```{r}
args(readBin)
# Lembre-se de usar ?readBin
```
O que são estes argumentos?
- `con` é um objeto de conexão ou um string de caracteres nomeando um arquivo.
- `what` é um string de caracteres que indica o modo dos dados a serem lidos. Pode ser um “numeric", "double", "integer", "int", "logical", "complex", or "character".
- `n` um inteiro especificando o número máximo de valores a serem lidos.
- `size` um inteiro especificando o número de bytes por valor lido. O padrão de NA_integer_ usa um tamanho padrão para um valor do modo (what) especificado (4 para “integer”, 8 para “double” e 16 para “complex”. Este argumento é ignorado para dados "character". Neste caso, os dados de caracteres são lidos como sequências de caracteres de byte único terminadas em nulo.
- `signed` é um valor lógico. Usado apenas para números “integer” de tamanhos 1 e 2. Se TRUE (por default), “integers” são considerados como números inteiros assinados.
- `endian` é um string de caracteres. Se endian = "big" ou se endian = "little", especifica-se a extremidade (endian-ness) dos valores lidos ou escritos. Se endian="swap" a extremidade é trocada. Hardware Intel é "little" endian e hardware Sun é "big" endian.
```{r}
# Ler o arquivo binário: readBin
l1 <- readBin("dados/gs.140422.1900g.ch4",
what="int",
n = 1349*1613,
size = 2,
signed = T,
endian = "little")
class(l1)
```
Uma forma rápida para verificarmos os nossos dados é gráfica. Logo, que tal um plot?
```{r}
l2 <- matrix(l1, ncol=1613, nrow=1349)
class(l2)
# Vamos chamar o pacote cptcity para selecionar facilmente uma paleta de cores legal.
library(cptcity)
image(l2,
col = cpt(find_cpt("sat")[8]),
main = "Temperatura de brilho")
```
Tem algo estranho com esta imagem. O que é? (valendo um sticker).
```{r message=FALSE, warning=FALSE}
library(raster, quietly = TRUE)
l3 <- raster(t(l2[1:1349,1:1613]),
xmn=-82.00,
ymn=-44.96,
xmx=-82.0 + (0.03593245*1349),
ymx=-44.96 + (0.03593245*1613),
crs = CRS("+init=epsg:4326"))
class(l3)
```
O capítulo geoespacial será visto no final deste curso. Porém, nesta etapa vamos usar o pacote `raster` somente para analisar se os dados binários foram lidos corretamente.
```{r}
sp::spplot(((l3 + 75)/100)-273, # Estas correções são necessárias. Veja: http://www.cpc.ncep.noaa.gov/products/global_precip/html/README
col.regions = cpt(find_cpt("sat")[8]),
at = seq(-80,0,1),
main = "Temperatura de brilho (ºC)")
```
**Escrever dados binários no R**
```{r}
# Escrever um arquivo binário: writeBin
args(writeBin)
# Lembre-se de usar ?writeBin
```
`useBytes` um valor lógico. No `R`, se FALSE (o default), especifica que writeBin converteria strings com codificações para uma string imprimível antes de escrever os bytes. Se TRUE, especifica que writeBin escreveria os bytes do string não convertidos.
`object` um objeto escrito no `con`.
```{r}
# Na linha abaixo vamos criar um arquivo temporário com o auxílio da função "tempfile"
# para depois escrever os dados dentro deste arquivo.
tf <- tempfile()
# Vamos atribuir a "tb" os 20 primeiros valores de l1 (temperatura de brilho).
tb <- c(21000, 21000, 20800, 21000, 20800, 20700, 20600, 20600, 20900, 20900,
20900, 20900, 20700, 20500, 20500, 20400, 20500, 20700, 20400, 20300)
class(tb)
x <- as.integer(tb)
writeBin(x, con = tf)
# Agora vamos ler o arquivo binário escrito acima. Você lembra quais são os argumentos para ler binário?
readBin(tf,
what = "integer",
n = 20)
```