lubridate包,非常强大,能够识别各种类型的日期.字符型和时间型数据,都是格式比较特别的你数据,在处理时,比较麻烦,但是有了lubridate这个包之后,时间处理变得非常简单,这个包函数命名简单,格式比较统一.
解析日期和时间
首先,lubridate函数的方便之处在于无论年月日之间以什么间隔符分隔,它总能找到正确的值且返回的是数字值,比如:
> year("2016-10-24")
[1] 2016
> year("2016/10/24")
[1] 2016
> month("2016/10/24")
[1] 10
> day("2016/10/24")
[1] 24
同时,lubridate还提供了函数帮助处理不同排列顺序的年月日数据:
> ymd("20110604")
[1] "2011-06-04"
> mdy("06-04-2011")
[1] "2011-06-04"
> dmy("04/06/2011")
[1] "2011-06-04"
> dmy("04062011")
[1] "2011-06-04"
如果您的日期包含时间信息,添加H,M,和/或s函数的名称。ymd_hms
可能是最常见的日期和时间格式。要阅读的具体日期,具有一定的时区,提供在该时区的正式名称tz
参数。
ymd_hms("20161120220000")
[1] "2016-11-20 22:00:00 UTC"
> ymd_hms("2016-11-20 22:00:00", tz = "Pacific/Auckland")
[1] "2016-11-20 22:00:00 NZDT"
ymd,mdy,dmy分别表示了三种常见的年月日排列方式,通过这种方式我们就可以把不同的日期数据都转化为标准的日期数据。
时区
为了处理时区信息,lubridate包提供了三个函数:
tz:提取时间数据的时区
with_tz:将时间数据转换为另一个时区的同一时间
force_tz:将时间数据的时区强制转换为另一个时区
有两个非常有用的事情要做日期和时区。首先,显示不同的时区相同的时刻。二,创建由现有的时钟时间与新的时区相结合的新时刻。
这些被完成with_tz
和force_tz
。
输入meeting在Pacific/Auckland的开场时间,再转为America/Chicago时间
> meeting <- ymd_hms("2011-07-01 09:00:00", tz = "Pacific/Auckland");meeting
[1] "2011-07-01 09:00:00 NZST"
> with_tz(meeting, "America/Chicago") #显示不同的时区相同的时刻
[1] "2011-06-30 16:00:00 CDT"
> mistake <- force_tz(meeting, "America/Chicago");mistake
[1] "2011-07-01 09:00:00 CDT"
> with_tz(mistake, "Pacific/Auckland")
[1] "2011-07-02 02:00:00 NZST"
设置和提取信息
提取与功能的日期时间的信息second
,minute
,hour
,day
,wday
,yday
,week
,month
,year
,和tz
。您也可以使用这些设置(即改变)给定的信息。请注意,这将改变日期和时间,wday
并month
具有可选的label
参数,它取代了他们的数字输出和平日或月的名称。
> year("2011-08-10 14:20:01")
[1] 2011
> minute("2011-08-10 14:20:01")
[1] 20
> week("2011-08-10 14:20:01")
[1] 32
时间间隔
lubridate还允许我们定义一个时间区间,例如:
> interval(ymd(20161101), ymd(20161103))
[1] 2016-11-01 UTC--2016-11-03 UTC
两个时间段是由--相连的,UTC表示时区
date1 <- as.POSIXct("2016-11-08 01:59:59") #POSIXct: 日期时间类,精确到秒,用数字表示
date2 <- as.POSIXct("2016-12-29 12:00:00")
interval(date1, date2)
[1] 2016-11-08 01:59:59 CST--2016-12-29 12:00:00 CST
date1 <- as.POSIXlt("2016-11-08 01:59:59") #POSIXlt: 日期时间类,精确到秒,用列表表示
date2 <- as.POSIXlt("2016-12-29 12:00:00")
interval(date1, date2)
[1] 2016-11-08 01:59:59 UTC--2016-12-29 12:00:00 UTC
处理日期数据的时候,使用了as.POSIXct函数,但是现在发现一个问题,这个函数貌似不能处理类似于
"%Y-%m-%d %H:%M:%S"的日期格式。
lubridate允许我们在给时间数据赋值的时候加上时区这一项,由于在日常生活中使用可能性较小,这篇文章里就不涉及了。
> int1<-interval(ymd(20161101), ymd(20161103)); int1
有了时间区间的定义,我们还可以判断一个时间区间是否在另一个时间区间里面,用"%within%"操作符。
> as.period(int1)
[1] "2d 0H 0M 0S"
> int1 / dminutes(1)
[1] 2880
如上还可以查看或计算一个时间区间的长度。
把时间间隔保存为一个lubridate间隔类对象。这是非常有用的哦!
间隔是特定的时间跨度(因为它们依赖于具体日期),但也lubridate提供两种一般时间跨度类:持续时间和周期。创建期间辅助功能的时间(复数)的单位命名。创建工期的辅助函数遵循相同的格式,但用“D”(持续时间)开始,或者,如果你喜欢,和“e”(有关详细)。
时间数据运算
此外我们还可以用对时间数据进行加减,这也是很有用的,因为有时候我们要判断两个时间之间的间隔是否超过了某个值:
> minutes(2) ## period
[1] "2M 0S"
> dminutes(2) ## duration
[1] "120s (~2 minutes)"
minutes(2)函数表示的2个整分钟的概念,而dminutes(2)则是具体120秒
dyears(1)表示的365天而years(1)则是一个整年的概念
leap_year()函数可以判断是否是闰年
> leap_year(2016) #判断是否是闰年
[1] TRUE
> ymd('20160228')+dyears(1)
[1] "2017-02-27"
> ymd('20160228')+years(1)
[1] "2017-02-28"
矢量
在lubridate代码矢量,并准备在交互式设置和功能内所使用。举个例子,我提供了一个功能,推进的日期当月的最后一天last_day <- function(date) {
ceiling_date(date, "month") - days(1)
}
####################################
lubridate包主要有两类函数,一类是处理时点数据(time instants),另一类是处理时段数据(time spans)。有了时点和时段数据,就可以进行各种计算了。
时点类函数,它包括了解析、抽取、修改。
从字符型数据解析时间,会自动识别各种分隔符
> x <- ymd('2016-11-20');x
[1] "2016-11-20"
观察x日期是一年中的第几天
> yday(x)
[1] 325
修改x日期中的月份为5月
> month(x) <- 5 ;month(x)
[1] 5
> x
[1] "2016-05-20"
注意点:
时段类函数,它可以处理三类对象,分别是:
interval:最简单的时段对象,它由两个时点数据构成。
duration:去除了时间两端的信息,纯粹以秒为单位计算时段的长度,不考虑闰年和闰秒,它同时也兼容基本包中的difftime类型对象。
period:以较长的时钟周期来计算时段长度,它考虑了闰年和闰秒,适用于长期的时间计算。
从两个时点生成一个interval时段数据
> x <- ymd('2016-11-20');x
> y <- interval(x,now());y
从interval格式转为duration格式
> as.duration(y)
时点+时段生成一个新的时点
> now() + as.duration(y)
10天后的时间数据
> now() + ddays(10)
几个月和几年的长度常常这样做算术他们可以直观的改变。考虑一个简单的操作,January 31st + one month。如果答案是:
1,February 31st (不存在)
2,March 4th (1月31日以后31天),或
3,February 28th (假设它不是一个闰年)
但它是一个无效的日期。则使lubridate尽可能一致,如果加上或减去一个月或一年创建一个无效的日期,lubridate将返回NA
2或3的解决方案,或使用特殊的%m+%和%m-%。%m+%并%m-%自动回滚可以追溯到一个月的最后一天,应该说是必要的。
jan31 <- ymd("2013-01-31")
jan31 + months(0:11)
## [1] "2013-01-31" NA "2013-03-31" NA "2013-05-31"
## [6] NA "2013-07-31" "2013-08-31" NA "2013-10-31"
## [11] NA "2013-12-31"
floor_date(jan31, "month") + months(0:11) + days(31)
## [1] "2013-02-01" "2013-03-04" "2013-04-01" "2013-05-02" "2013-06-01"
## [6] "2013-07-02" "2013-08-01" "2013-09-01" "2013-10-02" "2013-11-01"
## [11] "2013-12-02" "2014-01-01"
jan31 %m+% months(0:11)
## [1] "2013-01-31" "2013-02-28" "2013-03-31" "2013-04-30" "2013-05-31"
## [6] "2013-06-30" "2013-07-31" "2013-08-31" "2013-09-30" "2013-10-31"
## [11] "2013-11-30" "2013-12-31"
请注意,这只会影响使用算术个(和算术多年,如果你的起始日期是2月29日)。