第 3 章 高性能时间序列分析
3.1 创建时间序列对象的性能测试
所需 R 包。
定义一个 systemTime 函数来度量各种操作的效率。
systemTime <-function(expr, gcFirst = TRUE, n = 20) {
time <-sapply(integer(n), eval.parent(substitute(function(...)
system.time(expr, gcFirst = gcFirst))))
structure(apply(time, 1, median), class = "proc_time")
}
基于字符型时间戳,创建一个时期跨度为 100 年,列数为 5 的日时间序列对象需要多长时间?
R 会从 ASCII 格式,网页,或者 xls 与 csv 文件中读入时间序列数据后,通常将数据存储为字符串。
为了将字符串转化为 zoo、xts 或者 timeSeries 对象,需先将时间戳转化为合适的标签。考虑一个时期跨度为 100 年、共 35000 条记录的日时间序列数据。
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"),
to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
zoo:
## user system elapsed
## 0.0515 0.0000 0.0530
xts:
timeSeries:
## user system elapsed
## 0.196 0.003 0.202
3.1.1 基于日期型时间戳,创建一个时期跨度为 100 年、列数为 5 的日时间序列对
象需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"),
to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
index <-as.Date(charvec)
class(index)
## [1] "Date"
zoo:
## user system elapsed
## 0.006 0.000 0.006
这是基于 zoo 包创建时间序列对象的基本方法。
xts:
## user system elapsed
## 0.001 0.000 0.001
这是基于 xts 包创建时间序列对象的基本做法。
timeSeries:
## user system elapsed
## 0.003 0.000 0.003
鉴于金融时间序列分析的对象大都是 timeDate 对象,下面的操作效率可以作为一个效率基准。
3.1.2 基于 GMT POSIXct 时间戳,创建一个时期跨度为 100 年、列数为 5 的日时间序列对象需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"),
to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
index <-as.POSIXct(charvec, tz = "GMT")
class(index)
## [1] "POSIXct" "POSIXt"
zoo:
## user system elapsed
## 0.006 0.000 0.006
xts:
## user system elapsed
## 0.000 0.000 0.001
timeSeries:
## user system elapsed
## 0.003 0.000 0.003
3.1.3 基于非 GMT POSIXct 时间戳,创建一个时期跨度为 100 年、列数为 5 的日时间序列对象需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"),
to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
#index <-as.POSIXct(charvec, tz = "CET")
#class(index)
zoo:
## user system elapsed
## 0.006 0.000 0.006
xts:
## user system elapsed
## 1e-03 0e+00 5e-04
timeSeries:
## user system elapsed
## 0.003 0.000 0.003
3.1.4 基于 timeDate 型时间戳,创建一个时期跨度为 100 年、列数为 5 的日时间序列对象需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"), to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
index <-timeDate(charvec)
class(index)
## [1] "timeDate"
## attr(,"package")
## [1] "timeDate"
zoo:
## user system elapsed
## 0.0060 0.0000 0.0065
xts:
## user system elapsed
## 0.001 0.000 0.001
timeSeries:
## user system elapsed
## 0.001 0.000 0.001
3.2 对时间序列取子集的操作性能
所需 R 包。
定义一个 systemTime 函数来度量各种操作性能。
systemTime <-function(expr, gcFirst = TRUE, n = 20) {
time <-sapply(integer(n), eval.parent(substitute(function(...)
system.time(expr, gcFirst = gcFirst))))
structure(apply(time, 1, median), class = "proc_time")
}
3.2.1 基于整数,对时期跨度为 100 年,列数为 5的日时间序列对象进行取子集操作需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"),
to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
index <-charvec
length <-floor(length(charvec)/2)
subset <-sample(charvec)[1:length]
zoo:
## user system elapsed
## 0.089 0.002 0.093
xts:
该操作耗时巨大!
timeSeries:
## user system elapsed
## 0.113 0.002 0.117
3.2.2 基于 Date 对象,对时期跨度为 100 年,列数为 5 的日时间序列对象进行取子集操作需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"),
to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
index <-as.Date(charvec)
length <-floor(length(charvec)/2)
subset <-as.Date(sample(charvec)[1:length])
zoo:
## user system elapsed
## 0.0060 0.0010 0.0065
xts:
该操作耗时巨大。
timeSeries:
## user system elapsed
## 0.006 0.000 0.006
3.2.3 基于 Date 对象,对一个时期跨度为 100 年,列数为 5 的 GMT POSIXct 格式的日时间序列进行取子集操作需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"),
to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
index <-as.POSIXct(charvec, tz = "GMT")
length <-floor(length(charvec)/2)
subset <-as.POSIXct(sample(charvec)[1:length], tz = "GMT")
zoo:
## user system elapsed
## 0.005 0.001 0.007
xts:
该操作耗时巨大!
timeSeries:
## user system elapsed
## 0.006 0.000 0.006
3.2.4 基于 Date 对象,对一个时期跨度为 100 年,列数为 5 的非 GMT POSIXct 格式的日时间序列进行取子集操作需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"),
to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
index <-as.POSIXct(charvec, format="%Y-%m-%d",tz = "CET")
length <-floor(length(charvec)/2)
subset <-as.POSIXct(sample(charvec)[1:length], tz = "GMT")
zoo:
## Warning in zoo(data, index): some methods for
## "zoo" objects do not work if the index entries in
## 'order.by' are not unique
## user system elapsed
## 0.003 0.000 0.003
xts:
该操作耗时巨大!
timeSeries:
这里有问题。
3.2.5 基于 Date 对象,对一个时期跨度为 100 年,列数为 5 的以 GMT timeDate 对象形式存储的日时间序列进行取子集操作需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"), to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
index <-timeDate(charvec)
length <-floor(length(charvec)/2)
subset <-timeDate(sample(charvec)[1:length])
zoo:
## user system elapsed
## 0.006 0.001 0.007
zoo 会自动经 fCalendar 包调用旧版本的 timeDate 函数,因此要 detach。
xts:
该操作耗时巨大!
timeSeries:
## user system elapsed
## 0.004 0.000 0.004
3.2.6 基于 Date 对象,对一个时期跨度为 100 年,列数为 5 的以 GMT timeDate 对象形式存储的日时间序列进行取子集操作需要多长时间?
常规数据
charvec <-format(seq(from = as.Date("1901-01-01"), to = as.Date("1999-12-31"), by = "day"))
data <-matrix(rnorm(length(charvec)*5), ncol = 5)
index <-timeDate(charvec, zone = "Zurich", FinCenter = "Zurich")
length <-floor(length(charvec)/2)
subset <-timeDate(sample(charvec)[1:length], zone = "Zurich",FinCenter = "Zurich")
zoo:
## user system elapsed
## 0.006 0.001 0.007
xts:
timeSeries:
## user system elapsed
## 0.005 0.000 0.005