【R语言】必学包之lubridate包

[亡魂溺海] 提交于 2021-01-19 12:57:18

       lubridate包常用于处理时间数据的数据集,提供很便利的解析日期与时间的内置函数。相较于R内置的时间处理函数,lubridate包的处理方法会更快且更加丰富。lubridate包主要有两类函数,一类是处理时点数据(time instants),另一类是处理时段数据(time spans)。

1. 解析日期和时间

     以下的内置函数可用于根据输入向量中年月日元素的顺序解析日期。可以将字符和数字向量中的日期转换为date或者POSIXct对象,这些函数可以识别任意的非数字分隔符(或者无分隔符)的日期元素,只要格式的顺序是正确的,这些函数就可以正确地解析日期,即使输入向量包含不同格式的日期元素。

#解析年月日时间类型
ymd(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析年日月时间类型
ydm(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析月日年时间类型
mdy(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析月年日时间类型
myd(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析日月年时间类型
dmy(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析日年月时间类型
dym(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析季度类型
yq(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"))
  • …:包含疑似日期类型的字符或数字向量;
  • quiet:逻辑值,TRUE转换后不显示消息;
  • tz:指定时区,为NULL(默认值)直接返回Date对象,否则将带有时区属性的;POSIXct设置为tz;
  • Locale:设置语言环境;
  • truncated:设置可以被截断格式的数量
–	举例1:
library(lubridate)
x <- c(20170101, "2017-01-02", "2017/01/02","201701-02","2017/01-    
02", "2017 01 03", "2017-1-4","2017-1, 5", "Created on 2017 1 6", 
"201701 !!! 07")
#使用ymd解析时间类型,可以解析不同格式的日期元素
ymd(x)

–	举例2:
y <- " aaaa  01aaasd07asdfa2017asdaa"
#使用mdy解析月日年,可以提取出日期元素而不管分隔符
mdy(y)

–	举例3:
z <- "2017-01"
#z缺少日元素,使用ymd解析时显示warning信息,返回NA
ymd(z)
#设置quiet=TRUE,不显示warning信息
ymd(z, quiet = TRUE)
#只缺少日元素,设置truncated>=1即可使用ymd解析
ymd(z, truncated = 1)

z <- "2017"
#只缺少两个元素,设置truncated>=2才可使用ymd解析
ymd(z, truncated = 2)

m <- "1707"
#默认都是缺少右侧的元素,因此此例缺少年,解析为"0000-07-17"
dmy(m, truncated = 1)

#实际表示2017年8月,但是解析过程中有可能造成错误
n <- "1708"
#使用truncated=1解析为2017-08-01
ymd(n, truncated = 1)
#使用truncated=2,n当作1708年,因此解析为1708-01-01
ymd(n, truncated = 2)

–	举例4:
p <- c("2017-1", "2017/02", "2017aaa3", "201704")
#解析为2017年每个季度
yq(p)

 解析月日年时分秒,自动的分配世界标准时间UTC时区给解析后的date。

#解析年月日时分秒时间类型
ymd_hms(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析年月日时分时间类型
ymd_hm(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析年月日时时间类型
ymd_h(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析日月年时分秒时间类型
dmy_hms(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析日月年时分时间类型
dmy_hm(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析日月年时时间类型
dmy_h(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析月日年时分秒时间类型
mdy_hms(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析月日年时分时间类型
mdy_hm(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析月日年时时间类型
mdy_h(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析年日月时分秒时间类型
ydm_hms(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析年日月时分时间类型
ydm_hm(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
#解析年日月时时间类型
ydm_h(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0)
–	举例5:
x <- c(20100101120101, "2009-01-02 12-01-02", "2009.01.03 12:01:03","2009-1-4 12-1-4", "2009-1, 5 12:1, 5",
    "200901-08 1201-08", "2009 arbitrary 1 non-decimal 6 chars 12 in between 1 !!! 6", "OR collapsed formats: 20090107 120107 (as long as prefixed with zeros)", "Automatic wday, Thu, detection, 10-01-10 10:01:10 and p format: AM",
     "Created on 10-01-11 at 10:01:11 PM")
#解析出年月日时分秒
ymd_hms(x)

–	举例6:
x <- c("2011-12-31 12:59:59", "2010-01-01 12:11", "2010-01-01 
12", "2010-01-01")
#解析为年月日时分秒
ymd_hms(x, truncated = 3)
x <- c("2011-12-31 12:59", "2010-01-01 12", "2010-01-01")
ymd_hm(x, truncated = 2)

仅解析时分秒

#解析分秒
ms(..., quiet = FALSE, roll = FALSE)
#解析时分
hm(..., quiet = FALSE, roll = FALSE)
#解析时分秒
hms(..., quiet = FALSE, roll = FALSE)
  • …:时分秒组成的字符向量;
  • quiet:逻辑值,TRUE转换后不显示消息;
  • roll:逻辑值,为TRUE表示自动进位转换,如61秒会转换为1分01秒,默认值为FALSE不转换;
#解析为时分秒对象
hms("7 6 5", "3:23:::2", "2 : 23 : 33", "Finished in 9 hours, 20 min and 4 seconds")
#解析为时分秒对象,秒为0s
hm("6,5")
#解析为时分秒对象报错,Some strings failed to parse,只能使用包含两个数
#字的字符
hm("6,5,4")
#解析为时分秒对象,”-“会被解析为负号, 返回9H 10M -10S"
hms("9:10-10")
#解析为时分秒对象,设置roll为TRUE,自动与分进行运算,返回"9H 9M 50S"
hms("9:10-10",roll = TRUE)
#解析为时分秒对象,设置roll为TRUE,自动与分进行运算,返回"9H 11M 20S"
hms("9:10:80",roll = TRUE)

解析时间过程中如果遇到年月日无序排列的情况可以使用以下函数解析。

#将格式各样的日期时间字符转换为日期时间类型的数据
parse_date_time(x, orders, tz = "UTC", truncated = 0, quiet = FALSE, locale = Sys.getlocale("LC_TIME"), select_formats = .select_formats, exact = FALSE)
#更快速的C解析函数
parse_date_time2(x, orders, tz = "UTC", exact = FALSE, lt = FALSE)
#更快速的C解析函数,需要显式的format
fast_strptime(x, format, tz = "UTC", lt = TRUE)
  • x:字符或者数字表示的日期;
  • orders:date-time形式的字符向量,每个order可以是strptime中列出的格式化字符,但是可以不包含“%”前缀, 解析过程中会丢弃格式化字符中包含的任意的分隔符;
  • tz : 字符串用于指定解析日期的时区;
  • truncated: 设置可以被截断格式的数量;
  • quiet:逻辑值,TRUE转换后不显示消息;
  • locale: 设置语言环境;
  • select_formats:函数,从匹配训练集的formats中选出实际用于解析时间的formats,输入为整型向量,返回字符向量表示的formats
  • exact: 逻辑值,为TRUE则将orders参数解释为精确的strftime格式,并且不执行训练或猜测;
  • lt:逻辑值,TRUE返回POSIXlt类对象,否则返回POSIXct类对象,为了与strptime兼容,'fast_strptime'默认lt = TRUE,  'parse_date_time2'默认lt = FALSE;
  • format:字符串表示的formats,每个format必须带有strptime相同的参数前缀,并且需要包含所有的分隔符;
–	举例8:
#解析过程format的分隔符会被忽略
x <- c("09-01-01", "09-01-02", "09-01-03")
parse_date_time(x, "ymd")
parse_date_time(x, "y m d")
parse_date_time(x, "%y%m%d")
parse_date_time(x, "y-md")
parse_date_time(x, "y---m///d")

#orders包含多个formats,可用于解析formats设置的时间对象
x <- c("2009-01-01", "02022010", "02-02-2010")
parse_date_time(x, c("dmY", "ymd"))

#设置truncated = 3,如果不存在时间对象解析为00:00:00
x <- c("2011-12-31 12:59:59", "2010-01-01 12:11", "2010-01-01 12", "2010-01-01")
parse_date_time(x, "Ymd HMS", truncated = 3)

#设置exact参数,精确的解析时间对象
x <- c("09-01-01", "090102", "09-01-03 12:02")
parse_date_time(x, c("%m-%d-%y", "%m%d%y", "%m-%d-%y %H:%M"), 
exact = TRUE)
parse_date_time(c('12/17/1996 04:00:00','4/18/1950 0130'),                
c('%m/%d/%Y %I:%M:%S','%m/%d/%Y %H%M'), exact = TRUE)

–	举例9:
#按指定的时区解析时间对象,返回POSIXct对象
parse_date_time2("2010-03-14 02:05:06", "YmdHMS", tz = "Asia/Shanghai")

#按指定的时区解析时间对象,设置lt=TRUE,返回POSIXlt对象
parse_date_time2("2010-03-14 02:05:06", "YmdHMS", tz = "Asia/Shanghai", lt = TRUE)

–	举例10:
dates <- c("02/27/92", "02/27/92", "01/14/92", "02/28/92", "02/01/92")
times <- c("23:03:20", "22:29:56", "01:03:30", "18:21:03", "16:56:26")
date_time <- paste(dates, times)
#按固定格式解析时间对象,返回POSIXlt类对象,默认时区为UTC
fast_strptime(date_time, "%m/%d/%y %H:%M:%S")
#按固定格式解析时间对象,返回POSIXct类对象,默认时区为UTC
fast_strptime(date_time, "%m/%d/%y %H:%M:%S", lt = FALSE)
#按固定格式解析时间对象,返回POSIXlt类对象,按时区Asia/Shanghai解析
fast_strptime(date_time, "%m/%d/%y %H:%M:%S", tz = "Asia/Shanghai")

2. 设置和提取时间信息

lubridate同时也提供了从datetime对象中提取时间的各个元素的函数,例如提取datetime中的year,month和day等。提取过程包括精确提取和模糊提取(即取整)。

#返回或设置日期对象中的day
day(x)
day(x) <- value
#返回或设置日期对象中的当月的某一天
mday(x)
mday(x) <- value
#返回或设置日期对象中的当周的某一天
wday(x, label = FALSE, abbr = TRUE)
wday(x) <- value
#返回或设置日期对象中的当季的某一天
qday(x)
qday(x) <- value
#返回或设置日期对象中的当年的某一天
yday(x)
yday(x) <- value

#返回或设置日期对象中的hour
hour(x)
hour(x) <- value
#返回或设置日期对象中的minute
minute(x)
minute(x) <- value
#返回或设置日期对象中的second
second(x)
second(x) <- value

#返回或设置日期对象中的month
month(x, label = FALSE, abbr = TRUE)
month(x) <- value

#返回或设置日期对象中的year
year(x)
year(x) <- value

#返回参数所表示的月总共有多少天
days_in_month(x)

  • x:POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its,   ti, jul, timeSeries或者fts对象;
  • label:逻辑值,仅适用于wday函数,为TRUE使用有序的字符串(eg: Sunday)因子显示week中的day,FALSE使用数字代表day,weekday默认周日为1;
  • abbr:逻辑值,仅适用于wday函数,为FALSE使用有序的字符串(eg: Sunday)因子显示week中的day,TRUE使用缩写的字符(eg: Sun)因子表day;
  • value:数值对象;
–	举例1:
#获取当前时间
time <- Sys.time()
#返回日期对象中的day
day(time)
#返回日期对象是当月的第几天
mday(time)
#返回日期对象是当季的第几天
qday(time)
#返回日期对象是当年的第几天
yday(time)
#返回日期对象是当周的第几天
wday(time)
#返回日期对象是当周的第几天,返回字符串因子
wday(time, label = TRUE, abbr = FALSE)
#返回日期对象是当周的第几天,返回缩写的字符串因子
wday(time, label = TRUE, abbr = TRUE)

–	举例2:
#获取当前时间
time <- Sys.time()
#设置日期对象为第15天
day(time) <- 15
#设置日期对象为当月的第10天
mday(time) <- 10
#设置日期对象是当季的第30天
qday(time) <- 30
#返回日期对象是当年的第365天
yday(time) <- 365

–	举例3:
#获取当前时间
time <- Sys.time()
#返回日期对象中的hour
hour(time)
#返回日期对象中的minute
minute(time)
#返回日期对象中的second
second(time)

–	举例4:
#获取当前时间
time <- Sys.time()
#返回日期对象中用数字表示的月
month(time)
#返回日期对象中用字符表示的月
month(time, label = TRUE, abbr = FALSE)
#返回日期对象中用缩写字符表示的月
month(time, label = TRUE, abbr = TRUE)

–	举例5:
#获取当前时间
time <- Sys.time()
#返回日期对象中用数字表示的年
year(time)

–	举例6:
#返回2016年2月总共有的天数
days_in_month(as.Date("2016-02-01"))

      模糊提取时间信息,即对提取的信息取整到不同的单元。可以取整到最近的unit或unit的倍数,其中unit支持所有有意义的英文单元,如secs, min, mins, 2 minutes和3 years 等。取整过程中函数ceiling_date通常会转换对象为较低的时刻值(如,2000-01-01 –> 2000-01-01 00:00:00),然后根据设置的unit转换为下一个最近的unit边界值,对于参数change_on_boundary取默认值NULL或者FALSE时, 比设置的unit低级的时间元素如果为00,则不进位,否则向上进位,例如unit =minute,若此时的秒为00,则不进位,如果为01则minute向上进位。

# 四舍五入取整
round_date(x, unit = "second")
# 向下取整
floor_date(x, unit = "seconds")
# 向上取整
ceiling_date(x, unit = "seconds", change_on_boundary = NULL)
  • x:datetime对象组成的向量;
  • unit : 字符串表示的一个时间单元或时间单元的倍数,有效的时间单元包括second, minute, hour, day, week, month, bimonth, quarter, halfyear或 year,另外也支持period构造函数中使用的英文缩写形式;
  • change_on_boundary : 默认值为NULL,不会修改特定时刻的边界,但是对date对象依然会向上舍入到下一个边界,相反设置为TRUE,进行向上舍入,为FALSE时与NULL 类似;
–	举例6:
#返回2017-08-31 12:02:00 CST
round_date(as.POSIXct("2017-08-31 12:01:59.50"), "second")
#返回2017-08-31 12:01:59 CST
round_date(as.POSIXct("2017-08-31 12:01:59.49"), "second")

#返回2017-08-31 12:02:00 CST
round_date(as.POSIXct("2017-08-31 12:01:30.49"), "minute")
#返回2017-08-31 12:01:00 CST
round_date(as.POSIXct("2017-08-31 12:01:29.49"), "minute")
    #返回2017-08-31 12:05:00 CST
round_date(as.POSIXct("2017-08-31 12:02:30"), "5 mins")
#返回2017-08-31 12:00:00 CST
round_date(as.POSIXct("2017-08-31 12:02:29"), "5 mins")

#返回2017-08-31 12:00:00 CST
round_date(as.POSIXct("2017-08-31 12:29:59"), "hour")
#返回2017-08-31 13:00:00 CST
round_date(as.POSIXct("2017-08-31 12:30:00"), "hour")
#返回2017-08-31 12:00:00 CST
round_date(as.POSIXct("2017-08-31 11:00:00"), "2 hours")
#返回2017-08-31 10:00:00 CST
round_date(as.POSIXct("2017-08-31 10:59:00"), "2 hours")

#返回2017-09-01 CST
round_date(as.POSIXct("2017-08-31 12:00:00"), "day")
#返回2017-08-31 CST
round_date(as.POSIXct("2017-08-31 11:59:59"), "day")

#返回2017-09-03 CST
round_date(as.POSIXct("2017-08-30 12:00:00"), "week")
#返回2017-08-27 CST
round_date(as.POSIXct("2017-08-30 11:59:59"), "week")

#返回2017-09-01 CST
round_date(as.POSIXct("2017-08-16 12:00:00"), "month")
#返回2017-08-01 CST
round_date(as.POSIXct("2017-08-16 11:59:59"), "month")

#返回2017-09-01 CST
round_date(as.POSIXct("2017-08-01 00:00:00"), "2 months")
round_date(as.POSIXct("2017-08-01 00:00:00"), "bimonth")
#返回2017-07-01 CST
round_date(as.POSIXct("2017-07-31 00:00:00"), "2 months")
round_date(as.POSIXct("2017-07-31 00:00:00"), "bimonth")

#返回2017-10-01 CST
round_date(as.POSIXct("2017-08-16 00:00:00"), "quarter")
round_date(as.POSIXct("2017-08-16 00:00:00"), "3 months")
#返回2017-07-01 CST
round_date(as.POSIXct("2017-08-15 00:00:00"), "quarter")
round_date(as.POSIXct("2017-08-15 00:00:00"), "3 months")

#返回2018-01-01 CST
round_date(as.POSIXct("2017-10-01 00:00:00"), "halfyear")
#返回2017-07-01 CST
round_date(as.POSIXct("2017-09-30 00:00:00"), "halfyear")

#返回2018-01-01 CST
round_date(as.POSIXct("2017-07-03 00:00:00"), "year")
#返回2017-01-01 CST
round_date(as.POSIXct("2017-07-02 00:00:00"), "year")

–	举例7:
#返回2017-08-31 12:01:59 CST
floor_date(as.POSIXct("2017-08-31 12:01:59.50"), "second")
#返回2017-08-31 12:01:00 CST
floor_date(as.POSIXct("2017-08-31 12:01:59.49"), "minute")
#返回2017-08-31 12:00:00 CST
floor_date(as.POSIXct("2017-08-31 12:02:30"), "5 mins")
#返回2017-08-31 12:00:00 CST
floor_date(as.POSIXct("2017-08-31 12:30:00"), "hour")
#返回2017-08-31 10:00:00 CST
floor_date(as.POSIXct("2017-08-31 11:00:00"), "2 hours")
#返回2017-08-31 CST
floor_date(as.POSIXct("2017-08-31 12:00:00"), "day")
#返回2017-08-27 CST
floor_date(as.POSIXct("2017-08-30 12:00:00"), "week")
#返回2017-08-01 CST
floor_date(as.POSIXct("2017-08-16 12:00:00"), "month")
#返回2017-07-01 CST
floor_date(as.POSIXct("2017-08-01 00:00:00"), "bimonth")
#返回2017-07-01 CST
floor_date(as.POSIXct("2017-08-16 00:00:00"), "quarter")
#返回2017-07-01 CST
floor_date(as.POSIXct("2017-10-01 00:00:00"), "halfyear")
#返回2017-01-01 CST
floor_date(as.POSIXct("2017-07-03 00:00:00"), "year")

–	举例8:
#返回2017-08-31 12:02:00 CST,使用毫秒直接进位
ceiling_date(as.POSIXct("2017-08-31 12:01:59.49"), "second")
ceiling_date(as.POSIXct("2017-08-31 12:01:59.49"), "second", 
               change_on_boundary = FALSE)
ceiling_date(as.POSIXct("2017-08-31 12:01:59.49"), "second", 
               change_on_boundary = TRUE)
#返回2017-08-31 12:01:59 CST,不进位
ceiling_date(as.POSIXct("2017-08-31 12:01:59"), "second")
ceiling_date(as.POSIXct("2017-08-31 12:01:59"), "second", 
               change_on_boundary = FALSE)

#返回2017-08-31 12:01:00 CST
ceiling_date(as.POSIXct("2017-08-31 12:01:00"), "minute")
ceiling_date(as.POSIXct("2017-08-31 12:01:00"), "minute", 
               change_on_boundary = FALSE)
#返回2017-08-31 12:02:00 CST
ceiling_date(as.POSIXct("2017-08-31 12:01:01"), "minute")
ceiling_date(as.POSIXct("2017-08-31 12:01:01"), "minute", 
               change_on_boundary = FALSE)
#返回2017-08-31 12:02:00 CST
ceiling_date(as.POSIXct("2017-08-31 12:01:00"), "minute", 
               change_on_boundary = TRUE)
ceiling_date(as.POSIXct("2017-08-31 12:01:01"), "minute", 
               change_on_boundary = TRUE)

#返回2017-08-31 12:05:00 CST
ceiling_date(as.POSIXct("2017-08-31 12:00:01"), "5 mins")
ceiling_date(as.POSIXct("2017-08-31 12:00:01"), "5 mins", 
               change_on_boundary = FALSE)
ceiling_date(as.POSIXct("2017-08-31 12:00:01"), "5 mins", 
               change_on_boundary = TRUE)

#返回2017-08-31 13:00:00 CST
ceiling_date(as.POSIXct("2017-08-31 12:30:00"), "hour")
#返回2017-08-31 14:00:00 CST
ceiling_date(as.POSIXct("2017-08-31 12:30:00"), "2 hours")

#返回2017-08-31 CST,不进位
ceiling_date(as.POSIXct("2017-08-31"), 'day')
ceiling_date(as.POSIXct("2017-08-31"), 'day', change_on_boundary 
                = FALSE)
#返回2017-09-01 CST
ceiling_date(as.POSIXct("2017-08-31"), 'day', change_on_boundary 
                = TRUE)

#返回2017-08-31 CST,不进位
ceiling_date(as.POSIXct("2017-08-31 00:00:00"), 'day')
ceiling_date(as.POSIXct("2017-08-31 00:00:00"), 'day', 
                change_on_boundary = FALSE)
#返回2017-09-01 CST
ceiling_date(as.POSIXct("2017-08-31 00:00:00"), 'day', 
                change_on_boundary = TRUE)
#返回2017-09-01 CST
ceiling_date(as.POSIXct("2017-08-31 00:00:01"), 'day')
ceiling_date(as.POSIXct("2017-08-31 00:00:01"), 'day', 
                change_on_boundary = FALSE)

#返回2017-09-03 CST
ceiling_date(as.POSIXct("2017-08-30 11:59:59"), "week")

#返回2017-08-01 CST
ceiling_date(as.POSIXct("2017-08-01 00:00:00"), "month")
#返回2017-09-01 CST
ceiling_date(as.POSIXct("2017-08-01 00:00:01"), "month")
ceiling_date(as.POSIXct("2017-08-01 00:00:00"), "month", 
                change_on_boundary = TRUE)


#返回2017-07-01 CST
ceiling_date(as.POSIXct("2017-07-01 00:00:00"), "bimonth")
#返回2017-09-01 CST
ceiling_date(as.POSIXct("2017-07-01 00:00:01"), "bimonth")
ceiling_date(as.POSIXct("2017-07-01 00:00:00"), "bimonth", 
                change_on_boundary = TRUE)


#返回2017-07-01 CST
ceiling_date(as.POSIXct("2017-07-01 00:00:00"), "quarter")
#返回2017-10-01 CST
ceiling_date(as.POSIXct("2017-07-01 00:00:01"), "quarter")
ceiling_date(as.POSIXct("2017-07-01 00:00:00"), "quarter", 
                change_on_boundary = TRUE)

#返回2017-07-01 CST
ceiling_date(as.POSIXct("2017-07-01 00:00:00"), "halfyear")
#返回2018-01-01 CST
ceiling_date(as.POSIXct("2017-07-01 00:00:01"), "halfyear")
ceiling_date(as.POSIXct("2017-07-01 00:00:00"), "halfyear", 
                change_on_boundary = TRUE)

#返回2017-01-01 CST
ceiling_date(as.POSIXct("2017-01-01 00:00:00"), "year")
#返回2018-01-01 CST
ceiling_date(as.POSIXct("2017-01-01 00:00:01"), "year")
ceiling_date(as.POSIXct("2017-01-01 00:00:00"), "year", 
                change_on_boundary = TRUE)

3. 获取和修改时区

       关于时区的操作,lubridate提供了读取并修改时区属性的方法tz,但是修改时区属性并不会改变时间对象本身。可以使用with_tz和force_tz函数进行修改,前者将时间数据转换为另一个时区的同一时间,实际的时刻并没有改变,后者时间数据的时区强制转换为另一个时区,实际的时钟时刻已被修改, 如果输入的时区不存在,将使用默认的UTC时区。

#返回或设置日期对象中的timezone属性
tz(x)
tz(x) <- value

#在新时区下生成新的时钟时刻,实际时钟时刻并没有被修改
with_tz(time, tzone = "")

#在新的时区显示相同的时钟时刻,实际时钟时刻已改变
force_tz(time, tzone = "")
–	举例1:
#使用ymd_hms会自动分配UTC时区
tzone <- ymd_hms("2017-08-20 20:20:20")
#获取对象的时区
tz(tzone)
#更改时区并不会修改时间对象本身,只是修改了对象的时区属性
tz(tzone) <- "GMT"

–	举例2:
#美国的Estern time
est <- ymd_hms("2017-08-22 09:00:00", tz = "America/New_York")
#转换中国时区所对应的时钟时刻
with_tz(est, tzone = "Asia/Shanghai")

–	举例3:
#美国的Estern time
est <- ymd_hms("2017-08-22 09:00:00", tz = "America/New_York")
#只修改时区,时钟时刻不变,实际上原始的时刻已被修改
force_tz(est, tzone = "Asia/Shanghai")

4. 时间跨度

      lubridate对时间跨度有三种表示方式,包括Intervals, durations和periods。Interval可以不同的unit精确的记录时间跨度,但是对于较大的时间单位(小时,月,年等),可能会受到闰年和夏令时的影响。Durations显示在一段时间内发生的秒数,如果数字很大,会以更大的unit显示出估计值,底层通常被记录为固定的秒数,因此durations并不会受闰年和夏令时的影响。Periods用于记录两个datetime类型的时钟时间,可以用years, months, days, hours, minutes和seconds表示,除秒外其它单元都必须用整数表示,由于受闰年和夏令时的影响,period并没有固定的长度,除非与一个具体的开始时间配对后。

      durations类通常提供了更准确的运算结果, 一个duration年总是等于365天。 而periods是随着时间线的波动而给出更理性的结果,这一特点在建立时钟时间(clock times)的模型时非常有用。比方说,durations遇到闰年时,结果就太死板,而periods给出的结果就灵活很多。

  • 时间差(difftime)

make_difftime函数可以根据指定的unit创建difftime对象,显示的时候根据unit给出估计的值,底层依然以second记录时间。unit仅用于设置显示的unit

#生成difftime对象
make_difftime(num = NULL, units = "auto", ...)
–	举例1:
#以second记录时间差,按照unit显示,数值都是以second为单位
make_difftime(1)
make_difftime(60)
make_difftime(3600)
make_difftime(3600, units = "minute")

#以second记录时间差,按照unit显示
make_difftime(second = 3,minute = 1.5,hour = 2,day = 6, week = 1)
make_difftime(hour = 1, minute = -60)
make_difftime(day = -1)
#120表示120秒(2 mins)
make_difftime(120, day = -1, units = "minute")
  • 时间间隔(interval)

时间间隔由两个时间点(start time和end time)组成的Interval类对象,如果start time早于end time则interval为正,反之为负。

#interval函数用于生成时间间隔对象
interval(start, end, tzone = attr(start, "tzone"))
start %--% end
  • start : 开始时间,POSIXt 或者date-time对象;
  • end : 结束时间,POSIXt 或者date-time对象;
  • tzone : 用于显示时间间隔的时区
–	举例2:
date1 <- as.POSIXct("2009-03-08 01:59:59")
date2 <- as.POSIXct("2000-02-29 12:00:00")
#正interval
interval(date2, date1)
date2 %--% date1
#负interval
interval(date1, date2)
date1 %--% date2

 as.interval用于将描述时间间隔的对象duration, difftime, period或者numeric,结合POSIXt或Date对象表示的start time,转换为Interval对象。

#用于转换为interval对象
as.interval(x, start, ...)
–	举例3:
#difftime,转换为interval
diff <- make_difftime(days = 31) 
as.interval(diff, ymd("2009-01-01"))
as.interval(diff, ymd("2009-02-01"))
#duration,转换为interval
dur <- duration(days = 31) 
as.interval(dur, ymd("2009-01-01"))
as.interval(dur, ymd("2009-02-01"))
#period,转换为interval
per <- period(months = 1) 
as.interval(per, ymd("2009-01-01"))
as.interval(per, ymd("2009-02-01"))
#numeric,转换为interval,3600代表3600天
as.interval(3600, ymd("2009-01-01"))

interval操作函数

#判断是否为interval对象
is.interval(x)
#获取或设置interval的开始时间
int_start(int)
int_start(int) <- value
#获取或设置interval的结束时间
int_end(int)
int_end(int) <- value
#返回interval的长度
int_length(int)
#调换interval中开始时间和结束时间的顺序
int_flip(int)
#按给定的位移调整interval,使用duration和period实际的interval长度不变
int_shift(int, by)
#判断两个interval是否有重叠
int_overlaps(int1, int2)
#标准化interval,保证interval为正
int_standardize(int)
#判断两个interval是否使用相同的端点,不考虑interval的方向
int_aligns(int1, int2)
#返回日期时间向量间的间隔(interval对象)
int_diff(times)
#如果interval a完全在b中赶回TRUE(包括边界并且忽略顺序),否则返回FALSE
a %within% b
  • x:R对象
  • int,int1,int2: interval对象
  • by:period或者duration对象表示的位移值
  • times:POSIXct, POSIXlt或Date对象表示的向量
–	举例4:
date1 <- as.POSIXct("2017-09-01 01:59:59")
date2 <- as.POSIXct("2017-09-10 12:00:00")
#返回正的interval,结束时间大于开始时间
inter1 <- interval(date1, date2)
#提取开始时间和结束时间
int_start(inter1)
int_end(inter1)
#返回interval的长度以秒为单位,正interval返回813601秒
int_length(inter1)
#原interval向后调整一天,实际的int_length不变
int_shift(inter1, by = duration(days = 1))
int_shift(inter1, by = period(days = 1))

#返回负的interval,结束时间小于开始时间
inter2 <- date2 %--% date1
#返回interval的长度以秒为单位,负interval返回-813601秒
int_length(inter2)
#调换interval的顺序,转换后interval为正
int_flip(inter2)
#标准化interval,是interval保持为正
int_standardize(inter2)
#判断两个interval之间是否存在重叠,存在重叠返回TRUE
int_overlaps(inter1, inter2)
#判断两个interval之间是否存在重叠,不存在重叠返回FALSE
int_overlaps(inter1, int_shift(inter1, by = period(days = 10)))

#返回interval表示的各POSIXct对象间的差
dates <- now() + days(1:10)
int_diff(dates)

#返回TRUE,inter1完全在inter1中
inter1 %within% inter1
#返回TRUE,inter1完全在inter2中,忽略interval的正负(顺序)
inter1 %within% inter2
#返回FALSE,位移过后不完全在inter1中
int_shift(inter1, by = duration(days = 1)) %within% inter1
  • 持续时间(durations)

duration底层对象都是用秒表示,显示时,如果时间跨度较大,会同时使用较大单元的估计值。可以用minutes, hours, days 和weeks显示duration,超出week的unit变化较大,因此不能用于表示duration。

#创建duration对象
duration(num = NULL, units = "seconds", ...)
  • num:时间单元的数量,可以为字符向量,支持缩写;
  • units: 字符串表示的时间单元,默认为seconds,num为字符型时忽略该参数;
  • … : 时间单元列表,可以为seconds, minutes, hours, day和 weeks;
–	举例5:
#生成表示90s的duration对象
duration(90, "seconds")
duration(second = 90)
duration(minute = 1.5)
duration(mins = 1.5)
duration(1.5, "minutes")
#生成表示-86400s的duration对象
duration(day = -1)
duration(-1, "days")
#生成表示1130493s的duration对象,显示为1.87weeks
duration(second = 3, minute = 1.5, hour = 2, day = 6, week = 1)

#使用字符创建duration对象
duration("2M 1sec")
duration("2hours 2minutes 1second")
duration("2d 2H 2M 2S")
duration("2days 2hours 2mins 2secs")

#表示为两天
duration("day day")

#直接与字符串比较大小,返回TRUE
duration("day 2 sec") > "day 1sec"

#判断是否为duration对象
is.duration(as.Date("2017-09-10"))
is.duration(duration(days = 12.4))

转换period为duration时,period的实际大小取决于指定的开始时间,因此会转换为不精确的估计值,并不存在period到 duration一对一的转换。

#判断是否为duration对象
is.duration(x)
#用于转换 Interval, Period和numeric对象为duration对象
as.duration(x, ...)
–	举例6:
#判断是否为duration对象
is.duration(as.Date("2017-09-10"))
is.duration(duration(days = 12.4))

#转换interval对象为duration对象
span <- interval(ymd("2017-09-01"), ymd("2017-09-10"))
as.duration(span)

#转换numeric对象为duration对象,数字值单位为秒
as.duration(1000)

#转换perido对象为duration对象,转换的值为估计值
per <- period(months = 1)
as.duration(per)

创建duration对象

#使用seconds创建duration
dseconds(x = 1)
#使用minutes创建duration, 底层仍用second表示
dminutes(x = 1)
#使用hours创建duration, 底层仍用second表示
dhours(x = 1)
#使用days创建duration, 底层仍用second表示
ddays(x = 1)
#使用weeks创建duration, 底层仍用second表示
dweeks(x = 1)
#使用years创建duration, 底层仍用second表示
dyears(x = 1)
#使用milliseconds创建duration, 底层仍用second表示
dmilliseconds(x = 1)
#使用microseconds创建duration, 底层仍用second表示
dmicroseconds(x = 1)
#使用nanoseconds创建duration, 底层仍用second表示
dnanoseconds(x = 1)
#使用picoseconds创建duration, 底层仍用second表示
dpicoseconds(x = 1)
–	举例7:
#生成表示60s的duration对象
dminutes(x = 1)
dseconds(x = 60)
dmilliseconds(x = 60000)
dmicroseconds(x = 60000000)
dnanoseconds(x = 60000000000)
dpicoseconds(x = 60000000000000)

#生成表示1 day的duration对象
ddays(x = 1)
dhours(x = 24)
dminutes(x = 1440)
dweeks(x = 1/7)
#duration默认一年为365天
dyears(x = 1/365)
  • 时间周期(period)

period对象必须与实际的开始时间相结合后才有固定的长度,period的长度取决于匹配的开始时间,以2009-01-01 开始的一年有365天,以2012-01-01开始的年有366天。

#创建period对象
period(num = NULL, units = "second", ...)
#判断是否为period对象
is.period(x)
#用于转换 Interval, Period, difftime和numeric对象为period对象
as.period(x, unit, ...)
  • num:表示时间单元的数值向量;
  • units:字符向量表示的时间单元,与num必须有相同的长度;
  • … : 时间单元列表,可以为seconds, minutes, hours, day和 weeks;
–	举例8:
#表示period对象,num和units按顺序分别对应
period(c(90, 5), c("second", "minute"))
period(c(3, 1, 2, 13, 1), c("second", "minute", "hour", "day", "week"))
period(second = 3, minute = 1, hour = 2, day = 13, week = 1)
period(c(1, -60), c("hour", "minute"))
period (second = 90, minute = 5)
period(c(1, -60), c("hour", "minute"), hour = c(1, 2), minute = c(3, 4))
period("2hours 2minutes 1second")
period("2H 2mins 1sec")

–	举例9:
#判断是否为period对象
is.period(as.Date("2017-09-10"))
is.period(period(days = 1))

leap <- interval(ymd("2016-01-01"), ymd("2017-01-01"))
#返回366d 0H 0M 0S
as.period(leap, unit = "days")
#返回1y 0m 0d 0H 0M 0S
as.period(leap, unit = "years")

#转换数值为period,不设置unit默认为second,返回1000S
as.period(1000)
#转换数值为period,返回1000M 0S
as.period(1000, unit = 'mins')
#转换数值为period,返回1000d 0H 0M 0S
as.period(1000, unit = 'days')

#转换duration为period
as.period(dhours(x = 24))

#转换difftime为period
as.period(make_difftime(day = 1))

创建period对象

#使用seconds创建period
seconds(x = 1)
#使用minutes创建period
minutes(x = 1)
#使用hours创建period
hours(x = 1)
#使用days创建period
days(x = 1)
#使用weeks创建period
weeks(x = 1)
#使用years创建period
years(x = 1)
#使用milliseconds创建period
milliseconds(x = 1)
#使用microseconds创建period
microseconds(x = 1)
#使用nanoseconds创建period
nanoseconds(x = 1)
#使用picoseconds创建period
picoseconds(x = 1)
#使用month创建period
months(x, abbreviate)
–	举例10:
#创建表示1day的period对象
days(x = 1)
hours(x = 24)
minutes(x = 1440)
seconds(x = 86400)
weeks(x = 1/7)

#创建表示1year的period对象
years(x = 1)
months(x = 12)

5. 日期时间的计算

Datetime对象的计算比数值计算要复杂的多,时钟时刻需要随着夏令时,闰年和闰秒等周期性的校准,使得对时间的运算相对较复杂,而lubridate包可以简化时间的运算得到精确的计算结果。

–	举例13:
date <- as.POSIXct("2017-02-28 01:59:59")
#与period对象相加
date + days(1)
#与duration对象相加
date + ddays(1)

date2 <- as.POSIXct("2017-01-31 01:59:59")
#不存在的日期用NA表示
date2 + c(0:11) * months(1)
#超出每月最后一天的date,返回每月最后一天
date2 %m+% (c(0:11) * months(1))

#可以同时与duration和period对象加减
date2 - days(3) + hours(6)
date2 - ddays(3) + hours(6)

#可以同时与duration和difftime对象加减
date2 + make_difftime(day = 2) - ddays(3)

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!