R语言lubridate包处理日期时间


本文首发于公众号:医学和生信笔记,完美观看体验请至公众号查看本文。



R语言的日期和时间问题很复杂,各种转换和计算、解析等都有明确的要求,而且由于格式复杂,经常会遇到各种问题。

lubridate包是专门用来处理日期时间数据的,设计转换、解析、计算等多种功能。

要想完全搞明白R语言里面的日期时间实在不是简单的事情,除了搞懂R里面的格式和各种函数的用法外,还要充分了解各种地理知识!比如时区、自然年、ISO年、国际日期变更线、闰年、闰月、夏令时、冬令时、时间的加减等。

简介

  • date-time

以秒为单位,类似于:2022-03-13 12:09:10 UTC

library(lubridate)
## 
## 载入程辑包:'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union

dt <- as_datetime(2211870400) # 从1970-01-01 00:00:00开始算经过了多少秒
dt
## [1] "2040-02-03 08:26:40 UTC"
  • date

以天为单位,也是自1970年1月1日开始

d <- as_date(18090)
d
## [1] "2019-07-13"
  • time

以秒为单位,没有日期,只有时分秒

t <- hms::as_hms(85)
t
## 00:01:25

解析date-time

可用于把字符串(string)或者数值(number)转化为date-time类型。

  • 识别数据中的年、月、日、时、分、秒
  • 使用以下函数识别不同顺序的date-time,每个函数都可以接受tz参数用于设置时区

常用解析函数

y、m、d、h、m、s分别代表年、月、日、时、分、秒,字母的顺序就代表你的数据中日期时间的顺序。

ymd_hms()
ymd_hm()
ymd_h()

ydm_hms()
ydm_hm()
ydm_h()

mdy_hms()
mdy_hm()
mdy_h()

dmy_hms()
dmy_hm()
dmy_h()

ymd()
ydm()
mdy()
myd()
dmy()
dym()

yq():q代表季节

my()
ym()

从以上函数相信你应该可以看出:

不能是单独的几月几日,例如3-13这种,是识别不了的!

对于解析日期来说,如果是字符型,默认的分隔符是/或者-,其他的分隔符都不能识别!

例子

下面是一些正确解析的例子,什么样的数据就要使用什么样的函数,错了就无法识别!

# 常见格式
ymd_hms("2017-11-28T12:00:00")
## [1] "2017-11-28 12:00:00 UTC"

ymd_hms("2022-02-12 13:21:45")
## [1] "2022-02-12 13:21:45 UTC"

ymd_hm("2022-02-13 14:00")
## [1] "2022-02-13 14:00:00 UTC"
ymd_h("2022/01/23 13")
## [1] "2022-01-23 13:00:00 UTC"

mdy_hm("03/11/2021 12:23")
## [1] "2021-03-11 12:23:00 UTC"

# 英文也是可以的
dmy_hms("1 Jan 2017 23:12:34") # 月份首字母大小写都可以
## [1] "2017-01-01 23:12:34 UTC"

mdy("july 4th, 2022") #4或者4th都可以
## [1] "2022-07-04"

dmy("4th of July 2020")
## [1] "2020-07-04"

# 从数值解析
ymd(20220216)
## [1] "2022-02-16"
mdy(03122022)
## [1] "2022-03-12"

# 季节
yq("2022:Q2") #q或者Q都可以
## [1] "2022-04-01"

其他例子

如果是以小数点分割的年月类型,且是数值型,也是可以解析的:

date_decimal(2022.3)
## [1] "2022-04-20 11:59:59 UTC"
date_decimal(2022.03)
## [1] "2022-01-11 22:47:59 UTC"

快速获取当前的日期和时间:

now()
## [1] "2022-04-01 15:48:15 CST"
today()
## [1] "2022-04-01"

快速解析日期时间:

# 基于C写的,解析速度快,数据量大时才能体现,这3个函数用法基本一样
fast_strptime()
parse_date_time()
parse_date_time2()

