2009-07-25 13 views
17

Ich habe einen Datenrahmen, der mehrere Zeitreihen von Returns enthält, die in Spalten gespeichert sind.Umformung von Zeitreihendaten vom Wide- zum Tall-Format (zum Plotten)

Die erste Spalte enthält Datumsangaben und nachfolgende Spalten sind unabhängige Zeitreihen mit jeweils einem Namen. Die Spaltenüberschriften sind die Variablennamen.

## 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 

Ich möchte auf einem separaten Grundstück jede Zeitreihe als eine Linie zeichnen, in einem Gitter, wobei jede Parzelle durch die Variablennamen gekennzeichnet.

mit Gittern Um dies zu plotten, müssen die Daten in einem großen Format, wie zum Beispiel:

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

Was für einen guten Funktionsaufruf ist, dies zu tun?

Antwort

16

Sie auch Schmelze verwenden können() von dem ‚umformen‘ Bibliothek (ich denke, es ist einfacher zu bedienen als selbst) zu umformen() - Sie können den zusätzlichen Schritt, dass spare die Zeit Spalt zurück in ...

> 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)) 

Für diese besondere Aufgabe hinzufügen zu müssen, jedoch würde ich mit der ‚Zoo‘ Bibliothek betrachtet , die keine Umformung des Datenrahmens erfordern würde:

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

R Entwickler/Mitwirkende (Gabor und Hadley in diesem Fall) haben uns mit vielen großen Möglichkeiten gesegnet.(Und kann nicht vergessen Deepayan für die Gitter Paket)

+0

Schmelze ist genau das, was ich gesucht habe. Stephen, könntest du deine Antwort so bearbeiten, dass sie den letzten Plotting-Schritt enthält? – medriscoll

+1

Nachdem ich eine Stunde mit der Funktion "stats :: reshape()" verschwendet habe, muss ich mich fragen, welche Medikamente einige der Leute, die R-Funktionen geschrieben haben, genommen haben. schmelzen() ist großartig. (noch einmal, danke Hadley) – forkandwait

9

Wenn es sich um eine multivariate Zeitreihe handelt, sollten Sie es als Zoo-Objekt speichern, indem Sie das Paket mit demselben Namen verwenden. Dies erleichtert das Indizieren, Zusammenführen, Unterteilen - siehe Zoo-Vignetten.

Aber wie Sie gefragt haben Gitter-Plots - und das kann auch getan werden. In diesem Beispiel haben wir ein einfaches ‚long‘ data.frame mit einer Datumsspalte, sowie einer Wertspalte ‚val‘ und einer variablen Spalte id ‚var‘ konstruieren:

> 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))) 

Da Datensatz Plotten pro Ihre Beschreibung ist für einen Plot von ‚durch variable gruppierte gegebenen Datenwert‘, indem er durch xyplot aus dem Gitter Paket getan, wo wir auf den Leitungen in jeder Platte drehen:

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

für einen Datenrahmen ‚Temp‘ mit dem Datum in die erste Spalte und die Werte in jeder der anderen Spalten:

> 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")) 
2

Vielen Dank für die Antworten Leute - Dirks Antwort war auf Mark.

Der fehlende Schritt erwies sich als "stack()" -Funktion, um den Datenrahmen von einem breiten in ein langes Format zu konvertieren. Ich bin mir bewusst, dass es einen einfacheren Weg gibt, dies mit der reshape() - Funktion zu tun, glücklich, ein Beispiel zu sehen, wenn jemand es posten möchte.

Also hier ist, was ich tun endete, mit dem ‚dat‘ Datenrahmen in der Frage erwähnt:

## 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) 
+2

Siehe auch aus dem reshape Paket Schmelze für von breit zu lange zu konvertieren. – hadley

12

Von tidyr gather Hilfeseite:

Beispiele

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) 
+9

Hmmm ... interessant. Es sieht aus wie tidyr sammeln Hilfeseite rekursiv Links zu dieser Frage und dieser Antwort. –

Verwandte Themen