Organizando dados com R

A linguagem R tem muitas funções que poupam um grande trabalho quando o assunto é organizar dados gravados em arquivos de texto. A rotina a seguir possui uma função para ler um arquivo CSV para organizar os dados em um data frame e depois juntar as colunas (excluindo valores inválidos, rotulados como ‘NA’):

le.csv = function(var,sistema) {
	# Definir nome e localização de arquivo conforme variável 'sistema'
	filepath = paste(diretorio,'/dados/',var,'_', sistema,'.csv', sep = '')
	# Definir formato de leitura de data
	setClass('myDate')
	setAs("character","myDate", function(from) as.Date(from, format="%Y-%m-%d"))
	# Ler arquivo CSV informado, de três colunas, sendo a primeira de data e as outras duas de dados numéricos com cabeçalho
	dados = read.csv(filepath, colClasses=c('myDate','numeric','numeric'), header = TRUE, as.is = TRUE)
	# Opção comentada substitui o valor -1 por NA, para depois eliminar essa linha
	#vol.obs = read.csv(filepath, colClasses=c('myDate','numeric','numeric'), header = TRUE, as.is = TRUE, na.strings='-1')
	# Eliminar linhas com NA
	dados = dados[complete.cases(dados),]
	# Arrumar dados em ordem cronológica
	dados = dados[order(as.Date(dados$data, format="%Y-%m-%d")),]
}

dados.var1 = le.csv(var1,sistema)
dados.var2 = le.csv(var2,sistema)
# Juntar as colunas
dados.obs = merge(dados.var1,dados.var2, by='data')

Um dos arquivos lidos tem três colunas (uma de data formato YYYY-MM-DD e outras duas de dados) e outro arquivo tem suas colunas (data e dados). O objetivo final do script deve resultar em um data frame com a data e duas colunas de dados (var1 e var2).

O comando “merge” une colunas utilizando uma coluna que esteja em ambas as data frames, identificada pelo parâmetro “by” (é possível usar mais de uma coluna em comum usando by=c(‘col1′,’col2’), por exemplo). Nesse caso, o comando junta as linhas com o mesmo valor de data exclui as linhas que não tenham o valor de data coincidente em ambas as data frames. Essa é a opção padrão, mas também é possível usar a opção “all = TRUE” para o efeito contrário: as linhas que não tenham correspondência não são excluídas, mas permanecem e recebem “NA” nas colunas que não possuam o valor. Usando a terminologia SQL, o primeiro caso corresponde ao “inner join” e o segundo, ao “outer join”; “all.x = TRUE” é um “left (outer) join” e “all.y = TRUE” é um “right (outer) join”.

Caso uma das colunas tenha menos dados que a outra, ou seja, tem datas sem dados para uma das variáveis, existe a possibilidade de interpolar esses valores. Para isso, utilize as seguintes linha no lugar do “merge” no script anterior:

# Conjunto com menos dados
zc = zoo(dados.var1$var1, dados.var1$data)
# Conjunto com mais dados
zs = zoo(dados.var2$var2, dados.var2$data)
# Como a série de var2 está "completa", o que faltar de data recebe NA no volume
z = merge(zs,zc)
# Interpola dados faltantes de var1 e substitui coluna
z$zc = na.approx(z$zc, rule=2)
dados.obs = z[index(zs),]
# Data inicial da série
dataini = index(tmin)[1]

Veja essa outra opção de interpolação na qual só existe um conjunto de dados horários com algumas horas faltantes. Deve-se criar também um vetor de datas para referência, sem falhas (datas_gabarito):

datas_gabarito = seq(ISOdate(year, month, day, hour = 0, min = 0, sec = 0, tz = "GMT"), by = "hour", length.out = N)
zs = zoo(seq(1,N),as.character(datas_gabarito))
zc = zoo(temp$var, as.character(temp$data))
z = merge(zs,zc) # Completa valores faltantes com NA
z$zc = na.approx(as.numeric(z$zc), rule=2) # Interpola para tirar NA
coluna = z[index(zs),]
coluna = coluna$zc # Seleciona somente dados, com a data como índice

Obs.: se aparecerem erros como “NAs introduzidos por coerção” ou “need at least two non-NA values to interpolate”, force o vetor a ser interpolado para ser numérico usando “as.numeric(VETOR)”.

A interpolação permite construir um novo conjunto de dados a partir de dados previamente conhecidos, permitindo assim “completar as lacunas” de dias sem valores observados ou com medidas espúrias, excluídas do conjunto de dados original. Clique no link para ver mais sobre interpolação usando um script em PHP para ficar mais claro como esse método funciona.

Dica sobre somar datas e horários: para somar cinco dias, basta transformar em formato date (1ª linha):

dia = as.Date("2016-06-30") + 5
CincoMinutos = chron("1970-01-01","00:05:00",format="y-m-d",out.format="y-m-d")
dia = as.Date("2016-06-30") + CincoMinutos

Já para somar cinco minutos (2ª e 3ª linhas), é possível usar o pacote “chron” e a função (de mesmo nome) para criar uma variável com esse tamanho, que é contabilizado desde o início de 1970.

One comment

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.