R语言时间序列数据应用xts
zoo是时间序列的基础库,是面向通用的设计。 xts 是对时间序列库(zoo) 的一种扩展实现。xts 类型继承了zoo 类型,丰富了时间序列数据处理的函数。
一、xts对象的结构和定义
1、xts对象是一个具有时间索引的观测值矩阵,结构如下:
xts = matrix + times
2、创建xts对象,函数如下:
xts (x= , order.by= , … )
参数 x : 数据,必须是一个向量或者矩阵;
order.by: 索引(index),是一个与x行数相同的升序排列的时间对象。
创建示例:
data <- rnorm(5)
dates <- seq(as.Date("2016-01-01"), length = 5, by = "days")
smith <- xts(x = data, order.by = dates)
3、属性(Attr)
xts允许数据绑定任意键值属性,可用来保存对象的元数据。创建xts对象时添加属性,只需要将name=value参数传送给xts()函数。
#使用 POSIXct日期类对象创建bday
bday <- as.POSIXct("1899-05-08")
# 创建xts对象,并新增born属性
hayek <- xts(x = data, order.by = dates, born = bday)
4、分解xts对象
xts 和 zoo的核心是一个简单的R矩阵和一些附加属性,最重要的属性是索引( index)。索引包含了将数据作为时间序列的所有信息。
coredata() 获取xts对象中的矩阵部分。
index() 获取xts对象的index部分。
5、转换成xts对象
as.xts()
6、xts与其他时间序列的主要区别
xts与R大部分其他时间序列对象的主要区别是: xts可以使用表示时间的任何类,不管是POSIXct, Date 还是其他类,xts将它们转换成一种内部格式,使用户尽可能自然地选取子集。
a <- xts(x = 1:2, as.Date("2012-01-01") + 0:1)
a[index(a)]
7、索引的属性
查看索引的类别 indexClass()
查看索引的时区 indexTZ()
显示或修改索引时间格式 indexFormat()
# 修改时间表示格式
indexFormat(temps) <- "%m/%d/%Y"
tzone(), 用于提取或设置时区。
tzone(x) <- "Time_Zone"
Xts对象的索引的原始向量是自UNIX纪元(1970-01-01)以来的累计秒数的向量
.index()可获取索引的原始向量。
以下函数用于提取类似于POSIXlt 类型的时间组件:
.indexday()
.indexmon()
.indexyear()
#创建一个周末日期索引
index <- which(.indexwday(temps) == 0 | .indexwday(temps) == 6)
二、输入和输出xts数据
1、实际应用中从硬盘或者网络中读取数据。
例如,硬盘中的tmp_file文件的内容如下:
a,b
1/02/2015, 1, 3
2/03/2015, 2, 4
输入示例1:
# 读取tmp_file文件
dat<-read.csv(tmp_file)
#将dat转换成xts格式
xts(dat, order.by = as.Date(rownames(dat), "%m/%d/%Y"))
输入示例2:
#使用read.zoo读取tmp_file文件
dat_zoo <- read.zoo(tmp_file, index.column = 0, sep = ",", format
= "%m/%d/%Y")
#将dat_zoo转换成xts
dat_xts <- xts(dat_zoo)
输入示例3:
# FUN = as.yearmon将时间字符串转换成更合适的时间类。
sun <- read.zoo(tmp_file, sep = ",", FUN = as.yearmon)
# 转换成xts对象
sun_xts<-xts(sun)
2、 输出xts对象
主要有两种方式:
1、使用saveRDS() 和readRDS() 将单个R对象序列化。
2、使用 zoo中的函数 write.zoo()
#获取临时文件名
tmp <- tempfile()
#使用zoo将xts对象写入tmp文件
write.zoo(data_xts, sep = ",", file = tmp)
三、查询时间范围
1、查询日期范围
Xts可快速有效地确定日期和时点范围的子集,并提取相应的观测值。
使用特殊字符和日期搭配就可提取xts对象的日期范围。
A["20090825"] ## 20090825
A["201203/201212"] ## 201203至201212
A["/201601"] ## 自 201601开始
2、提取每日时间间隔
# 选取所有日期9:30-16:00之间的观测值
NYSE["T09:30/T16:00"]
3、观测值的更新或替换
# 将dates向量中对应的观测值设置为NA
x[dates] <- NA
# 自2016-06-09至今的观测值修改为0
x["2016-06-09/"] <- 0
4、定位时间周期的开始和结束
last(temps, "1 week")
last(lastweek, 2)
first(lastweek, "-2 days")
可以将first()和last()组合起来使用
#第1周的后3天
last(first(Temps, '1 week'), '3 days')
5、查看时间周期性和次数
periodicity() 查看时间序列的周期
ndays() , nmonths(), nquarters() 查看周期的次数
四、xts对象的合并运算
xts objects在做数学计算时,会遵循时间并且只返回有时间交集的数据。
1、用merge按列合并xts
merge()将一个或多个序列按列合并。适用于按固定日期来规范观测值。
merge(a, b, join = "right", fill = 9999)
3个关键参数:
... :用于合并的任意个的对象
Join :规定如何合并序列,例如inner或left方式。
Fill : 规定如何设置序列合并后出现的缺失值
2、用rbind按行合并xts
合并结果按时间升序排列
五、观测值的NA值处理
1、前一个或下个观测值结转法
取缺失值的前一个观测值来填补缺失值。可防止先窥偏差(look-ahead bias)
# 使用上个观测值
na.locf(x)
#设置fromLast = TRUE,可使用下个观测值填补空缺
na.locf(x, fromLast = TRUE)
2、使用na.approx()插补缺值
na.approx()基于两点之间的简单线性插值,数据点使用索引值之间的距离来估算,估算值在时间上是线性的。
六、时间序列操作
1、偏移函数lag()
k是偏移的步长。在xts中,k为正,序列的观测值将向下(时间后方)偏移;k为负,观测值将向上偏移。Zoo与xts相反。
> a
[,1]
2016-01-01 1
2016-01-02 2
2016-01-03 3
> lag(a)
[,1]
2016-01-01 NA
2016-01-02 1
2016-01-03 2
> lag(a,k=-1)
[,1]
2016-01-01 2
2016-01-02 3
2016-01-03 NA
2、差分函数diff()
一个简单的差分例如: x(t) - x(t-k) 其中k是序列偏移的步长。高阶差分是对每个之前的差分计算结果的重复应用。
diff(xtsdata, lag = , differences = )
参数说明:
Lag:偏移数;
differences:差分的次序(例如:调用多少次 diff )。
# 下面两条指令的效果相同
diff(x, differences = 2)
diff(diff(x))
3、endpoints()函数,按时间间隔分割数据
endpoints(data,on=, k= )
该函数接收一个时间序列并返回每个时间区间的最后一个观测值的位置向量。返回值以0开始,以数据长度(总行数)结束。
参数on 支持各种时间周期, 包括"years", "quarters", "months","hours"和 "minutes"等。
参数K用于找到第k个周期。例如,设置on = "weeks", k = 2, 可取每两周的最后一天。注意最后一个返回值总是数据的长度,即便是与间隔周期不一致。
例如,下列代码显示某数据每年的最后一个观测值
endpoints(Air, on = "years")
[1] 0 12 24 36 48 60 72 84 96 108 120 132 144
4、用period.apply按时间分割数据,并运算
period.apply(x, INDEX, FUN, ...)
使用举例:
# 计算每周的端点
ep <- endpoints(temps, on = "weeks")
# 计算每周均值并显示结果
period.apply(temps, INDEX = ep, FUN = mean)
5、用split-lapply-rbind分割数据并运算
#按周来划分数据,f参数是一个字符串,用于描述划分的间隔(例如:"months", "years")
data_weekly <- split(data, f = "weeks")
#创建一个每周均值的列表
temps_avg <- lapply(X = data_weekly, FUN = mean)
x_list_rbind <- do.call(rbind, temps_avg)
do.call(rbind, ...)
向rbind传送一个list,而不是一次传送一个对象。
6、单变量序列转换成OHLC数据(Open-High-Low-Close data)
基于常规窗口整合不同频次的序列可以使分析更容易。
to.period()函数格式如下,参数包括序列x, 表示周期的字符k等
to.period(x,
period = "months",
k = 1,
indexAt,
name=NULL,
OHLC = TRUE,
...)
使用举例:
usd_eur_weekly <- to.period(usd_eur, period = "weeks")
usd_eur_yearly <- to.period(usd_eur, period = "years", OHLC =
FALSE)
7、转换成低频序列
to.period()也可将序列转换成低调整频次的数据,类似于二次抽样。
# 转换成季度OHLC格式
mkt_quarterly <- to.period(eq_mkt, period = "quarters")
#使用快捷功能转换成季度OHLC格式
mkt_quarterly2 <- to.quarterly(eq_mkt, name = "edhec_equity", indexAt = "firstof")
indexAt参数设置为firstof ,选取区间时间的起点。设置参数name可以改变每一列的基础名。
8、计算时间序列的滚动标准差
时间序列数据的另一个常用需求是在数据的滚动窗口应用函数。
xts 对象可使用zoo函数rollapply()来实行。
该函数参数有时间序列对象x,窗口大小width,应用于每个滚动周期的函数FUN。
Width参数规定了窗口中的观测值数量。例如,选取一个序列的10天滚动。
rollapply(x, width = 10, FUN = max, na.rm = TRUE)
注意:如果是日观测值的序列是选取10天,如果是月观测值的序列会选取10个月。
七、修改时间戳
1、在高频次数据中发现具有相同时间戳的观测值时,一般有效的做法是强制时间唯一,增加毫秒随机数。
make.index.unique(data,eps= , drop= ,…)
参数说明:
eps:epsilon or small change的缩写,控制相同的时间被扰乱的程度。
drop = TRUE:移除全部重复观测值。
举例
make.index.unique(x, eps = 1e-4) # 增加随机数
make.index.unique(x, drop = TRUE) # 去除重复项
2、 某些情形时间戳过于精确,最好是近似到一些固定的间隔点。例如观测值可能在一小时内的任何时点发生,但只需记录最近的下个整点。
以下一个时间对齐数据,秒,分钟,小时。
align.time(data,n= ) 参数n,表示要近似到的秒数
align.time(x, n = 60) # 近似到分钟
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
数据分析在当今信息时代发挥着重要作用。单因素方差分析(One-Way ANOVA)是一种关键的统计方法,用于比较三个或更多独立样本组 ...
2025-04-25CDA持证人简介: 居瑜 ,CDA一级持证人国企财务经理,13年财务管理运营经验,在数据分析就业和实践经验方面有着丰富的积累和经 ...
2025-04-25在当今数字化时代,数据分析师的重要性与日俱增。但许多人在踏上这条职业道路时,往往充满疑惑: 如何成为一名数据分析师?成为 ...
2025-04-24以下的文章内容来源于刘静老师的专栏,如果您想阅读专栏《刘静:10大业务分析模型突破业务瓶颈》,点击下方链接 https://edu.cda ...
2025-04-23大咖简介: 刘凯,CDA大咖汇特邀讲师,DAMA中国分会理事,香港金管局特聘数据管理专家,拥有丰富的行业经验。本文将从数据要素 ...
2025-04-22CDA持证人简介 刘伟,美国 NAU 大学计算机信息技术硕士, CDA数据分析师三级持证人,现任职于江苏宝应农商银行数据治理岗。 学 ...
2025-04-21持证人简介:贺渲雯 ,CDA 数据分析师一级持证人,互联网行业数据分析师 今天我将为大家带来一个关于用户私域用户质量数据分析 ...
2025-04-18一、CDA持证人介绍 在数字化浪潮席卷商业领域的当下,数据分析已成为企业发展的关键驱动力。为助力大家深入了解数据分析在电商行 ...
2025-04-17CDA持证人简介:居瑜 ,CDA一级持证人,国企财务经理,13年财务管理运营经验,在数据分析实践方面积累了丰富的行业经验。 一、 ...
2025-04-16持证人简介: CDA持证人刘凌峰,CDA L1持证人,微软认证讲师(MCT)金山办公最有价值专家(KVP),工信部高级项目管理师,拥有 ...
2025-04-15持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。在实际生活中,我们可能会 ...
2025-04-14在 Python 编程学习与实践中,Anaconda 是一款极为重要的工具。它作为一个开源的 Python 发行版本,集成了众多常用的科学计算库 ...
2025-04-14随着大数据时代的深入发展,数据运营成为企业不可或缺的岗位之一。这个职位的核心是通过收集、整理和分析数据,帮助企业做出科 ...
2025-04-11持证人简介:CDA持证人黄葛英,ICF国际教练联盟认证教练,前字节跳动销售主管,拥有丰富的行业经验。 本次分享我将以教培行业为 ...
2025-04-11近日《2025中国城市长租市场发展蓝皮书》(下称《蓝皮书》)正式发布。《蓝皮书》指出,当前我国城市住房正经历从“增量扩张”向 ...
2025-04-10在数字化时代的浪潮中,数据已经成为企业决策和运营的核心。每一位客户,每一次交易,都承载着丰富的信息和价值。 如何在海量客 ...
2025-04-09数据是数字化的基础。随着工业4.0的推进,企业生产运作过程中的在线数据变得更加丰富;而互联网、新零售等C端应用的丰富多彩,产 ...
2025-04-094月7日,美国关税政策对全球金融市场的冲击仍在肆虐,周一亚市早盘,美股股指、原油期货、加密货币、贵金属等资产齐齐重挫,市场 ...
2025-04-08背景 3月26日,科技圈迎来一则重磅消息,苹果公司宣布向浙江大学捐赠 3000 万元人民币,用于支持编程教育。 这一举措并非偶然, ...
2025-04-07在当今数据驱动的时代,数据分析能力备受青睐,数据分析能力频繁出现在岗位需求的描述中,不分岗位的任职要求中,会特意标出“熟 ...
2025-04-03