将时间序列数据从广泛的格式转换为高格式(用于绘图)
我有一个数据框包含多个时间序列的回报,存储在列中。
第一列包含date,随后的列是独立的时间序列,每个都有一个名称。 列标题是variables名称。
## 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 XYZ 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
我想把每个时间序列作为一个单独的图上的一条线,以一个格子来表示,每个图都用variables名标记。
为了用格子来绘制这个数据,数据必须是高格式的,例如:
t symbol price 1 2009-01-01 X -1.8763317 2 2009-01-02 Y -0.1885183 2 2009-01-02 Z -6.655663
什么是一个好的函数调用来做到这一点?
你也可以使用'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在这种情况下)已经为我们提供了许多很好的select。 (也不能忘记Deepayan的格子包)
从tidyr收集帮助页面:
例子
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)
如果它是多variables时间序列,请考虑使用相同名称的包将其存储为动物园对象。 这使索引,合并,更容易 – 看动物园的小插曲。
但是,当你问格子图 – 这也可以做到。 在这个例子中,我们用一个date列,以及一个值列“val”和一个variablesid列“var”构造一个简单的'long'data.frame:
> 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完成的,方法是询问在每个面板中打开行的“给定值的数据按variables分组”
> library(lattice) > xyplot(val ~ date | var, data=D, panel=panel.lines)
对于第一列中的date和每个其他列中的值的数据框“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") )
非常感谢答案的人 – 德克的答案是在标记。
缺less的步骤竟然是使用“stack()”函数将dataframe从宽格式转换为长格式。 我知道可能有一个更简单的方法来做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)