目录
1.日期和日期时间类型
2.从字符串生成日期数据
3.日期显示格式
4.访问日期时间的组成值
5.日期舍入计算
6.日期计算
6.1 时间长度
6.2 时间周期
6.3 时间区间
7.基本 R 软件的日期功能
7.1 生成日期和日期时间型数据
7.2 取出日期时间的组成值
7.3 日期计算
练习
1.日期和日期时间类型
载入扩展包的方式:
library(lubridate)
如果下面内容:
证明你没有安装此扩展包
此时需要安装扩展包,安装方式如下:
点击【程序包】,再点击【安装程序包】
然后,找到 China(Beijing 2)
然后找到需要安装的扩展包 lubridate
然后,点击【确定】即可,安装完成会出现如下内容
这次我们再此载入扩展包 lubridate
2.从字符串生成日期数据
函数 lubridate::today() 返回当前日期:
today()
返回:
函数 lubridate::now() 返回当前日期时间:
now()
返回:
在结果中,我们看到了 CST 字样,CST 是时区,这里使用了操作系统提供的当前时区。CST 不是一个含义清晰的时区,在不同国家对应不同的时区,在中国代表中国标准时间(北京时间)
ymd(c("2022-1-24","2022-01-24"))
返回:
月 - 日 - 年:
mdy(c("1-24-2022", "01-24-2022"))
返回:
日 - 月 - 年:
dmy(c("24-1-2022","24-01-2022"))
返回:
如果在年号只有两位数字时,默认对应到 1969-2068 范围。
make_date(2022, 1, 24)
返回:
ymd_hms("2022-1-24 19:26:35")
返回:
make_datetime(2022, 1, 24, 19, 32, 36)
返回:
用 lubridate::as_date() 可以将日期时间型转换为日期型,如
as_date(as.POSIXct("2022-01-24 19:32:36"))
返回:
用 lubridate::as_datetime() 可以将日期型数据转换为日期时间型,如
as_datetime(as.Date("2022-01-24"))
返回:
3.日期显示格式
x <- as.POSIXct(c('2022-1-24', '2022-01-24'))
as.character(x)
返回:
在 as.character() 中可以用 format 选项指定显示格式,格式中 “%Y” 代表四位的公元年号,“%m” 代表两位的月份数字,“%d” 代表两位的月内日期号
如 %m/%d/%Y 表示 月-日-年
x <- as.POSIXct(c('2022-1-24', '2022-01-24'))
as.character(x, format='%m/%d/%Y')
返回:
x <- as.POSIXct(c('2022-1-24', '2022-01-24'))
old.lctime <- Sys.getlocale('LC_TIME')
Sys.setlocale('LC_TIME', 'C')
返回:
as.character(x, format='%b%y')
返回:
Sys.setlocale('LC_TIME', old.lctime)
返回:
包含时间的转换,如
x <- as.POSIXct('2022-1-24 19:56:42')
as.character(x)
返回:
as.character(x, format='%H:%M:%S')
返回:
4.访问日期时间的组成值
- • year() 取出年
- • month() 取出月份数值
- • mday() 取出日数值
- • yday() 取出日期在一年中的序号,元旦为 1
- • wday() 取出日期在一个星期内的序号,但是一个星期从星期天开始,星期天为 1, 星期一为 2,星期六为 7。
- • hour() 取出小时
- • minute() 取出分钟
- • second() 取出秒
month(as.POSIXct("2022-1-24 19:56:42"))
返回:
提取日
mday(as.POSIXct("2022-1-24 19:56:42"))
返回:
提取日期在一个星期内的序号
wday(as.POSIXct("2022-1-24 19:56:42"))
x <- as.POSIXct("2022-1-24 20:08:15")
year(x) <- 2000
month(x) <- 1
mday(x) <- 1
x
返回:
update() 可以对一个日期或一个日期型向量统一修改其组成部分的值,如
x <- as.POSIXct("2022-1-24 20:08:15")
y <- update(x, year=2000)
y
返回:
5.日期舍入计算
x <- ymd_hms("2022-1-24 20:08:15")
floor_date(x, unit="10 minutes")
返回:
ceiling_date() 将时间向后归一化到 10 分钟的整数倍:
x <- ymd_hms("2022-1-24 20:08:15")
ceiling_date(x, unit="10 minutes")
返回:
round_date() 将时间归一化到最近的 10 分钟的整数倍,时间恰好是 5 分钟倍数时按照类似四舍五入的原则向上取整。例如
x <- ymd_hms("2022-1-24 20:08:15")
round_date(x, unit="10 minutes")
返回:
6.日期计算
- • 时间长度 (duration),按整秒计算
- • 时间周期 (period),如日、周
- • 时间区间 (interval),包括一个开始时间和一个结束时间
6.1 时间长度
d1 <- ymd_hms("2022-01-24 0:0:0")
d2 <- ymd_hms("2022-01-24 12:0:5")
di <- d2 - d1; di
返回:
结果显示与日期之间差别大小有关系,结果是类型是 difftime。
lubridate 包提供了 duration 类型,处理更方便:
as.duration(di)
返回:
dhours(1)
返回:
dhours(1) + dseconds(5)
返回:
dhours(1)*10
返回:
可以给一个日期加或者减去一个时间长度,结果严格数按推移的秒计算,如
d2 <- ymd_hms("2022-01-24 12:0:5")
d2 - dhours(5)
返回:
d2 <- ymd_hms("2022-01-24 12:0:5")
d2 + ddays(10)
返回:
时间的前后推移在涉及到时区和夏时制时有可能出现未预料到的情况。
用 unclass() 函数将时间长度数据的类型转换为普通数值,如:
unclass(dhours(1))
返回:
6.2 时间周期
years(2) + 10*days(1)
返回:
lubridate 的月度周期因为与已有函数名冲突,所以没有提供,需要使用 lubridate::period(num, units="month") 的格式,其中 num 是几个月的数值。
ymd("2016-01-01") + dyears(1)
返回:
使用时间周期函数则得到预期结果:
ymd("2016-01-01") + years(1)
返回:
6.3 时间区间
构造如:
d1 <- ymd_hms("2000-01-01 0:0:0")
d2 <- ymd_hms("2000-01-02 12:0:5")
din <- (d1 %--% d2); din
返回:
对一个时间区间可以用除法计算其时间长度,如
din / ddays(1)
返回:
din / dseconds(1)
返回:
生成时间区间,也可以用 lubridate::interval(start, end) 函数,如
interval(ymd_hms("2000-01-01 0:0:0"), ymd_hms("2000-01-02 12:0:5"))
返回:
可以指定时间长度和开始日期生成时间区间,如
d1 <- ymd("2022-01-24")
din <- as.interval(dweeks(1), start=d1); din
返回:
int_start(din)
返回:
int_end(din)
返回:
din2 <- int_shift(din, by=ddays(3)); din2
返回:
用 lubridate::int_overlaps() 判断两个时间区间是否有共同部分,如
int_overlaps(din, din2)
返回:
int_intersect <- function(int1, int2){
n <- length(int1)
int1 <- lubridate::int_standardize(int1)
int2 <- lubridate::int_standardize(int2)
sele <- lubridate::int_overlaps(int1, int2)
inter <- rep(lubridate::interval(NA, NA), n)
if(any(sele)){
inter[sele] <-
lubridate::interval(pmax(lubridate::int_start(int1[sele]),
lubridate::int_start(int2[sele])),
pmin(lubridate::int_end(int1[sele]),
lubridate::int_end(int2[sele])))
}
inter
}
测试如下:
d1 <- ymd(c("2018-01-15", "2018-01-18", "2018-01-25"))
d2 <- ymd(c("2018-01-21", "2018-01-23", "2018-01-30"))
din <- interval(d1, d2); din
返回:
接下来,我们用用上面自定义的函数试试:
首先得先导入这个函数
source("D:/桌面/R语言/int_intersect.r")
然后,我们调用一下
int_intersect(rep(din[1], 2), din[2:3])
返回:
此自定义函数还可以进一步改成允许两个自变量长度不等的情形。
7.基本 R 软件的日期功能
7.1 生成日期和日期时间型数据
x <- as.Date("2022-1-24"); x
返回:
as.numeric(x)
返回:
as.Date() 可以将多个日期字符串转换成 Date 类型,如
as.Date(c("2022-1-24", "2022-01-24"))
返回:
as.Date("1/24/2022", format="%m/%d/%Y")
返回:
as.POSIXct(c('2022-1-24'))
返回:
as.POSIXct(c('2022/01/24'))
返回:
as.POSIXct('2022-01-24 13:15:45')
返回:
as.POSIXct(c('1998-03-16 13:15:45', '2015-11-22 9:45:3'))
返回:
x <- as.POSIXct(c('1998-03-16 13:15:45', '2015-11-22 9:45:3'))
attributes(x)
返回:
在 as.POSIXct() 函数中用 format 参数指定一个日期格式。如
as.POSIXct('1/24/22', format='%m/%d/%y')
返回:
as.POSIXct(paste('1991-12', '-01', sep=''), format='%Y-%m-%d')
返回:
又如
old.lctime <- Sys.getlocale('LC_TIME')
Sys.setlocale('LC_TIME', 'C')
返回:
as.POSIXct(paste('01', 'DEC91', sep=''), format='%d%b%y')
返回:
Sys.setlocale('LC_TIME', old.lctime)
返回:
把'DEC91' 转换成了’1991-12-01’。
as.POSIXct('1949-10-01', tz='Etc/GMT+8')
返回:
7.2 取出日期时间的组成值
x <- as.POSIXct('1998-03-16 13:15:45')
y <- as.POSIXlt(x)
cat(1900+y$year, y$mon+1, y$mday, y$hour, y$min, y$sec, '\n')
返回:
x <- as.POSIXct(c('1998-03-16', '2015-11-22'))
as.POSIXlt(x)$year + 1900
返回:
7.3 日期计算
x <- as.Date("1970-1-5")
x1 <- x + 10; x1
返回:
x2 <- x - 5; x2
返回:
as.POSIXct(c('1998-03-16 13:15:45')) - 30
返回:
as.POSIXct(c('1998-03-16 13:15:45')) + 10
返回:
as.POSIXct(c('1998-03-16 13:15:45')) + 3600*24*2
返回:
x <- as.POSIXct(c('1998-03-16', '2015-11-22'))
c(difftime(x[2], x[1], units='days'))
返回:
x <- as.POSIXct(c('1998-03-16 13:15:45', '2015-11-22 9:45:3'))
c(difftime(x[2], x[1], units='days'))
返回:
difftime() 中 units 选项还可以取为 'secs', 'mins', 'hours' 等。
练习
date1 <- dates.tab[,' 出生日期']
date2 <- dates.tab[,' 发病日期']