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

Posted

技术标签:

【中文标题】将时间序列数据从宽格式重塑为高格式(用于绘图)[重复]【英文标题】:Reshaping time series data from wide to tall format (for plotting) [duplicate] 【发布时间】:2010-11-13 22:36:54 【问题描述】:

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

第一列包含日期,随后的列是独立的时间序列,每个都有一个名称。列标题是变量名。

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

什么是一个好的函数调用来做到这一点?

【问题讨论】:

以防万一有人想在这里找到下面未提及的答案,这是在基础 R 中使用 reshape 函数的解决方案:reshape(dat, direction = "long", varying = 2:4, v.names = "price", idvar = "t", timevar = "symbol", times = names(dat)[2:4], new.row.names = 1:30) 【参考方案1】:

您还可以使用“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) )

但是,对于这个特定的任务,我会考虑使用“动物园”库,它不需要您重塑数据框:

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

R 开发人员/贡献者(在本例中为 Gabor 和 Hadley)为我们提供了许多很棒的选择。 (并且不能忘记格子包的 Deepayan)

【讨论】:

Melt 正是我想要的。斯蒂芬,你能编辑你的答案以包括最后一个绘图步骤吗? 在“stats::reshape()”函数上浪费了一个小时,我想知道一些编写 R 函数的人正在服用什么药物。融化()很棒。 (再次感谢哈德利)【参考方案2】:

来自tidyr gather帮助页面:

示例

library(tidyr)
library(dplyr)
# From http://***.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)

【讨论】:

嗯...有趣。看起来 tidyr 收集帮助页面递归地链接到这个问题和这个答案。 -time 在这个gather() 表达式中是什么意思? @TX 表示排除时间列。【参考方案3】:

如果是多变量时间序列,考虑使用同名包将其存储为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)))

鉴于该数据集,根据您的描述进行绘图是由 lattice 包中的 xyplot 通过要求绘制“给定数据按变量分组的值”的图来完成的,我们在每个面板中打开线:

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

【讨论】:

【参考方案4】:

对于数据框“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") )

【讨论】:

【参考方案5】:

非常感谢大家的回答 - Dirk 的回答是正确的。

原来缺少的步骤是使用“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)

【讨论】:

另请参阅从 reshape 包中熔化以从宽转换为长。

以上是关于将时间序列数据从宽格式重塑为高格式(用于绘图)[重复]的主要内容,如果未能解决你的问题,请参考以下文章

BigQuery 使用从宽到长的结构重塑表

如何将熊猫数据框从宽形拆分为高形

使用多个变量和一些时间不变将数据框从宽重塑为面板

R 中的重塑问题:我重塑的数据框将 3 个变量变为 1 个

在大查询中从宽到长重塑(标准 SQL)

将三列数据框重塑为矩阵(“长”到“宽”格式)[重复]