下面是用于解析多个时间日期的函数,在日常接触到的数据中,这几个函数才是最常用的也是最好用的。

# 多个字符
x <- c("09-01-01", "09-01-02", "09-01-03")
parse_date_time(x, "ymd")
## [1] "2009-01-01 UTC" "2009-01-02 UTC" "2009-01-03 UTC"
parse_date_time(x, "y m d")
## [1] "2009-01-01 UTC" "2009-01-02 UTC" "2009-01-03 UTC"
parse_date_time(x, "%y%m%d")
## [1] "2009-01-01 UTC" "2009-01-02 UTC" "2009-01-03 UTC"


## 多种格式
x <- c("09-01-01", "090102", "09-01 03", "09-01-03 12:02")
parse_date_time(x, c("ymd", "ymd HM"))
## [1] "2009-01-01 00:00:00 UTC" "2009-01-02 00:00:00 UTC"
## [3] "2009-01-03 00:00:00 UTC" "2009-01-03 12:02:00 UTC"

## 顺序不一样
x <- c("2009-01-01", "02022010", "02-02-2010")
parse_date_time(x, c("dmY", "ymd"))
## [1] "2009-01-01 UTC" "2010-02-02 UTC" "2010-02-02 UTC"


## 格式不全,可使用truncated参数解决
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)
## [1] "2011-12-31 12:59:59 UTC" "2010-01-01 12:11:00 UTC"
## [3] "2010-01-01 12:00:00 UTC" "2010-01-01 00:00:00 UTC"

## 指定顺序,使用exact参数
parse_date_time(x, c("%m-%d-%y", "%m%d%y", "%m-%d-%y %H:%M"), exact = TRUE) # 解析失败,因为顺序不一样
## [1] NA NA NA NA
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) # 顺序一样解析成功
## [1] "1996-12-17 04:00:00 UTC" "1950-04-18 01:30:00 UTC"

## 含有季节
parse_date_time(c("2016.2", "2016-04"), orders = "Yq")
## [1] "2016-04-01 UTC" "2016-10-01 UTC"
parse_date_time(c("2016", "2016-04"), orders = c("Y", "Ym"))
## [1] "2016-01-01 UTC" "2016-04-01 UTC"

获取和设定成分

可用于提取日期时间类型的特定成分,比如提取年、月、日、时、分、秒等;也可单独改变这些成分。

主要包括以下函数

x <- "2022-01-23 14:23:09"

date(x) # 获取日期
## [1] "2022-01-23"

year(x) # 获取年
## [1] 2022
isoyear(x)
## [1] 2022
epiyear(x)
## [1] 2022

month(x) # 获取月
## [1] 1

day(x)
## [1] 23
wday(x) # 一周中的第几天
## [1] 1
qday(x) # 一个季度中的第几天
## [1] 23

hour(x)
## [1] 14

minute(x)
## [1] 23

second(x)
## [1] 9

tz(x) # 获取时区
## [1] "UTC"

week(x) # 一年中的第几周
## [1] 4
isoweek(x)
## [1] 3
epiweek(x)
## [1] 4

quarter(x) # 一年中的第几季
## [1] 1
semester(x) # 上半年还是下半年
## [1] 1

am(x)
## [1] FALSE
pm(x)
## [1] TRUE

dst(x) # 是不是夏令时
## [1] FALSE

leap_year(x) # 是不是闰年!
## [1] FALSE

对日期时间取约数

x <- ymd_hms("2017-11-28 12:00:00")

floor_date(x, unit = "month")
## [1] "2017-11-01 UTC"
floor_date(x, unit = "day")
## [1] "2017-11-28 UTC"

round_date(x) # 四舍五入
## [1] "2017-11-28 12:00:00 UTC"

ceiling_date(x) # 取小
## [1] "2017-11-28 12:00:00 UTC"

lubridate包还有一块很重要的内容是日期时间的计算,不过由于在我的日产工作中用得不多,还没有仔细学习过,以后再说!


本文首发于公众号:医学和生信笔记,完美观看体验请至公众号查看本文。


  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值