(本文首发于个人公众号“数据与平行世界”,欢迎关注!)
时间序列数据的主要属性是它的时间索引(时间戳),时间索引可以是日期对象、日期时间对象或者依赖于序列频率的其他对象。载入原始数据的时候,往往并没有伴随着恰当的日期/时间对象。因此,在将数据转换为时间序列之前,往往要进行格式上的重新处理。处理时间和日期对象的能力是时间序列数据预处理过程的一部分,往往也是相当麻烦和繁琐的一部分。
1、日期和时间
日期和时间对象的处理是复杂的,主要的挑战在于格式的多样性。比如,常用的计算机日历系统使用字母顺序的形式表示年月日这三种日期成分:
- Y:年
- yy:20
- yyyy:2020
- M:月
- m:1(1月)
- mm:01(1月)
- mmm:Jan(1月)英文月名的三位缩写
- mmmm:January 英文的完整月名
- D:天。
- d:1
- dd:01
- ddd:Mon 星期的缩写
- dddd:Monday 完整的星期名称
除此之外,还有表示顺序的差异,不同国家/地区的惯用表示法是不一样的:
中国:YMD 2020/05/27
美国:MDY 05/27/2020 May 27th,2020
2、R内置的日期和日期时间类
作为基础,我们首先来介绍R中基本的日期和日期时间类。
R的 base
包提供了两种基本的日期和时间类:
1、Date
类:日期类,服从ISO8601标准的日历日期表示,格式是yyyy-mm-dd。默认的起点时间是1970-01-01,每个日期对象都有一个数值取值。序列频率为天或低于天(月、年等)。
2、POSIXct
类/POSIXlt
类:日期时间类(DateTime),标准格式是yyyy-mm-dd h : m : s 。两者的差异在于各自取值内部存储的方式不同。POSIXct类与Date类相似,以数值向量表示从起点时间开始的秒数,POSIXlt类则将每个日期时间的各种时间成分按列表保存。序列频率高于天。
看一下这两种类型(Sys.Date()取系统的日期,Sys.time()取系统的日期时间):
>date<-Sys.Date()
> date
[1] "2020-05-28"
> class(date)
[1] "Date"
> date_time<-Sys.time()
> date_time
[1] "2020-05-28 15:07:41 CST"
> class(date_time)
[1] "POSIXct" "POSIXt"
2.1 日期和时间对象的创建和转换
在R中,对一个特定的类指派取值有一个通用的函数模版:as.[the class name]
。
所以,可以使用as.Date()``as.POSIXct()``as.POSIXct()
这样的函数将字符形式的时间表示转换为日期/日期时间类:
> as.Date("2020-05-31")
[1] "2020-05-31"
> as.Date("31-05-2020")###wrong!
[1] "0031-05-20"
由于时间表示形式的复杂性,这种转换是很容易出错误的(如上面的as.Date("31-05-2020")
)。因此,这种格式转换,特别是从外部文件读入数据时,往往需要指定待转换时间的表示格式。常用的时间格式表示如下表所示(完整的格式参考strptime函数的帮助文件:??strptime
):
表1:
看一些例子:
> as.Date("2020-05-31")
[1] "2020-05-31"
> as.Date("31-05-2020")
[1] "0031-05-20"
> as.Date("31-05-2020",format='%d-%m-%Y')
[1] "2020-05-31"
> as.Date("01/05/2020",format="%m/%d/%Y")
[1] "2020-01-05"
> as.Date("May 28,2020",format="%B %d,%Y")
[1] "2020-05-28"
> strptime("31-05-2020",format="%d-%m-%Y")
[1] "2020-05-31 CST"
> strptime("31/05/2020",format="%d/%m/%Y")
[1] "2020-05-31 CST"
> strptime("20200531",format="%Y%m%d")
[1] "2020-05-31 CST"
> strptime("31/5/20