首页 文章

从宽到高格式重塑时间序列数据(用于绘图)[重复]

提问于
浏览
18

这个问题在这里已有答案:

我有一个包含多个时间序列返回的数据框,存储在列中 .

第一列包含日期,后续列是独立的时间序列,每个列都有一个名称 . 列 Headers 是变量名称 .

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

我想将每个时间序列绘制成一个单独的图上的一条线,在一个点阵中,每个图用变量名标记 .

要使用晶格绘制此图,数据必须采用高格式,如下所示:

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

这样做有什么好的函数调用?

5 回答

  • 3

    你也可以使用'reshape'库中的melt()(我认为它比reshape()本身更容易使用) - 这将为你节省额外的步骤,即必须添加时间列...

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

    但是,对于这个特殊的任务,我会考虑使用'zoo'库,它不需要你重塑数据框:

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

    R开发者/贡献者(在这种情况下是Gabor和Hadley)祝福我们有很多很棒的选择 . (并且不能忘记Deepayan的格子包)

  • 9

    来自tidyr gather帮助页面:

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

    如果它是多变量时间序列,请考虑使用相同名称的包将其存储为zoo对象 . 这使索引,合并,子菜单变得更加容易 - 参见动物园的小插曲 .

    但是当你问到格子图时 - 这也可以做到 . 在这个例子中,我们构造了一个带有日期列的简单“long”data.frame,以及一个值列'val'和一个变量id列'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)))
    

    给定数据集,根据您的描述绘制是通过格子包中的xyplot完成的,通过询问“按变量分组的值给定数据”的图,我们在每个面板中打开线:

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

    对于具有第一列中的日期和其他每列中的值的数据框“temp”:

    > 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") )
    
  • 12

    非常感谢答案的人 - 德克的回答是标记 .

    缺少的步骤结果是使用“stack()”函数将数据帧从宽格式转换为长格式 . 我知道使用reshape()函数可能有一种更简单的方法,如果有人想要发布它,很高兴看到一个例子 .

    所以这就是我最终做的事情,使用问题中提到的'dat'数据框:

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

相关问题