Remodelando dados de séries temporais de largura para o formato de altura (para plotagem) [duplicado]

StackOverflow https://stackoverflow.com/questions/1181060

  •  19-09-2019
  •  | 
  •  

Pergunta

Esta questão já tem uma resposta aqui:

I tem uma estrutura de dados contendo várias séries de tempo de retorno, armazenados em colunas.

A primeira coluna contém datas e colunas subseqüentes são séries de tempo independentes, cada uma com um nome. Os cabeçalhos de coluna são os nomes de variáveis.

## I have a data frame like this
t <- seq(as.Date('2009-01-01'),by='days',length=10)
X <- rnorm(10,0,1)
Y <- rnorm(10,0,2)
Z <- rnorm(10,0,4)

dat <- data.frame(t,X,Y,Z)

## which appears as
           t          X          Y         Z
1 2009-01-01 -1.8763317 -0.1885183 -6.655663
2 2009-01-02 -1.3566227 -2.1851226 -3.863576
3 2009-01-03 -1.3447188  2.4180249 -1.543931

Eu quero traçar cada série temporal como uma linha em um terreno separado, em uma rede, com cada parcela rotulado pelos nomes de variáveis.

Para traçar este com estrutura, os dados devem estar em um formato de altura, como tal:

           t symbol       price
1 2009-01-01      X -1.8763317
2 2009-01-02      Y -0.1885183
2 2009-01-02      Z -6.655663

O que é uma boa chamada de função para fazer isso?

Foi útil?

Solução

Você também pode usar fusão () da biblioteca 'remodelar' (eu acho que é mais fácil de usar do que remodelar () em si) - que vai lhe poupar a etapa extra de ter que adicionar a coluna para trás o tempo em ...

> library(reshape)
> m <- melt(dat,id="t",variable_name="symbol")
> names(m) <- sub("value","price",names(m))
> head(m)
           t symbol       price
1 2009-01-01      X -1.14945096
2 2009-01-02      X -0.07619870
3 2009-01-03      X  0.01547395
4 2009-01-04      X -0.31493143
5 2009-01-05      X  1.26985167
6 2009-01-06      X  1.31492397
> class(m$t)
[1] "Date"
> library(lattice)                                                              
> xyplot( price ~ t | symbol, data=m ,type ="l", layout = c(1,3) )

Para esta tarefa particular, no entanto, eu consideraria usando a biblioteca 'zoo', o que não seria necessário que você remodelar o quadro de dados:

> library(zoo)                                                                  
> zobj <- zoo(dat[,-1],dat[,1])                                                 
> plot(zobj,col=rainbow(ncol(zobj))) 

desenvolvedores R / contribuintes (Gabor e Hadley, neste caso) tem nos abençoado com muitas ótimas opções. (E não podemos esquecer Deepayan para o pacote de rede)

Outras dicas

A partir tidyr recolher página de ajuda :

Exemplos

library(tidyr)
library(dplyr)
# From http://stackoverflow.com/questions/1181060
stocks <- data.frame(
  time = as.Date('2009-01-01') + 0:9,
  X = rnorm(10, 0, 1),
  Y = rnorm(10, 0, 2),
  Z = rnorm(10, 0, 4)
)

gather(stocks, stock, price, -time)
stocks %>% gather(stock, price, -time)

Se for uma série temporal multivariada, considere armazená-lo como um objeto zoológico usando o pacote com o mesmo nome. Isso faz com que a indexação, fusão, subseting muito mais fácil --- ver as vinhetas do jardim zoológico.

Mas, como você perguntou sobre parcelas de treliça - e isso também pode ser feito. Neste exemplo, nós construímos um simples 'long' data.frame com uma coluna de data, bem como uma coluna de valor 'val' e uma coluna ID variável 'var':

> set.seed(42)
> D <- data.frame(date=rep(seq(as.Date("2009-01-01"),Sys.Date(),by="week"),2),\
                  val=c(cumsum(rnorm(30)), cumsum(rnorm(30))), \
                  var=c(rep("x1",30), rep("x2",30)))

Dado esse conjunto de dados, plotagem por sua descrição é feita por xyplot do pacote de rede pedindo um lote de 'dados de valor dada agrupadas por variável' em que se transformam em linhas em cada painel:

> library(lattice)
> xyplot(val ~ date | var, data=D, panel=panel.lines)

Para uma trama de dados 'temp' com a data na primeira coluna e os valores em cada uma das outras colunas:

> par(mfrow=c(3,4)) # 3x4 grid of plots
> mapply(plot,temp[,-1],main=names(temp)[-1],MoreArgs=list(x=temp[,1],xlab="Date",type="l",ylab="Value") )

Muito obrigado para o pessoal respostas - A resposta de Dirk foi na marca.

O passo que falta acabou por ser usando a função "pilha ()" para converter o quadro de dados a partir de uma ampla para um formato longo. Estou ciente de que pode haver uma maneira mais fácil de fazer isso com a função de remodelagem (), o prazer de ver um exemplo, se alguém quiser publicá-la.

Então, aqui está o que eu acabei fazendo, usando o 'dat' trama de dados mencionado na pergunta:

## use stack() to reshape the data frame to a long format
## <time> <stock> <price>
stackdat <- stack(dat,select=-t) 
names(stackdat) <- c('price','symbol')

## create a column of date & bind to the new data frame
nsymbol <- length(levels(stackdat$symbol))  
date <- rep(dat$t, nsymbol)  
newdat <- cbind(date,stackdat)

## plot it with lattice
library(lattice)
xyplot(price ~ date | symbol,  ## model conditions on 'symbol' to lattice
       data=newdat,            ## data source
       type='l',               ## line
       layout=c(nsymbol,1))    ## put it on a single line

## or plot it with ggplot2
library(ggplot2)
qplot(date, price, data = newdat, geom="line") + facet_grid(. ~ symbol)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top