-
Notifications
You must be signed in to change notification settings - Fork 0
/
AppendixB.Rmd
498 lines (401 loc) · 18.1 KB
/
AppendixB.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
# Funções nativas do R para importar e exportar dados
```{r setup, include = FALSE}
rm(list = ls())
pcks <- c("knitr", "pander") # , "htmlTable")
#pcks <- c("knitr", "emo", "pander") # , "htmlTable")
# pcks <- c("knitr", "emo")
easypackages::libraries(pcks)
opts_chunk$set(
prompt = FALSE,
cache = FALSE,
fig.path = "images/",
comment = "#>",
collapse = TRUE,
eval = FALSE
)
# rblue <- "<code class='sourceCode bash'><span class='ex'>R</span></code>"
rblue <- '<img src="images/logo_r.png" width="20">'
```
## Amostras pequenas de dados
### scan() {#scan}
A função `scan()` também pode ler dados de arquivos, mas a sua saída é um vetor, ou seja ela não mantém a estrutura dos dados contidos no arquivo.
Vamos baixar um arquivo de dados da internet para ilustrar o uso da `scan()`.
```{r}
# download dados de exemplo
aq_url <- "https://raw.githubusercontent.com/lhmet/adar-ufsm/master/data/airquality.txt"
# arquivo temporário, você pode substituir tempfile() por um caminho de seu computador, p.ex. "~/Downloads"
(aq_dest_file <- tempfile())
download.file(aq_url, destfile = aq_dest_file)
```
```{r scan-B}
# Exemplo: vetor
vetor_aq <- scan(aq_dest_file)
# parte inicial dos dados
head(vetor_aq, 100)
# parte final
tail(vetor_aq, 100)
# dados são importados como vetor
is.vector(vetor_aq)
mode(vetor_aq)
```
### readline()
Para ler apenas uma linha de dados a partir do teclado como `character` usamos a função **`readline()`**:
```{r Chunk1120}
sentenca <- readline(prompt = "digite alguma coisa e tecle enter para continuar: ")
sentenca
```
Esta função pode ser utilizada como uma forma de controlar um *looping*. Esse exemplo ilustra o uso da função `lapply()` para execução de laços ou *loopings* ao longo de um vetor de índices. Essa função será vista futuramente no curso.
```{r readline-B}
# para reprodutibilidade
set.seed(123)
# looping ao longo da sequência de 1 a 5
l <- sapply(
1:5,
function(i) {
# cria vetor com números aleatórios com distribuição uniforme
x <- runif(n = 100, min = 1, max = 50)
# anomalia acumulada
y <- cumsum(x - mean(x))
plot(y, type = "o")
abline(h = 0, lty = 2)
# leitura de linha, só após teclar enter vai gerar próximo gráfico
readline(prompt = "tecle <enter> para continuar: ")
}
)
l
```
### Impressão na tela
No modo interativo do R podemos imprimir os valores de um objeto na tela digitando o nome do objeto.
```{r print-B}
x <- 1:3
y <- x ^ 2
y
# ou
print(y)
```
Entretanto isso não é possível quando precisamos mostrar o valor de uma variável dentro do corpo de uma função ou dentro de um laço (*looping*). Nesse caso podemos usar a função `print()`:
```{r printscope-B}
# dentro de uma função
# digitando o nome do objeto não imprimi na tela
fcubo <- function(x) {
classe <- class(x)
# intenção de mostrar objeto de entrada
classe
x ^ 3
}
fcubo(2)
# adicionando print
cubo <- function(x) {
# mostra objeto de entrada
classe <- class(x)
print(classe)
x ^ 3
}
fcubo(-3) # não imprime classe do objeto de entrada
cubo(-3) # imprime classe do objeto de entrada
```
#### `cat()` ao invés de `print()`
É melhor usar a função `cat()` ao invés da função `print()`, já que a `print()` permite a impressão de apenas um único objeto enquanto a `cat()` não. Compare os resultados das duas funções:
```{r catprint-B}
print("abc")
cat("abc\n") # \n indica quebra de linha
x
cat("os elementos de x são: ", x, "\n")
cat("os elementos de x são: ", x, sep = "")
cat("os elementos de x são: ", x, sep = "\n")
k <- c(5, 12, 13, 8, 88)
cat(k, sep = c(".", "___", " ---> ", "\n", "\n"))
```
### textConnection()
Imagine que você tivesse recebido essa amostra de dados por e-mail:
dates cidade temperatura chuva
2013-01-01 SM 13 3
2013-01-01 SS 30 10
2013-01-01 CV 22 12
Para converter essa pequena amostra de dados em um *dataframe* nós podemos selecionar, copiar e colar o texto no primeiro argumento da função `textConnection`, e então usar a função `read.table`.
```{r textCon-B}
texto <- " dates cidade temperatura chuva
2013-01-01 SM 31 3
2013-01-01 SS 35 10
2013-01-01 CV 21 14"
# conexão de texto
tc <- textConnection(object = texto)
tc
x <- read.table(file = tc, header = TRUE)
x
```
## Exportando e recuperando objetos do R no formato textual
### `dput()`, `dget`, `dump` e `source`.
Uma função útil para compartilhar dados com alguém que precisa reproduzi-los é a função `dput()` (que pode ser traduzido como \"despejar\"). Ela escreve uma representação textual de um objeto R que pode ser escrita em um arquivo. Para recriar o objeto basta usar a função `dget()`.
```{r dput-B}
x
# representação textual do objeto x
dput(x)
# salva representação textual de x em um arquivo temporário, você pode substituir tempfile() por um caminho de seu computador, p.ex. "~/Downloads"
(aq_dest_file <- tempfile())
(x_dest_file <- tempfile())
dput(x, file = x_dest_file)
# recuperando x a partir do arquivo
y <- dget(x_dest_file)
# alterar valores de y
y <- y[, 3:4] - sqrt(2)
y
# verificar existência de x e y
ls()
# listando variáveis que começam com x ou y
ls(pattern = "^[xy]")
# salvando mais de um objeto em um arquivo
(xy_dest_file <- tempfile())
dump(ls(pattern = "^[xy]"), file = xy_dest_file)
# vamos apagar x e y do espaco de trabalho
rm(x, y)
# x e y não existem mais
ls()
# recuperando os objetos x e y salvos em xy.R
source(xy_dest_file)
ls()
x
y
```
Portanto diferente da escrita dos dados em si para um arquivo texto as funções `dump()` e `dput()` armazenam os **dados** e os **metadados**, assim outro usuário não precisa especificá-los novamente. Assim o usuário que recebe a saída do `dput()` em um arquivo, pode recriar os dados pelo comando `dget("nomedoarquivo")`.
```{r str-B}
# representação textual de um data.frame
dados3est <- structure(
list(
dates = c("2013-01-01", "2013-01-01", "2013-01-01"),
cidade = c("SM", "SS", "CV"),
temperatura = c(31L, 35L, 21L),
chuva = c(3L, 10L, 14L)
),
.Names = c("dates", "cidade", "temperatura", "chuva"),
class = "data.frame",
row.names = c(NA, -3L)
)
dados3est
```
**Vantagens:**
- armazena os **dados e os metadados**
- recuperação rápida e fácil dos dados
**Desvantagens:**
- armazenamento de dados nesse formato não é muito eficiente em termos de espaço em disco
- pouca legibilidade dos dados
Esse procedimento é geralmente recomendado para fornecer pequenas amostras de dados (e-mails por exemplo)
## Dados de pacotes do R
O `R` possui diversos conjuntos de dados internos que são automaticamente carregados quando iniciado. Esses dados são usados nos exemplos do `help()` de diversas funções para ilustrar o uso e a aplicação delas. Esses dados podem ser carregados com a função `data()`.
```{r data-B}
# lista de dados disponíveis
data()
# Annual Precipitation in US Cities, p/ mais informações "?precip"
data(precip)
# primeiros 30 elementos dos dados precip
head(precip, n = 30)
# New York Air Quality Measurements, , p/ mais informações "?airquality"
data(airquality)
# primeiras linhas dos dados
head(airquality, n = 10)
```
## Leitura de arquivos texto com funções da base do R {#readtable}
A função nativa do `r rblue` mais usada para leitura de dados de um arquivo texto é a `read.table()`. Os dados lidos são armazenados em um dataframe.
Essa função possui diversos parâmetros para especificar a importação de acordo com as peculiaridades do formato de dados do arquivo.
O valor *default* do parâmetro `sep` é um ou mais caracteres de `espaço` e `tabs`. Devido as diversas opções de separadores existem outras funções envelopes da `read.table()`, com a diferença no separador, por exemplo as funções: `read.csv(), read.csv2(), read.delim()` que chamam a `read.table()`, dentro corpo da função, com o argumento `sep` definido como `,`, `;` e `\t`, respectivamente. Para detalhes sobre essas funções o *help* de cada uma. Uma vez que essas funções aceitam qualquer argumento da `read.table()` elas são mais convenientes que usar a `read.table()` e configurar os argumentos apropriados manualmente.
Alguns argumentos da função `read.table()` são:
* `file` nome do arquivo
* `header` lógico (TRUE ou FALSE) indicando se o arquivo tem ou não linha de cabeçalho
* `sep` um caractere indicando como as colunas são separadas
* `colClasses`, um vetor caractere indicando as classes de cada coluna no conjunto de dados
* `nrows`, número de linhas no conjunto de dados
* `comment.char`, um caractere indicando o caractere usado como comentário (para ignorar essas linhas)
* `skip`, o número de linhas que devem ser "puladas" desde o início do arquivo
* `stringsAsFactors`, lógico, as variáveis do tipo `character` devem ser codificadas como `factor`?
Esse último argumento pode ser definido também através da configuração global de opções no R pelo comando: `options(stringsAsFactors=FALSE)`.
Quando se faz a leitura de dados com `read.table("nome_do_arquivo")` o R automaticamente:
+ pula linhas que começam com '#'
+ descobre quantas linhas tem o arquivo e quanta memória precisa ser alocada
+ descobre qual o tipo de variável em cada coluna
Vamos ver alguns exemplos de leitura de dados hidrometeorológicos no formato texto amplamente usados em aplicações da Meteorologia.
### Dados hidrometeorológicos brasileiros
#### [hidroweb-ANA](http://hidroweb.ana.gov.br/)
O sistema hidroweb é o maior base de dados hidrológicos brasileira. No trecho de código a seguir baixamos um arquivo de dados de precipitação obtidos no sistema hidroweb que foi salvo no site do livro.
```{r hidroweb-B}
# arquivo de exemplo disponível no GitHub
hidroweb_url_file <- "https://raw.github.com/lhmet/adar-ufsm/master/data/CHUVAS.TXT"
#arquivo temporário, você pode substituir tempfile() por um caminho de seu computador, p.ex. "~/Downloads/CHUVAS.TXT"
hidroweb_dest_file <- tempfile()
download.file(
url = hidroweb_url_file,
destfile = hidroweb_dest_file
)
```
Antes de importar os dados você precisa visualizar o arquivo para extrair as informações básicas necessárias para sua importação. Você pode abri-lo em um editor de texto.
```{r Chunk410}
# caracteres não devem tratados como fatores
options(stringsAsFactors = FALSE)
# leitura de dados da ANA
dprec <- read.csv2(file = hidroweb_url_file,
skip = 15,
head = TRUE,
fill = TRUE)
# primeiras linhas
head(dprec)
# últimas linhas
tail(dprec)
# corrigindo nome da primeira coluna
names(dprec)[1] <- "EstacaoCodigo"
# removendo última coluna que só tem NAs
dprec <- dprec[ , -ncol(dprec)]
# estrutura dos dados
str(dprec)
# Fazendo a mesma leitura com read.table
dprec2 <- read.table(file = hidroweb_url_file,
skip = 15,
head = T,
stringsAsFactors = FALSE,
fill = T,
sep = ";",
dec = ",")
head(dprec2)
```
#### [BDMEP-INMET](http://www.inmet.gov.br/portal/index.php?r=bdmep/bdmep)
O Banco de Dados Meteorológicos para Ensino e Pesquisa do INMET é uma das principais fonte de dados climáticos brasileiros. Abaixo veremos como importar um arquivo de dados diários de uma estação meteorológica convencional. Os dados foram obtidos no BDMEP e salvos no site do livro.
No trecho de código a seguir baixamos o arquivo de dados da estação 83004.
```{r, bdmep-B}
# arquivo de exemplo disponível no GitHub
bdmep_url_file <- "https://raw.githubusercontent.com/lhmet/adar-ufsm/master/data/83004.txt"
#arquivo temporário, você pode substituir tempfile() por um caminho de seu computador, p.ex. "~/Downloads/CHUVAS.TXT"
bdmep_dest_file <- tempfile()
download.file(
url = bdmep_url_file,
destfile = bdmep_dest_file
)
```
```{r readbdmep-B}
x <- read.csv2(file = bdmep_dest_file,
header = FALSE,
skip = 16,
stringsAsFactors = FALSE,
na.strings = ""
)
head(x)
str(x)
```
Os dados lidos não incluíram a linha de cabeçalho com os nomes das variáveis. Nós pulamos essa linha porque o nome das variáveis está de acordo como número de colunas do arquivo. Então se tentarmos ler um arquivo de dados que contém linhas com número de registros diferentes ocorrerá um erro pois os dados não são tabulares.
Outro aspecto nos dados lidos é que aparecem vários `<NA>`, que é o símbolo para dados do tipo `character` faltantes. A razão dos terem sido interpretados dessa forma deve-se a um caractere (`</pre>`) encontrado na última linha do arquivo.
Para que os dados numéricos não sejam interpretados como caractere nós poderíamos executar a função `read.table(..., nrows = 5878)`, que ignoraria a última linha do arquivo e os dados seriam interpretados como `numeric`.
```{r readbdmep2-B}
x1 <- read.csv2(file=bdmep_dest_file,
header = FALSE,
skip = 16,
stringsAsFactors = FALSE,
dec = ".",
na.strings = "",
nrows = 5878
)
head(x1)
str(x1)
```
Outra alternativa seria converter as colunas de interesse (todas exceto as de 1 a 3) para `numeric` através da função `as.numeric()` usando a função `apply` ao longo das colunas:
```{r bdmep3-B}
# corrigindo classe dos dados
# convertendo de character para numeric
x[, -c(1:3)] <- apply(x[,-c(1:3)], 2, as.numeric)
str(x)
# razão dos avisos
#as.numeric("NA")
```
Mas e o nome das variáveis? Nós ignoramos a linha de cabeçalho por que nos dados do INMET ocorre uma variável denominada `VelocidadeVentoInsolacao`. Essa *string* deveria ser separada em duas. Vamos fazer essa adequação aos dados.
```{r bdmepclean-B}
# lendo somente o nome das variaveis
vnames <- read.csv2(file=bdmep_dest_file,
header = FALSE,
skip = 15,
stringsAsFactors = FALSE,
dec = ".",
na.strings = "",
nrows = 1)
# convertendo de dataframe para vetor
vnames <- c(t(vnames))
vnames
# número de variáveis é diferente do número de colunas do arquivo
length(vnames) == ncol(x)
# corrigindo nomes das variaveis
# substitui "VelocidadeVentoInsolacao" por "VelocidadeVento"
vnames[13] <- "VelocidadeVento"
# acresenta na 14a posição dos nomes a variável "insolacao" e
# desloca os elementos orginais do vetor
vnames <- c(vnames[1:13], "insolacao", vnames[14:length(vnames)])
length(vnames)
ncol(x)
names(x) <- vnames
head(x)
```
Finalmente vamos escrever os dados do INMET corretamente organizados.
```{r writebdmep-B}
bdmep_dest_file_clean <- file.path(tempdir(), "83004_clean.txt")
write.csv2(x,
file = bdmep_dest_file_clean,
na = "-9999",
row.names = FALSE)
```
### Arquivos formatados com largura fixa
Alguns arquivos texto com dados tabulares podem não conter separadores (para p.ex. economizar espaço de disco). Outros arquivos podem ser formatados usando largura fixa para reservar o espaço de cada variável, o que aumenta a legibilidade dos dados em editor de texto.
Nesses casos a função `read.fwf()` é conveniente. Vamos usar como exemplo o arquivo de dados do Índice de Oscilação Sul (SOI) obtido no site do [National Weather Service - Climate Prediction Center (NWS-CPC)](http://www.cpc.ncep.noaa.gov).
```{r fwf-B}
# link para os dados do SOI
noaa_url_file <- "http://www.cpc.ncep.noaa.gov/data/indices/soi"
```
Abrindo o link dos dados no navegador para visualização dos dados.
```{r opennoaa-B, eval=FALSE}
browseURL(url = noaa_url_file)
```
Leitura dos dados:
```{r readfwf-B}
#soi <- read.fwf(file = link, # nome do arquivo ou link
soi <- read.fwf(file = noaa_url_file, # sem internet, usar esse arquivo
skip = 4, # pula 4 linhas
header = FALSE, # sem cabeçalho
nrows = 70, # num. de linhas
widths = c(4, rep(6,12)), # largura dos campos das variáveis
na.strings = "-999.9", # string para dados faltantes
col.names = scan(noaa_url_file, # varredura do arquivo
#col.names = scan(link, # varredura do arquivo
what = "character", # tipo dos dados a serem lidos
skip = 3, # pula 3 linhas
nmax = 13) # num. max de registros a serem lidos
)
head(soi)
```
Vamos alterar a estrutura dos dados: ao invés dos dados serem distribuídos ao longo das colunas, vamos estruturá-los como série temporal, ou seja cada valor mensal corresponderá a uma linha.
```{r readsoi-B}
# converte a matriz de dados para um vetor (em sequencia cronológica)
soi_v <- c(t(soi[, -1]))
# criando um dataframe com valores de SOI, mes e ano
soi_df <- data.frame(ano = rep(soi$YEAR, each = 12),
mes = rep(1:12, length(soi[,1])),
soi = soi_v)
# escrevendo dados SOI em um arquivo CSV
soi_csv_file <- file.path(tempdir(), "SOI.csv")
write.csv(x = soi_df,
file = soi_csv_file,
na = "-999.9",
row.names = FALSE)
```
Vamos ler os dados reestruturados que foram salvos no formato [csv](http://en.wikipedia.org/wiki/Comma-separated_values) usando uma função que permite a escolha do arquivo de forma iterativa.
```{r filechoose-B, eval = FALSE}
# leitura de dados com escolha interativa do arquivo
soi.df <- read.csv(file = file.choose(),
# file.choose só é válido em sistema *unix
# no windows é choose.file()
header = TRUE,
na.strings = "-999.9")
```
Navegue até o diretório do arquivo `SOI.csv` e clique duas vezes sobre ele.
```{r soiread-B}
soi.df <- read.csv(file = soi_csv_file,
header = TRUE,
na.strings = "-999.9")
```
```{r soishow-B}
head(soi.df)
str(soi.df)
```
A função `read.fortran()` é uma função similar à `read.fwf()` e permite usar especificações de colunas no estilo [Fortran](http://en.wikipedia.org/wiki/Fortran).