[ACCEPTED]-Reshaping time series data from wide to tall format (for plotting)-time-series

Accepted answer
Score: 18

you can also use melt() from the 'reshape' library 9 (I think it's easier to use than reshape() itself) - that'll 8 save you the extra step of having to add 7 the time column back 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) )

For this particular 6 task, however, I would consider using the 5 'zoo' library, which would not require you 4 to reshape the data frame:

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

R developers/contributors 3 (Gabor and Hadley in this case) have blessed 2 us with many great choices. (and can't forget 1 Deepayan for the lattice package)

Score: 18

From tidyr gather help page:

Examples

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)

0

Score: 11

If it is a multivariate time series, consider 13 storing it as a zoo object by using the 12 package of the same name. This makes indexing, merging, subseting 11 a lot easier --- see the zoo vignettes.

But 10 as you asked about lattice plots -- and 9 this can also be done. In this example, we 8 construct a simple 'long' data.frame with 7 a date column, as well as a value column 6 'val' and a variable id column '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)))

Given 5 that dataset, plotting per your description 4 is done by xyplot from the lattice package 3 by asking for a plot of 'value given data 2 grouped by variable' where we turn on lines 1 in each panel:

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

For a dataframe 'temp' with the date in 2 the first column and values in each of the 1 other columns:

> 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") )
Score: 3

Many thanks for the answers folks - Dirk's 8 answer was on mark.

The missing step turned 7 out to be using "stack()" function to convert 6 the data frame from a wide to a long format. I'm 5 aware there may be an easier way to do this 4 with the reshape() function, happy to see 3 an example if someone wants to post it.

So 2 here's what I ended up doing, using the 1 'dat' dataframe mentioned in the question:

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

More Related questions