Rimodellare dati di serie temporali da largo formato altezza (per la stampa) [duplicare]
-
19-09-2019 - |
Domanda
Questa domanda ha già una risposta qui:
Ho un frame di dati contenente più serie storica dei rendimenti, memorizzato in colonne.
La prima colonna contiene le date e colonne successive sono serie temporali indipendenti ciascuno con un nome. Le intestazioni delle colonne sono i nomi delle variabili.
## 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
Voglio tracciare ogni serie tempo come una linea su un terreno separato, in un reticolo, con ogni appezzamento etichettato dai nomi delle variabili.
Per tracciare questo con reticolo, i dati devono essere in un formato alto, come ad esempio:
t symbol price
1 2009-01-01 X -1.8763317
2 2009-01-02 Y -0.1885183
2 2009-01-02 Z -6.655663
Che cosa è una buona funzione di chiamata a fare questo?
Soluzione
è possibile utilizzare anche melt () dal 'rimodellare' biblioteca (penso che sia più facile da usare rispetto Reshape () stesso) - che si risparmia il passaggio aggiuntivo di dover aggiungere la colonna volta nel ...
> 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) )
Per questo particolare compito, però, vorrei prendere in considerazione utilizzando la libreria 'zoo', che non richiedono di rimodellare la struttura dei dati:
> library(zoo)
> zobj <- zoo(dat[,-1],dat[,1])
> plot(zobj,col=rainbow(ncol(zobj)))
sviluppatori R / collaboratori (Gabor e Hadley in questo caso) ci hanno benedetto con molte grandi scelte. (E non può dimenticare Deepayan per il pacchetto reticolo)
Altri suggerimenti
tidyr raccogliere pagina di aiuto :
Esempi
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 si tratta di una serie temporale multivariata, considerare memorizzazione come un oggetto zoo utilizzando il pacchetto omonimo. Questo rende l'indicizzazione, la fusione, subseting molto più facile --- vedere le vignette zoo.
Ma, come hai chiesto di trame reticolo - e questo può anche essere fatto. In questo esempio, viene costruito un semplice 'lungo' data.frame con una colonna data, così come una colonna valore 'val' e una variabile id colonna '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)))
Dato che dataset, tracciando secondo la vostra descrizione è fatto da xyplot dal pacchetto reticolo chiedendo un terreno di 'dati di valore dato raggruppati per variabile' dove svoltiamo su linee in ogni pannello:
> library(lattice)
> xyplot(val ~ date | var, data=D, panel=panel.lines)
Per un dataframe 'temp' con la data nella prima colonna e valori in ciascuna delle altre colonne:
> 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") )
Molte grazie per le risposte gente - la risposta di Dirk era sul punto.
Il passaggio mancante risultò essere utilizzando "stack) (" la funzione di convertire il frame di dati da un bersaglio un formato lungo. Sono consapevole ci può essere un modo più semplice per fare questo con la funzione Reshape (), felice di vedere un esempio, se qualcuno vuole pubblicarlo.
Quindi, ecco quello che ho finito per fare, utilizzando il 'dat' dataframe menzionato nella domanda:
## 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)