用lubridate操作时间和日期

一、介绍

乍看之下,日期和时间很简单,因为生活中很常用。但是细看下来,它可以很复杂。
本文介绍lubridate包来操作时间,需要额外加载这个包。
本文操作的数据表是nycflights13,也需要提起加载。
之前我们用的tidyverse包,也会用到它的函数,所以一起加载。

二、日期和时间操作

1. 三种形式

  1. date:tidyverse会以<date>标注。
  2. time:tidyverse中以<time>标注。
  3. date-time:顾名思义是一个date加上一个time,以<dttm>标注。在其他地方,这种类型在R中也被称为POSIXct,了解一下即可。

我们在这一篇文章里,主要分享关于date和date-time的内容,因为r中直接对时间操作的场合比较少。

2. 获得时间

today()获得一个date。
now()获得一个date-time。

3. 创建时间

a.从字符串创建

方法一:parse_datetime()、parse_date()、parse_time()
parse_datetime函数需要一个具有标准格式的参数传入。这个格式是从大时间到小时间。比如"2024-05-30T0922"就指的是2024年5月30日9点22分。如果你不写时间的话,会直接设置成半夜。

parse_date需要传入4位数的年份加上两位数月份、两位数日,中间用"-“或者”/"连接。
也就是下面这种:

parse_date("2024-05-03")

方法二:ymd_hms
这个方法很有创造力。
也就是在函数名中明确字符串的顺序。
如果你用的函数是ymd,也就是说告诉R你的字符串是按照year\month\day来安排的。
如果你用的mdy,那就是说字符串是按照month\day\year来安排的。
我们试验一下:

> ymd("20240530")
[1] "2024-05-30"
> mdy(05302024)
[1] "2024-05-30"

而且,你可以发现,日期在这里不用引号也可以。这就使语句变得极为简练。

还以把ymd_hms结合使用

> ymd_hms("20240530 082210")
[1] "2024-05-30 08:22:10 UTC"
> mdy_hm("05302024 0822")
[1] "2024-05-30 08:22:00 UTC"

b. 从独立的date-time组件中创建

大家还记得nycflights13这个数据集中flights表吧。
在这里插入图片描述
里面有几列,分别是year、month、day、hour、minute,这些就是我们说的date-time组件(component)。

我们可以通过make_date()或者是make_datetime()来创建一个date-time。
比如:

flights %>% select(year,month,day,hour,minute) %>% mutate(departure=make_datetime(year,month,day,hour,minute))

在这里插入图片描述

案例

我们再看一下flights表中有四个时间非常怪。
分别是:
dep_time, arr_time
实际出发和到达时间(格式为HHMM或HMM),当地时区。

sched_dep_time, sched_arr_time
预定出发和到达时间(格式为HHMM或HMM),当地时区。

在这里插入图片描述
以第一条数据为例,代表这次航班出发时间是5点17分,计划出发时间是5点15分,以此类推。
我们希望能够把这种时间变成常用的时间格式。

那思路很简单,以dep_time为例:
第一个flight的dep_time为517,那用517除以100,得到的商就是小时,余数就是分钟。
再结合make_time函数生成一个时间。

那我们可以这样写代码:

flights_dt <- flights %>% filter(!is.na(dep_time),!is.na(arr_time)) %>% mutate(dep_time=make_datetime(year,month,day,dep_time%/%100,dep_time%%100),arr_time=make_datetime(year,month,day,arr_time%/%100,arr_time%%100),sched_dep_time=make_datetime(year,month,day,sched_dep_time%/%100,sched_dep_time%%100),sched_arr_time=make_datetime(year,month,day,sched_arr_time%/%100,sched_arr_time%%100))

结果如下:

也就是说,时间都换成了datetime模式。

简单地回顾一下代码:
代码最开始使用filter筛选出空值,然后用mutate函数,构建四个变量dep_time,arr_time,sched_dep_time,sched_arr_time,在构建的时候,用make_datetime来构建出一个时间。
PS:因为构建方式类似,也可以自己创建一个函数,简化代码。

有了这些时间数据之后,我们可以视觉化一下一年内每天离开飞机数量的分布。

flights_dt %>% ggplot(aes(dep_time))+geom_freqpoly(binwidth=86400)

86400代表1天,即86400秒。
在这里插入图片描述

上面是统计了一年的每天飞机起飞数量,我们也可以具体到某一天。比如,我们想看看5月1号那一天每一分钟的起飞飞机数量:

flights_dt %>% filter(dep_time > ymd(20130501) & dep_time < ymd(20130502)) %>% ggplot(aes(dep_time))+geom_freqpoly(binwidth=600)

在这里插入图片描述

