5.2 lubridate
lubridate
包是对Base R中POSIXct类的封装。所以无论从函数名还是功能等方面,lubridate包中的函数功能更加清晰明了。从获取当前日期、时间,解析时间日期中的年、月、日、星期,计算年月间隔天数等常用的时间日期功能,lubridate
包中都有相对应的功能函数。
在处理日期时间数据时,我常用lubridate
解决,本节将介绍包中部分函数用法。
5.2.1 安装包
install.packages("tidyverse")
# 仅仅只安装lubridate
install.packages('lubridate')
# 开发版
::install_github("tidyverse/lubridate") devtools
# 加载包
library(lubridate,warn.conflicts = FALSE)
5.2.2 当前时间日期
now
函数
now()函数是当前时间,只有一个参数tzone,默认为系统的timezone。
now()
# now(tzone = 'Asia/Shanghai')
# base R
::Sys.time() base
today
函数
时区同样默认为系统的timezone。
today(tzone = 'Asia/Shanghai')
#base R
::Sys.Date() base
5.2.3 构造日期时间
使用数值直接创建日期时间。
函数make_date()
和make_datetime()
函数默认时区8为“UTC”。
make_date(year = 2021, month = 5, day = 1, tz = "Asia/Shanghai")
make_datetime(
year = 1970L,
month = 1L,
day = 1L,
hour = 0L,
min = 0L,
sec = 0,
tz = "Asia/Shanghai"
)
- make_datetime
make_datetime(
year = year(today()),
month = month(today()),
day = day(today()),
hour = hour(now()),
min = minute(now()),
sec = second(now()),
tz = "asia/shanghai"
)
- as_datetime
as_datetime('2020-01-09 09:15:40',tz='asia/shanghai')
as_date('2020-01-09') #ymd格式
# same above
#as_date('2020/01/09')
#as_date('20200109')
5.2.4 解析日期时间
数据源中日期列可能是各种的字符形式,需要转换为时间格式方便进行日期计算。商业环境中的数据是混乱的,生产库可能是不同的数据库系统,导致时间日期格式混乱,如果公司没有统一的用户层数据源,我们就需要自己清洗数据,将不同形式的日期格式转化为标准格式。
- 解析日期
# 整数和字符都可以
ymd(20200604)
ymd('20200604')
mdy(06042020)
dmy(04062020)
- 解析时间
ymd_hm("20100201 07-01", "20100201 07-1", "20100201 7-01")
ymd_hms("2013-01-24 19:39:07")
当需要处理unix时间戳时应.POSIXct()函数转化.
.POSIXct(1591709615)
ymd_hms(.POSIXct(1591709615))
在使用unix时间戳转换时一定注意R环境和数据系统环境时区是否一直。
曾经我在使用阿里云的RDS数据库时没注意时区差异,导致我清洗出来的时间数据错误。
ymd_hms(.POSIXct(1591709615),tz = 'Asia/Shanghai')
5.2.5 提取日期时间成分
#获取年
year(now())
#获取月
month(now())
# 当前时间所在年份天数
yday(now())
# 当前时间所在月天数
mday(now())
# 周几
wday(now(),label = TRUE,week_start = 1)
# 所在时刻
hour(now())
# 所在时刻
minute(now())
# 所在时刻
second(now())
5.2.6 处理时区
数据时区与本地R环境一致时,数据中的时区没必要处理,但是当数据是跨时区的或者不同生产系统的时区不一致,我们需要将数据时区处理一致。
1.时区查看
时区和所用系统设置相关
Sys.timezone()
# windows 系统默认的时区 中国台北
# linux 上是"Asia/Shanghai"
# mac 上是"Asia/Shanghai"
这里还有一个奇怪的点,Windows系统下时区设置为(UTC+08:00)北京,重庆,香港特别行政区,乌鲁木齐
,但是R返回的时区是Asia/Taipei
。
now()
now()
输出结果中,CST是时区概念。
CST可以同时代表四个时间
- Central Standard Time (USA) UT-6:00
- Central Standard Time (Australia) UT+9:30
- China Standard Time UT+8:00
- Cuba Standard Time UT-4:00
2.时区调整
lubridate中用with_tz()
,force_tz()
处理时区问题
<- ymd_hms("2020-12-13 15:30:30")
time
time
# Changes printing
with_tz(time, "Asia/Shanghai")
# Changes time
force_tz(time, "Asia/Shanghai")
- 时区差异
从下面三个时间观察时区,CST时间:中央标准时间;UTC时间:世界协调时间(UTC)是世界上不同国家用来调节时钟和时间的主要时间标准。
如:当UTC时间为0点时,中国CST时间为8点,因为零时区和中国北京时区相差8个时区.
::now() # now函数调用系统默认时区
lubridateas_datetime(now()) #as_datetime默认是UTC
as_datetime(now(),tz = 'asia/shanghai')
5.2.7 时间间隔
lubridate
中将时间间隔保存为interveal
类对象。
<- ymd_hms("2020-12-04 12:00:00", tz = "asia/shanghai")
arrive
arrive
<- ymd_hms("2020-12-10 14:00:00", tz = "asia/shanghai")
leave
leave
<- interval(arrive, leave)
res # same above
<- arrive %--% leave res
查看类
class(res)
两个时间间隔是否重复
<- interval(ymd(20201020, tz = "asia/shanghai"), ymd(20201231, tz = "asia/shanghai"))
jsm
jsmint_overlaps(jsm, res)
更多详细用法?interveal
interval(start = NULL, end = NULL, tzone = tz(start))
%--% end
start
is.interval(x)
int_start(int)
int_start(int) <- value
int_end(int)
int_end(int) <- value
int_length(int)
int_flip(int)
int_shift(int, by)
int_overlaps(int1, int2)
int_standardize(int)
int_aligns(int1, int2)
int_diff(times)
5.2.8 时间日期计算
时间日期计算以number line
为依据计算。原文是Because the timeline is not as reliable as the number line
,我没理解这句话。
minutes(2)
dminutes(2)
dhours(2)
注意闰年时计算年份的差异
leap_year(2019)
ymd(20190101) + dyears(1)
ymd(20190101) + years(1)
leap_year(2020)
ymd(20200101) + dyears(1) # 注意查看闰年时的差异
ymd(20200101) + years(1)
lubridate
中的函数都已向量化
<- ymd_hms("2020-12-01 09:00:00", tz = "asia/shanghai")
meeting <- meeting + weeks(0:5)
meeting %within% jsm meeting
除法计算
/ ddays(1)
res / dminutes(1)
res
%/% months(1)
res %% months(1) res
as.period
用法
as.period(res %% months(1))
对于日期而言,因为月天数、年天数不一致,导致不能直接加减天数,如下:
<- ymd("2020-01-31")
jan31 + months(0:11) jan31
lubridate
中不存在的日期返回NA
解决方案是:%m+%
或%m-%
%m+% months(0:11)
jan31 %m-% months(0:11) jan31
lubridate包中大部分函数默认时区为“UTC”,在涉及时间处理时需要注意时区。↩︎