时间序列基本操作.docx
《时间序列基本操作.docx》由会员分享,可在线阅读,更多相关《时间序列基本操作.docx(25页珍藏版)》请在冰豆网上搜索。
![时间序列基本操作.docx](https://file1.bdocx.com/fileroot1/2023-1/10/b8451bb3-3a6a-4866-b396-47599be148a7/b8451bb3-3a6a-4866-b396-47599be148a71.gif)
时间序列基本操作
一.建立时间序列对象,表达时间序列数据
1zoo包和xts包,xts包是zoo包的超子集
2R的基础包里有ts对象,应用受限过多,一般不使用。
3日期和日期时刻(Date和Datetime)
日期可以表达(每)日数据,也可以表达(每)周,月,年数据
日期时刻可以表达日内数据
可以自由使用时间戳记(timestamps)用于解决日历日期(calendardata)
4创建时间序列对象
> library(zoo)
> ts<-zoo(x,dt)
或者
> library(xts)
> ts<-xts(x,dt)
dt是一个对应日期或日期时刻的向量,x是一个向量或数据框。
可以使用as.实现对象的转换。
R至少有8种表达时间序列的不同结构。
5dt可被称作指标(index)
zoo包中指标可以是任何有序值,如Date对象,POSIXct对象,整数甚至是浮点值。
xts包中的指标必须是一个可以支持日期或时间的类。
Date对象,POSIXct对象,chron对象,
还可以采用yearmonyearqtrdateTime对象。
例
> prices<-c(132.45,130.85,130.00,129.55,130.85)
> dates<-as.Date(c("2010-01-04","2010-01-05","2010-01-06",
+ "2010-01-07","2010-01-08"))
> ibm.daily<-zoo(prices,dates)
> print(ibm.daily)
2010-01-042010-01-052010-01-062010-01-072010-01-08
132.45130.85130.00129.55130.85
例以秒为时间单位(1second≈0.00027778hours)
> prices<-c(131.18,131.20,131.17,131.15,131.17)
> seconds<-c(9.5,9.500278,9.500556,9.500833,9.501111)
> ibm.sec<-zoo(prices,seconds)
> print(ibm.sec)
9.59.50039.50069.50089.5011
131.18131.20131.17131.15131.17
也可以把多个时间序列置于一个数据框,建立多元时间序列。
6对zoo和xts对象可以采用coredata来提取纯数据
> coredata(ibm.daily)
[1]132.45130.85130.000.00129.55
可以使用index提取时间
> index(ibm.daily)
[1]"2010-01-04""2010-01-05""2010-01-06""2010-01-07""2010-01-08"
7也可以参考Rmetrics的timeSeries包
二、作图
1.plot(x)可以处理一个或多个zoo和xts对象
对单个时间序列对象v可以使用plot(v,type="l")或plot.ts(v).
例
xlab="Date"
ylab="RelativePrice"
main="IBM:
Historicalvs.Inflation-Adjusted"
lty=c("dotted","solid")
ylim=range(coredata(ibm.infl))
#Plotthetwotimeseriesintwoplots
plot(ibm.infl,screens=c(1,2),lty=lty,main=main,xlab=xlab,ylab=ylab,ylim=ylim)
#Plotthetwotimeseriesinoneplot
以及
plot(ibm.infl,screens=1,lty=lty,main=main,xlab=xlab,ylab=ylab)
#Addalegend
legend(as.Date("1970-01-01"),140,
c("Hist","Infl-Adj"),
lty=c("dotted","solid"))
例中的数据是一个二元时间序列,一个显示IBM在1970年代的报价,一个是对应的经过通胀调整的价格。
2quantmod包里也有很多绘图的函数。
三、时间序列操作
1.提取最新和最老的观测
(1)最老的观测head()
最新的观测tail()
head(ibm)
1970-01-021970-01-051970-01-061970-01-071970-01-081970-01-09
364.75368.25368.50368.75369.50369.00
> tail(ibm)
1979-12-211979-12-241979-12-261979-12-271979-12-281979-12-31
64.0064.8764.8764.7564.2564.37
可以设置第2个参数显示更多 tail(ibm,20)
(2)xts包的first和last函数,使用日期来替代观测的序号。
> first(as.xts(ibm),"3weeks")
[,1]
1970-01-02364.75
1970-01-05368.25
1970-01-06368.50
1970-01-07368.75
1970-01-08369.50
1970-01-09369.00
1970-01-12367.75
1970-01-13374.13
1970-01-14373.75
1970-01-15381.50
1970-01-16369.75
> last(as.xts(ibm),"month")
[,1]
1979-12-0365.00
1979-12-0465.37
1979-12-0565.75
.
. (etc.)
.
1979-12-2764.75
1979-12-2864.25
1979-12-3164.37
2.创建时间序列的子集(很繁琐的一个东西)
ts[i]:
从单一个时间序列提取第i个观测
ts[j,i]:
从第j个时间序列提取第i个观测
可以通过一个数据对象来指示时间序列,要使用和你的时间序列指标同样的类型的对象
> ts[as.Date("yyyy-mm-dd ")]
也可以通过一个日期序列指示它
>dates<-seq(startdate , enddate, increment )
>ts[dates]
window函数可以通过开始和结束的日期选择一个范围
>window(ts,start=startdate ,end=enddate)
这个函数用来选择一个连续日期范围是更容易的
window(ibm.daily,start=as.Date('2010-01-05'),end=as.Date('2010-01-07'))
2010-01-052010-01-062010-01-07
130.85130.00129.55
有时候通过日期来进行选择是更有用的,我们的指标由Date对象建立,所以可以使用一个Date对象标记时间序列的下标(如果指标是建立于POSIXct对象,也可用一个POSIXct对象)
ibm.daily[as.Date('2010-01-05')]
2010-01-05
130.85
也可以通过来自Date对象的一个向量进行选择
window(ibm.daily,start=as.Date('2010-01-05'),end=as.Date('2010-01-07'))
2010-01-052010-01-062010-01-07
130.85130.00129.55
3.合并时间序列
(1)使用zoo对象,用merge函数合并它们
> merge(ts1,ts2)
当两个时间序列有不同的时间戳记的时候,merge函数调和了不同日期数据的混乱细节
例
> ibm
1970-01-021970-01-051970-01-061970-01-071970-01-081970-01-091970-01-12
364.75368.25368.50368.75369.50369.00367.75
.
. (etc.)
.
1979-12-211979-12-241979-12-261979-12-271979-12-281979-12-31
64.0064.8764.8764.7564.2564.37
> cpi
1970-01-011970-02-011970-03-011970-04-011970-05-011970-06-011970-07-01
37.838.038.238.538.638.839.0
.
. (etc.)
.
1979-05-011979-06-011979-07-011979-08-011979-09-011979-10-011979-11-01
71.572.373.173.874.675.275.9
1979-12-01
76.7
> merge(ibm,cpi)
ibmcpi
1970-01-01NA37.8
1970-01-02364.75NA
1970-01-05368.25NA
1970-01-06368.50NA
1970-01-07368.75NA
1970-01-08369.50NA
.
. (etc.)
.
默认的,merge寻找所有数据的单位(union):
输出包括所有来自输入的数据,缺失的观测用NA值填上
(2)利用zoo包的na.locg函数,可以把这些NA用最近的观测代替。
> na.locf(merge(ibm,cpi)))
ibmcpi
1970-01-02364.7537.8
1970-01-05368.2537.8
1970-01-06368.5037.8
1970-01-07368.7537.8
1970-01-08369.5037.8
1970-01-09369.0037.8
.
. (etc.)
.
locf代表继承的最后观测,注意它排除了第一个观测,因为那天没有IBM股价
可以通过设定all=FALSE来交叉所有的数据。
> merge(ibm,cpi,all=FALSE)
ibmcpi
1970-04-01337.7538.5
1970-05-01296.7538.6
1970-06-01287.0038.8
1970-07-01254.0039.0
1970-09-01263.8839.2
1970-10-01297.0039.4
.
. (etc.)
.
注意交叉始于4月1日因为当年前3月的1日都是假期。
4.填充一个时间序列
用缺失的数据和时间创建一个0宽度对象(zoo包),然后把它和要填充的时间序列合并
> empty<-zoo(,dates ) #'dates'isvectorofthemissingdates
> merge(ts,empty,all=TRUE)
这个对象不包括数据,只有日期,可以用来填满其他的时间序列。
例
> cpi
1970-01-011970-02-011970-03-011970-04-011970-05-011970-06-01
37.838.038.238.538.638.8
.
. (etc.)
.
1979-07-011979-08-011979-09-011979-10-011979-11-011979-12-01
73.173.874.675.275.976.7
创建0宽度对象
> dates<-seq(from=as.Date("1970-01-01"),to=as.Date("1979-12-31"),by=1)
> empty<-zoo(,dates)
合并
> filled.cpi<-merge(cpi,empty,all=TRUE)
> filled.cpi
1970-01-011970-01-021970-01-031970-01-041970-01-051970-01-061970-01-07
37.8NANANANANANA
1970-01-081970-01-091970-01-101970-01-111970-01-121970-01-131970-01-14
NANANANANANANA
1970-01-151970-01-161970-01-171970-01-181970-01-191970-01-201970-01-21
NANANANANANANA
1970-01-221970-01-231970-01-241970-01-251970-01-261970-01-271970-01-28
NANANANANANANA
1970-01-291970-01-301970-01-311970-02-011970-02-021970-02-031970-02-04
NANANA38.0NANANA
.
.
用最接近的的观测值替代NA
> filled.cpi<-na.locf(merge(cpi,empty,all=TRUE))
> filled.cpi
1970-01-011970-01-021970-01-031970-01-041970-01-051970-01-061970-01-07
37.837.837.837.837.837.837.8
1970-01-081970-01-091970-01-101970-01-111970-01-121970-01-131970-01-14
37.837.837.837.837.837.837.8
1970-01-151970-01-161970-01-171970-01-181970-01-191970-01-201970-01-21
37.837.837.837.837.837.837.8
1970-01-221970-01-231970-01-241970-01-251970-01-261970-01-271970-01-28
37.837.837.837.837.837.837.8
1970-01-291970-01-301970-01-311970-02-011970-02-021970-02-031970-02-04
37.837.837.838.038.038.038.0
.
. (etc.)
四、时间序列的运算
1.滞后一个时间序列数据(lagging)
向前或向后转换时间序列的时间。
> lag(ts,k)
k正的k值可以把数据向前移(明天的数据变成今天的)负值可以把数据向后移。
例
> ibm.daily
2010-01-042010-01-052010-01-062010-01-072010-01-08
132.45130.85130.00129.55130.85
> lag(ibm.daily,k=+1,na.pad=TRUE)
2010-01-042010-01-052010-01-062010-01-072010-01-08
130.85130.00129.55130.85NA
> lag(ibm.daily,k=-1,na.pad=TRUE)
2010-01-042010-01-052010-01-062010-01-072010-01-08
NA132.45130.85130.00129.55
2.计算连续差分(successivedifferences)
两个连续观测的差分
diff(x)
差分适用于向量和zoo对象。
对一个zoo对象,差分的结果仍然是zoo对象,并且仍有正确的日期
例
> ibm.daily
2010-01-042010-01-052010-01-062010-01-072010-01-08
132.45130.85130.00129.55130.85
> diff(ibm.daily)
2010-01-052010-01-062010-01-072010-01-08
-1.60-0.85-0.451.30
可以通过lag参数,计算更宽空间的差分。
例
> head(cpi,24)
1970-01-011970-02-011970-03-011970-04-011970-05-011970-06-011970-07-01
37.838.038.238.538.638.839.0
1970-08-011970-09-011970-10-011970-11-011970-12-011971-01-011971-02-01
39.039.239.439.639.839.839.9
1971-03-011971-04-011971-05-011971-06-011971-07-011971-08-011971-09-01
40.040.140.340.640.740.840.8
1971-10-011971-11-011971-12-01
40.940.941.1
> diff(cpi,lag=12) #Computeyear-over-yearchange
1971-01-011971-02-011971-03-011971-04-011971-05-011971-06-011971-07-01
2.01.91.81.61.71.81.7
1971-08-011971-09-011971-10-011971-11-011971-12-011972-01-011972-02-01
1.81.61.51.31.31.31.4
.
. (etc.)
3.在时间序列上运用计算
可以使用算术运算符和常用函数
例
计算ibm股价上的百分比改变,利用价格除以每日的变化
他们有不同的开始时间和不同的长度,但是R会对齐序列返回一个zoo对象
> ibm.daily
2010-01-042010-01-052010-01-062010-01-072010-01-08
132.45130.85130.00129.55130.85
> diff(ibm.daily)
2010-01-052010-01-062010-01-072010-01-08
-1.60-0.85-0.451.30
> diff(ibm.daily)/ibm.daily
2010-01-052010-01-062010-01-072010-01-08
-0.012227742-0.006538462-0.0034735620.009935040
注意日期的变化
计算对数的价格差分
> diff(log(ibm.daily))
2010-01-052010-01-062010-01-072010-01-08
-0.012153587-0.006517179-0.0034675430.009984722
4.通过日历周期来运用函数(ApplyingaFunctionbyCalendarPeriod)
利用周月年等来组织内容,并对每个组来运用函数。
xts包提供了有关函数
> apply.daily(ts , f)
> apply.weekly(ts , f)
> apply.monthly(ts , f)
> apply.quarterly(ts , f)
> apply.yearly(ts , f)
或
> apply.monthly(as.xts(ts ), f)
ts是xts时间序列,而f是运用到每天,周月季年的函数
例
设有一个5年的ibm历史数据,存在zoo对象中
> head(ibm)
1970-01-021970-01-051970-01-061970-01-071970-01-081970-01-09
364.75368.25368.50368.75369.50369.00
可以计算平均价格
> apply.monthly(as.xts(ibm),mean)
[,1]
1970-01-30359.8843
1970-02-27346.8684
1970-03-31327.4348
.
. (etc.)
.
1974-10-31176.4791
1974-11-29181.0570
1974-12-31167.9233
其中首先要把zoo对象转换为xts对象
例
计算波动性
apply.monthly(as.xts(diff(log(ibm))),sd)这是按月的结果
以天数为倍数估计年化波动性
sqrt(251)*apply.monthly(as.xts(diff(log(ibm))),sd)
图示
> plot(sqrt(251)*apply.monthly(as.xts(diff(log(ibm))),sd),
+ main="IBM:
MonthlyVolatility",
+ ylab="Stddev,annualized")
5.运用滚动函数
将一个函数以,以某种滚动方式运用到时间序列上:
计算一个数据点的函数值,然后移到下一个点,
在那个点计算函数,再移到下一个点。
>library(zoo)
>rollapply(ts , width, f)
时间戳的选择:
align=“right” 来避免让f来计算那些没有包含在时间序列中的历史数据。
>rollapply(ts , width, f,align="right")
align=“right”时间戳取自最右边的值
align=“left”时间戳取自最左边的值
默认的align=“center”
by=n参数
不是连续计算,是跳跃计算,by值等于窗宽。
例
计算滚动的标准差
> sds<-rollapply(ts,30,sd,by=30,align="right")
rollapply输出会比输入短,可以设置na.pad