如果没有这样的一个时间,我们用之前的数据做这样的统计还是会遇到很多麻烦的。

反向操作:从datetime中提取日期时间组件(components)

这几个函数相对简单,大家看看代码就清楚了:

> datetime1 <- now()
> datetime1
[1] "2024-05-30 22:56:09 CST"
> year(datetime1)
[1] 2024
> month(datetime1)
[1] 5
> mday(datetime1)
[1] 30
> yday(datetime1)
[1] 151
> wday(datetime1)
[1] 5
> hour(datetime1)
[1] 22
> minute(datetime1)
[1] 56
> second(datetime1)
[1] 9.774509
> month(datetime1,label=TRUE)
[1] May
12 Levels: Jan < Feb < Mar < Apr < May < Jun < ... < Dec
> wday(datetime1,label=TRUE)
[1] Thu
Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat

简单说一下:
year:提取年
month:提取月(加上label=TRUE,会返回月份简短写法)
mday:提取当月第几天
yday:当年第几天
wday:当周第几天(加上label=TRUE,会返回周几简短写法)
hour:提取小时
minute:提取分钟
second:提取秒

例1:

我们可以用wday来看一年中周几的起飞飞机量最多。

flights_dt %>% mutate(wday=wday(dep_time,label=TRUE)) %>% ggplot(aes(wday))+geom_bar()

在这里插入图片描述
看起来周内起飞的飞机还比较平均,但周内比周末普遍要多。

例2

我们想看看一小时内每分钟延迟的飞机数量。

flights_dt %>% mutate(minute=minute(dep_time)) %>% group_by(minute) %>% summarize(avg_delay=mean(arr_delay,na.rm=TRUE),n=n()) %>% ggplot(aes(minute,avg_delay))+geom_line()

结果如下:
在这里插入图片描述

日期近似值
> now()
[1] "2024-05-31 09:26:16 CST"
> floor_date(now(),"hour")
[1] "2024-05-31 09:00:00 CST"
> floor_date(now(),"minute")
[1] "2024-05-31 09:26:00 CST"
> ceiling_date(now(),"hour")
[1] "2024-05-31 10:00:00 CST"
> ceiling_date(now(),"minute")
[1] "2024-05-31 09:27:00 CST"
> round_date(now(),"minute")
[1] "2024-05-31 09:27:00 CST"
> round_date(now(),"hour")
[1] "2024-05-31 09:00:00 CST"

如果了解其它语言就知道,这类似于其他语言对带小数点的数取近似值。只不过现在换成了对时间取近似值。

比如,我们想知道每一周的起飞数量的变化。那这需要把一周的时间转化为同一个日期。
这时候我们可以用floor_date(datetime,“week”)这个函数。这个函数会把日期转换为本周第一天。

flights_dt %>% count(week=floor_date(dep_time,"week")) %>% ggplot(aes(week,n))+geom_line()

在这里插入图片描述

c. 从已存的date/time对象中创建

4. 日期时间之间转换

如果要把date转化成datetime,用as_datetime();
如果要把datetime转化成date,用as_date();

5. 修改时间

修改时间有两种方式,第一种就是直接赋值

year(datetime)<-2022

第二种方式是用update函数

update(datetime,year=2022,month=6,mday=2,hour=2)
lubridate包是R语言中用于处理日期时间数据的工具包。它提供了一组简单而灵活的函数,可以解析、操作和计算日期时间对象。lubridate包主要分为两类函数:处理时点数据(time instants)和处理时段数据(time spans)。对于时点数据,lubridate包提供了函数来解析各种日期时间格式的数据,并提供了函数来提取日期时间的各个组成部分,如年、月、日、小时、分钟和秒。对于时段数据,lubridate包提供了函数来计算和操作日期时间之间的差异,如计算两个日期之间的天数、小时数和分钟数等。 以下是使用lubridate包处理日期时间数据的一些常见操作: 1. 解析日期时间数据: 使用`ymd()`函数解析年-月-日格式的日期数据。 使用`ymd_hms()`函数解析年-月-日 时:分:秒格式的日期时间数据。 2. 提取日期时间的组成部分: 使用`year()`函数获取日期时间的年份。 使用`month()`函数获取日期时间的月份。 使用`day()`函数获取日期时间的日。 使用`hour()`函数获取日期时间的小时。 使用`minute()`函数获取日期时间的分钟。 使用`second()`函数获取日期时间的秒。 3. 计算日期时间之间的差异: 使用`interval()`函数创建时间间隔对象。 使用`%--%`运算符计算两个日期时间之间的差异。 4. 格式化日期时间数据: 使用`format()`函数将日期时间对象格式化为指定的字符串格式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值