在 R 中使用日期比使用其他对象类需要更多的注意力。下面,我们提供了一些工具和示例来减少这个过程的痛苦。幸运的是,可以通过练习轻松解决日期问题,并使用一组有用的软件包,例如lubridate。
在导入原始数据时,R 通常将日期解释为字符对象——这意味着它们不能用于一般的日期操作,例如制作时间序列和计算时间间隔。为了使事情变得更加困难,可以通过多种方式格式化日期,并且您必须帮助 R 知道日期的哪一部分代表什么(月、日、小时等)。
R 中的日期是它们自己的对象类 -Date
类。需要注意的是,还有一个类可以存储带有日期和时间的对象。日期时间对象正式称为POSIXt
、POSIXct
和/或POSIXlt
类(区别并不重要)。这些对象被非正式地称为日期时间类。
- 重要的是让 R 识别列何时包含日期。
- 日期是一个对象类,使用起来可能很棘手。
- 在这里,我们介绍了几种将日期列转换为 Date 类的方法。
准备
加载包
此代码块显示此页面所需的包的加载。在本手册中,我们强调p_load()
来自pacman,它会在必要时安装包并加载它以供使用。您还可以library()
从基础R 加载已安装的包。有关 R 包的更多信息,请参阅R 基础页面。
# Checks if package is installed, installs if necessary, and loads package for current session
pacman::p_load(
lubridate, # general package for handling and converting dates
linelist, # has function to "guess" messy dates
aweek, # another option for converting dates to weeks, and weeks to dates
zoo, # additional date/time functions
tidyverse, # data management and visualization
rio) # data import/export
导入数据
我们从模拟的埃博拉疫情中导入病例数据集。如果您想下载数据以逐步进行操作,请参阅下载手册和数据页面中的说明。我们假设该文件位于工作目录中,因此此文件路径中未指定子文件夹。
linelist <- import("linelist_cleaned.xlsx")
当前日期
您可以通过使用base R执行以下操作来获取计算机的当前“系统”日期或系统日期时间。
# get the system date - this is a DATE class
Sys.Date()
# get the system time - this is a DATETIME class
Sys.time()
使用lubridate包,这些也可以分别用today()
和返回now()
。date()
返回带有工作日和月份名称的当前日期和时间。
转换为日期
将数据集导入 R 后,日期列值可能类似于“1989/12/30”、“05/06/2014”或“13 Jan 2020”。在这些情况下,R 可能仍将这些值视为字符值。必须告诉R这些值是日期……以及日期的格式是什么(哪一部分是日,哪一部分是月,哪一部分是年,等等)。
一旦被告知,R 会将这些值转换为 Date 类。在后台,R 会将日期存储为数字(从其“起始”日期 1970 年 1 月 1 日算起的天数)。您不会经常与日期编号交互,但这允许 R 将日期视为连续变量并允许特殊操作,例如计算日期之间的距离。
默认情况下,R 中 Date 类的值显示为 YYYY-MM-DD。在本节后面,我们将讨论如何更改日期值的显示。
下面我们介绍两种将列从字符值转换为日期类的方法。
提示:您可以使用基本R 函数检查列的当前类class()
,例如class(linelist$date_onset)
.
Base R
as.Date()
是将对象或列转换为 Date 类的标准基本R 函数(注意“D”的大写)。
使用要求:
- 如果以数字形式提供日期,则指定原始字符日期的现有格式或原始日期(请参阅 Excel 日期部分)
- 如果在字符列上使用,所有日期值必须具有相同的确切格式(如果不是这种情况,请
guess_dates()
从linelist包中尝试)
首先,使用基础 R 检查列的类class()
。如果您对数据的类不确定或感到困惑(例如,您看到“POSIXct”等),最简单的方法是首先将列转换为字符类,使用as.character()
,然后将其转换为 Date 类。
其次,在as.Date()
函数中,使用format =
参数告诉 R 字符日期组件的当前格式——哪些字符指的是月、日和年,以及它们是如何分开的。如果您的值已经采用 R 的标准日期格式之一(“YYYY-MM-DD”或“YYYY/MM/DD”),format =
则不需要该参数。
要,使用下面的特殊“strptime”缩写提供表示当前format =
日期格式的字符串(用引号引起来) 。例如,如果您的字符日期当前采用“DD/MM/YYYY”格式,例如“24/04/1968”,那么您可以使用format = "%d/%m/%Y"
将值转换为日期。将格式放在引号中是必要的。不要忘记任何斜线或破折号!
# Convert to class date
linelist <- linelist %>%
mutate(date_onset = as.Date(date_of_onset, format = "%d/%m/%Y"))
下面列出了大多数 strptime 缩写。您可以通过运行查看完整列表?strptime
。
%d = 月份的天数(5、17、28 等)
%j = 一年中的天数(儒略日 001-366)
%a = 工作日的缩写(周一、周二、周三等)
%A =整个工作日(周一、周二等) %w = 工作日编号(0-6,周日为 0)
%u = 工作日编号(1-7,周一为 1)
%W = 周编号(00-53,周一为周开始)
%U = 周数(01-53,星期日是周开始)
%m = 月数(例如 01、02、03、04)
%b = 缩写月份(一月、二月等)
%B = 完整月份(一月、二月等)
%y = 2 位数年份(例如 89)
%Y = 4 位数年份(例如 1989 年)
%h = 小时(24 小时制)
%m = 分钟
%s = 秒 % z = 与 GMT 的偏移量
%Z = 时区(字符)
提示:的format =
参数as.Date()
不是告诉 R 您希望日期的格式,而是告诉 R 在运行命令之前如何识别日期部分
提示:请确保在format =
参数中使用日期中出现的日期部分分隔符(例如 /、- 或空格)。
一旦值在日期类中,R 将默认以标准格式显示它们,即 YYYY-MM-DD。
lubridate
使用lubridate包可以更轻松地将字符对象转换为日期。这是一个tidyverse包,旨在使日期和时间的处理比在base R 中更简单和一致。由于这些原因,lubridate通常被认为是日期和时间的黄金标准包,并且在使用它们时推荐使用。
lubridate包提供了几个不同的帮助函数,旨在以一种直观的方式将字符对象转换为日期,并且比在as.Date()
. 这些函数特定于粗略的日期格式,但允许使用各种分隔符和日期的同义词(例如 01 vs Jan vs January)——它们以日期格式的缩写命名。
# install/load lubridate
pacman::p_load(lubridate)
该ymd()
函数灵活地将提供的日期值转换为年、月、日。
# read date in year-month-day format
ymd("2020-10-11")
## [1] "2020-10-11"
ymd("20201011")
该mdy()
函数灵活地将提供的日期值转换为月、日和年。
# read date in month-day-year format
mdy("10/11/2020")
## [1] "2020-10-11"
mdy("Oct 11 20")
该dmy()
函数灵活地将提供的日期值转换为日、月、年。
# read date in day-month-year format
dmy("11 10 2020")
## [1] "2020-10-11"
dmy("11 October 2020")
如果使用管道,使用lubridate将字符列转换为日期可能如下所示:
linelist <- linelist %>%
mutate(date_onset = lubridate::dmy(date_onset))
一旦值在日期类中,R 将默认以标准格式显示它们,即 YYYY-MM-DD。
请注意,上述函数最适用于 4 位数年份。两位数的年份可能会产生意想不到的结果,因为 lubridate 试图猜测世纪。
要将 2 位年份转换为 4 位年份(都在同一世纪),您可以转换为类字符,然后使用stringr包str_glue()
中的前缀将现有数字与前缀组合(请参阅Characters and strings)。然后转换为日期。
two_digit_years <- c("15", "15", "16", "17")
str_glue("20{two_digit_years}")
## 2015
## 2015
## 2016
## 2017
合并列
您可以使用lubridate函数make_date()
并将make_datetime()
多个数字列组合成一个日期列。例如,如果您在数据框中有数字列onset_day
、onset_month
和:onset_year
linelist
linelist <- linelist %>%
mutate(onset_date = make_date(year = onset_year, month = onset_month, day = onset_day))
Excel 日期
在后台,大多数软件将日期存储为数字。R 商店的历史可以追溯到 1970 年 1 月 1 日。因此,如果你运行,as.numeric(as.Date("1970-01-01))
你会得到0
.
Microsoft Excel 存储日期为 1899 年 12 月 30 日 (Windows) 或 1904 年 1 月 1 日 (Mac),具体取决于您的操作系统。有关详细信息,请参阅此Microsoft 指南。
Excel 日期通常以这些数值而不是字符的形式导入 R。如果您从 Excel 导入的数据集将日期显示为数字或字符,如“41369”……使用as.Date()
(或lubridate的as_date()
函数)进行转换,但不是提供上述“格式”,而是将 Excel 原始日期提供给参数origin =
。
如果 Excel 日期作为字符类型存储在 R 中,这将不起作用,因此请确保该数字是数字类!
注意:您应该以 R 的默认日期格式(“YYYY-MM-DD”)提供原始日期。
# An example of providing the Excel 'origin date' when converting Excel number dates
data_cleaned <- data %>%
mutate(date_onset = as.numeric(date_onset)) %>% # ensure class is numeric
mutate(date_onset = as.Date(date_onset, origin = "1899-12-30")) # convert to date using Excel origin
混乱的日期
linelistguess_dates()
包中的函数尝试读取包含许多不同格式日期的“杂乱”日期列,并将日期转换为标准格式。您可以在线阅读更多关于. 如果R 4.0.2 在 CRAN 上尚不可用,请尝试通过.guess_dates()guess_dates()
pacman::p_load_gh("reconhub/linelist")
例如guess_dates
,将看到以下字符日期“03 Jan 2018”、“07/03/1982”和“08/20/85”的向量,并将它们转换为 Date 类:2018-01-03
、1982-03-07
和1985-08-20
。
linelist::guess_dates(c("03 Jan 2018",
"07/03/1982",
"08/20/85"))
您可能包括的一些可选参数guess_dates()
是:
error_tolerance
- 不能被识别为允许日期的条目的比例(默认为 0.1 或 10%)last_date
- 最后一个有效日期(默认为当前日期)first_date
- 第一个有效日期。默认为 last_date 之前的五十年。
# An example using guess_dates on the column dater_onset
linelist <- linelist %>% # the dataset is called linelist
mutate(
date_onset = linelist::guess_dates( # the guess_dates() from package "linelist"
date_onset,
error_tolerance = 0.1,
first_date = "2016-01-01"
)
使用日期时间类
如前所述,R 还支持一个datetime
类——一个包含日期和时间信息的列。与Date
类一样,这些通常需要从character
对象转换为datetime
对象。
用时间转换日期
标准datetime
对象首先使用日期格式化,然后是时间组件 - 例如01 Jan 2020, 16:30。与日期一样,可以通过多种方式对其进行格式化,并且可以提供多种精度级别(小时、分钟、秒)。
幸运的是,还存在lubridate辅助函数来帮助将这些字符串转换为datetime
对象。这些函数是日期辅助函数的扩展,在末尾附加_h
(仅提供小时)、_hm
(提供小时和分钟)或_hms
(提供小时、分钟和秒)(例如 dmy_hms()
)。这些可以如图所示使用:
将只有小时的日期时间转换为日期时间对象
ymd_h("2020-01-01 16hrs")
ymd_h("2020-01-01 4PM")
## [1] "2020-01-01 16:00:00 UTC"
将带有小时和分钟的日期时间转换为日期时间对象
dmy_hm("01 January 2020 16:20")
## [1] "2020-01-01 16:20:00 UTC"
将带有小时、分钟和秒的日期时间转换为日期时间对象
mdy_hms("01 January 2020, 16:20:40")
## [1] "2020-01-20 16:20:40 UTC"
您可以提供时区,但它会被忽略。请参阅本页后面关于时区的部分。
mdy_hms("01 January 2020, 16:20:40 PST")
## [1] "2020-01-20 16:20:40 UTC"
使用数据框时,可以组合使用str_glue()
来自stringr包和适当的lubridate函数的时间和日期列来创建日期时间列。有关stringr的详细信息,请参阅字符和字符串页面。
在此示例中,linelist
数据框有一个格式为“小时:分钟”的列。要将其转换为日期时间,我们遵循以下几个步骤:
- 创建一个“干净”的入院时间列,其中缺失值用列中位数填充。我们这样做是因为lubridate不会对缺失值进行操作。将其与 column 结合
date_hospitalisation
,然后使用函数ymd_hm()
进行转换。
# packages
pacman::p_load(tidyverse, lubridate, stringr)
# time_admission is a column in hours:minutes
linelist <- linelist %>%
# when time of admission is not given, assign the median admission time
mutate(
time_admission_clean = ifelse(
is.na(time_admission), # if time is missing
median(time_admission), # assign the median
time_admission # if not missing keep as is
) %>%
# use str_glue() to combine date and time columns to create one character column
# and then use ymd_hm() to convert it to datetime
mutate(
date_time_of_admission = str_glue("{date_hospitalisation} {time_admission_clean}") %>%
ymd_hm()
)
单独转换时间
如果您的数据仅包含一个字符时间(小时和分钟),您可以使用strptime()
from base R 将它们转换为时间并进行操作。例如,要获得其中两个时间之间的差异:
# raw character times
time1 <- "13:45"
time2 <- "15:20"
# Times converted to a datetime class
time1_clean <- strptime(time1, format = "%H:%M")
time2_clean <- strptime(time2, format = "%H:%M")
# Difference is of class "difftime" by default, here converted to numeric hours
as.numeric(time2_clean - time1_clean) # difference in hours
## [1] 1.583333
但是请注意,如果没有提供日期值,则假定日期是今天。要将字符串日期和字符串时间组合在一起,请参阅上面部分中的如何使用stringr。阅读更多关于strptime()
这里。
要将一位数转换为两位数(例如,将小时或分钟“填充”前导零以实现 2 位数字),请参阅字符和字符串页面的“填充长度”部分。
提取时间
您可以使用hour()
、minute()
或lubridatesecond()
提取时间元素。
这是一个提取小时,然后按一天中的部分时间分类的示例。我们从列开始time_admission
,它是“HH:MM”格式的字符类。首先,strptime()
如上所述用于将字符转换为日期时间类。然后,用 提取小时hour()
,返回一个 0-24 之间的数字。最后,time_period
使用逻辑创建一列,case_when()
根据入场时间将行分类为早上/下午/晚上/晚上。
linelist <- linelist %>%
mutate(hour_admit = hour(strptime(time_admission, format = "%H:%M"))) %>%
mutate(time_period = case_when(
hour_admit > 06 & hour_admit < 12 ~ "Morning",
hour_admit >= 12 & hour_admit < 17 ~ "Afternoon",
hour_admit >= 17 & hour_admit < 21 ~ "Evening",
hour_admit >=21 | hour_admit <= 6 ~ "Night"))
使用日期
lubridate
还可用于各种其他功能,例如提取日期/日期时间的各个方面、执行日期算术或计算日期间隔
在这里,我们定义了用于示例的日期:
# create object of class Date
example_date <- ymd("2020-03-01")
提取日期组件
您可以提取常见的方面,例如月、日、工作日:
month(example_date) # month number
## [1] 3
day(example_date) # day (number) of the month
## [1] 1
wday(example_date) # day number of the week (1-7)
## [1] 1
您还可以从datetime
对象或列中提取时间分量。如果您想查看入场时间的分布,这可能很有用。
example_datetime <- ymd_hm("2020-03-01 14:45")
hour(example_datetime) # extract hour
minute(example_datetime) # extract minute
second(example_datetime) # extract second
有几个选项可以检索周。请参阅下面的流行病学周部分。
请注意,如果您希望以某种方式显示日期(例如“2020 年 1 月”或“3 月 20 日星期四”或“1977 年第 20 周”),您可以更灵活地执行此操作,如日期显示部分所述。
日期计算
您可以使用lubridate中的相应功能添加特定天数或周数。
# add 3 days to this date
example_date + days(3)
## [1] "2020-03-04"
# add 7 weeks and subtract two days from this date
example_date + weeks(7) - days(2)
## [1] "2020-04-17"
日期间隔
日期之间的差异可以通过以下方式计算:
- 确保两个日期都是上课日期
- 使用减法返回两个日期之间的“difftime”差异
- 如有必要,将结果转换为数值类以执行后续数学计算
下面计算并显示两个日期之间的间隔。您可以通过对 Date 类的值使用减法“减号”符号来查找间隔。但是请注意,返回值的类是“difftime”,如下所示,必须转换为数字。
# find the interval between this date and Feb 20 2020
output <- example_date - ymd("2020-02-20")
output # print
## Time difference of 10 days
class(output)
## [1] "difftime"
要对“difftime”进行后续操作,请将其转换为数字as.numeric()
。
所有这些都可以结合起来处理数据——例如:
pacman::p_load(lubridate, tidyverse) # load packages
linelist <- linelist %>%
# convert date of onset from character to date objects by specifying dmy format
mutate(date_onset = dmy(date_onset),
date_hospitalisation = dmy(date_hospitalisation)) %>%
# filter out all cases without onset in march
filter(month(date_onset) == 3) %>%
# find the difference in days between onset and hospitalisation
mutate(days_onset_to_hosp = date_hospitalisation - date_of_onset)
在数据框上下文中,如果缺少上述任一日期,则该行的操作将失败。这将导致一个NA
而不是一个数值。使用此列进行计算时,请务必将na.rm =
参数设置为TRUE
。例如:
# calculate the median number of days to hospitalisation for all cases where data are available
median(linelist_delay$days_onset_to_hosp, na.rm = T)
日期显示
一旦日期是正确的类,您通常希望它们以不同的方式显示,例如显示为“Monday 05 January”而不是“2018-01-05”。您可能还需要调整显示,以便按显示的日期元素对行进行分组 - 例如按月-年分组。
format()
使用基本R 功能调整日期显示format()
。此函数接受字符串(用引号括起来),以“%”strptime 缩写形式指定所需的输出格式(与 中使用的语法相同as.Date()
)。以下是大多数常见的缩写。
注意:使用format()
会将值转换为字符类,因此这通常用于分析结束或仅用于显示目的!您可以通过
运行查看完整列表。?strptime
%d = 月份的天数(5、17、28 等)
%j = 一年中的天数(儒略日 001-366)
%a = 工作日的缩写(周一、周二、周三等)
%A =整个工作日(周一、周二等)
%w = 工作日编号(0-6,周日为 0)
%u = 工作日编号(1-7,周一为 1)
%W = 周编号(00-53,周一为周开始)
%U = 周数(01-53,星期日是周开始)
%m = 月数(例如 01、02、03、04)
%b = 缩写月份(一月、二月等)
%B = 完整月份(一月、二月等)
%y = 2 位数年份(例如 89)
%Y = 4 位数年份(例如 1989 年)
%h = 小时(24 小时制)
%m = 分钟
%s = 秒
% z = 与 GMT 的偏移量
%Z = 时区(字符)
格式化今天日期的示例:
# today's date, with formatting
format(Sys.Date(), format = "%d %B %Y")
## [1] "15 December 2021"
# easy way to get full date and time (default formatting)
date()
## [1] "Wed Dec 15 20:25:53 2021"
# formatted combined date, time, and time zone using str_glue() function
str_glue("{format(Sys.Date(), format = '%A, %B %d %Y, %z %Z, ')}{format(Sys.time(), format = '%H:%M:%S')}")
## Wednesday, December 15 2021, +0000 UTC, 20:25:53
# Using format to display weeks
format(Sys.Date(), "%Y Week %W")
## [1] "2021 Week 50"
请注意,如果使用str_glue()
,请注意在预期的双引号内 " 您应该只使用单引号(如上所述)。
月-年
要将 Date 列转换为 Month-year 格式,我们建议您使用as.yearmon()
zoo包中的函数。这会将日期转换为“yearmon”类并保留正确的顺序。相反, usingformat(column, "%Y %B")
将转换为类 Character 并按字母顺序(不正确)对值进行排序。
下面,使用date_onset
as.yearmon()中的
函数yearmonth
从 column 创建一个新列。结果值的默认(正确)排序显示在表中。
# create new column
test_zoo <- linelist %>%
mutate(yearmonth = zoo::as.yearmon(date_onset))
# print table
table(test_zoo$yearmon)
##
## Apr 2014 May 2014 Jun 2014 Jul 2014 Aug 2014 Sep 2014 Oct 2014 Nov 2014 Dec 2014 Jan 2015 Feb 2015 Mar 2015 Apr 2015
## 7 64 100 226 528 1070 1112 763 562 431 306 277 186
相比之下,您可以看到只有 usingformat()
才能实现所需的显示格式,但不能正确排序。
# create new column
test_format <- linelist %>%
mutate(yearmonth = format(date_onset, "%b %Y"))
# print table
table(test_format$yearmon)
##
## Apr 2014 Apr 2015 Aug 2014 Dec 2014 Feb 2015 Jan 2015 Jul 2014 Jun 2014 Mar 2015 May 2014 Nov 2014 Oct 2014 Sep 2014
## 7 186 528 562 306 431 226 100 277 64 763 1112 1070
注意:如果您在 a 中工作ggplot()
并且只想调整日期的显示date_labels =
方式,则为in 参数提供 strptime 格式可能就足够了scale_x_date()
- 您可以使用"%b %Y"
or "%Y %b"
。请参阅ggplot 提示页面。
zoo也提供了该功能as.yearqtr()
,您可以边用scale_x_yearmon()
边用ggplot()
。
流行病学周
lubridate
有关按日期分组数据的更广泛示例,请参阅分组数据页面。下面我们简要描述按周对数据进行分组。
我们通常建议使用lubridatefloor_date()
中的函数unit = "week"
,并带有参数。这会将日期向下舍入到由week_start =
参数定义的一周的“开始” 。默认的星期开始是 1(星期一),但您可以指定一周中的任何一天作为开始(例如,星期天是 7)。用途广泛,floor_date()
可用于通过设置unit =
为“秒”、“分钟”、“小时”、“日”、“月”或“年”来向下舍入到其他时间单位。
返回值是一周的开始日期,在 Date 类中。Date 类在绘制数据时很有用,因为它很容易被ggplot()
.
如果您只对调整日期以在绘图中按周显示感兴趣,请参阅本页中有关日期显示的部分。例如,在绘制 Epicurve 时,您可以通过提供所需的 strptime “%” 命名法来格式化日期显示。例如,使用“%Y-%W”或“%Y-%U”返回年份和周数(分别给出周一或周日的周开始)。
每周计数
有关使用、和对数据进行分组的详细说明,请参阅分组数据页面。下面是一个简短的例子。count()
group_by()
summarise()
mutate()
使用floor_date()
with创建一个新的 'week' 列unit = "week"
count()
使用;获取每周的行数(案例)过滤掉任何缺少日期的案例- 完成
complete()
from tidyr以确保所有周都出现在数据中 - 即使是那些没有行/案例的周。默认情况下,任何“新”行的计数值为 NA,但您可以使用参数将它们设为 0,该fill =
参数需要一个命名列表(下面n
是计数列的名称)。
# Make aggregated dataset of weekly case counts
weekly_counts <- linelist %>%
drop_na(date_onset) %>% # remove cases missing onset date
mutate(weekly_cases = floor_date( # make new column, week of onset
date_onset,
unit = "week")) %>%
count(weekly_cases) %>% # group data by week and count rows per group (creates column 'n')
tidyr::complete( # ensure all weeks are present, even those with no cases reported
weekly_cases = seq.Date( # re-define the "weekly_cases" column as a complete sequence,
from = min(weekly_cases), # from the minimum date
to = max(weekly_cases), # to the maxiumum date
by = "week"), # by weeks
fill = list(n = 0)) # fill-in NAs in the n counts column with 0
Epiweek 替代品
请注意,lubridate还具有函数week()
、epiweek()
和isoweek()
,每个函数的开始日期和其他细微差别都略有不同。一般来说,floor_date()
应该是你所需要的。?week
通过进入控制台或阅读此处的文档来阅读这些功能的详细信息。
您可以考虑使用包aweek来设置流行病学周。您可以在 RECON 网站上阅读有关它的更多信息。它具有功能date2week()
,week2date()
您可以在其中设置周开始日week_start = "Monday"
。如果您想要“周”风格的输出(例如“2020-W12”),这个包是最简单的。aweek的另一个优点是,当date2week()
应用于日期列时,返回的列(周格式)自动属于类 Factor,并包括时间跨度内所有周的级别(这避免了上述额外步骤complete()
)。但是,一周没有将日期四舍五入到其他时间单位(例如月、年等)的功能。
时间序列的另一种替代方法也可以很好地显示“周”格式(“2020 W12”),它yearweek()
来自tsibble包,如时间序列和爆发检测页面所示。
转换日期/时区
当数据存在于不同时区时,在统一时区中标准化这些数据通常很重要。这可能会带来进一步的挑战,因为在大多数情况下,数据的时区部分必须手动编码。
在 R 中,每个datetime对象都有一个时区组件。默认情况下,所有 datetime 对象都将携带正在使用的计算机的本地时区 - 这通常特定于某个位置而不是指定的时区,因为时区通常会因夏令时而改变位置。如果没有日期的时间部分,就不可能准确地补偿时区,因为日期列所代表的事件不能归因于特定时间,因此不能合理地考虑以小时为单位的时间偏移。
为了处理时区,lubridate 中有许多帮助函数,可用于将 datetime 对象的时区从本地时区更改为不同的时区。通过将有效的 tz 数据库时区归属于 datetime 对象来设置时区。可以在此处找到这些列表 - 如果您使用数据的位置不在此列表中,则该时区附近的大城市可用并用于相同目的。
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
# assign the current time to a column
time_now <- Sys.time()
time_now
## [1] "2021-12-15 20:25:53 EST"
# use with_tz() to assign a new timezone to the column, while CHANGING the clock time
time_london_real <- with_tz(time_now, "Europe/London")
# use force_tz() to assign a new timezone to the column, while KEEPING the clock time
time_london_local <- force_tz(time_now, "Europe/London")
# note that as long as the computer that was used to run this code is NOT set to London time,
# there will be a difference in the times
# (the number of hours difference from the computers time zone to london)
time_london_real - time_london_local
## Time difference of 5 hours
滞后和超前计算
lead()
并且lag()
是dplyr包中的函数,可帮助查找向量中的先前(滞后)或后续(前导)值 - 通常是数字或日期向量。这在计算时间单位之间的变化/差异时很有用。
假设您要计算本周与上一周之间的病例数差异。数据最初以每周计数提供。
使用时lag()
或lead()
数据框中的行顺序非常重要!- 注意你的日期/数字是升序还是降序
首先,创建一个包含前一周(滞后)周值的新列。
- 控制向后/向前的单位数
n =
(必须是非负整数) - 用于
default =
定义放置在不存在行中的值(例如,没有滞后值的第一行)。默认情况下这是NA
. order_by = TRUE
如果您的行未按参考列排序,请使用
counts <- counts %>%
mutate(cases_prev_wk = lag(cases_wk, n = 1))
接下来,创建一个新列,它是两个案例列之间的差异:
counts <- counts %>%
mutate(cases_prev_wk = lag(cases_wk, n = 1),
case_diff = cases_wk - cases_prev_wk)
资源
lubridate tidyverse page
lubridate RStudio cheatsheet
R for Data Science page on dates and times
在线教程 日期格式