R-应用流行病学和公共卫生-8.日期处理

在 R 中使用日期比使用其他对象类需要更多的注意力。下面,我们提供了一些工具和示例来减少这个过程的痛苦。幸运的是,可以通过练习轻松解决日期问题,并使用一组有用的软件包,例如lubridate

在导入原始数据时,R 通常将日期解释为字符对象——这意味着它们不能用于一般的日期操作,例如制作时间序列和计算时间间隔。为了使事情变得更加困难,可以通过多种方式格式化日期,并且您必须帮助 R 知道日期的哪一部分代表什么(月、日、小时等)。

R 中的日期是它们自己的对象类 -Date类。需要注意的是,还有一个类可以存储带有日期时间的对象。日期时间对象正式称为POSIXtPOSIXct和/或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 位年份(都在同一世纪),您可以转换为类字符,然后使用stringrstr_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_dayonset_month和:onset_yearlinelist

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()(或lubridateas_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-031982-03-071985-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数据框有一个格式为“小时:分钟”的列。要将其转换为日期时间,我们遵循以下几个步骤:

  1. 创建一个“干净”的入院时间列,其中缺失值用列中位数填充。我们这样做是因为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"

日期间隔

日期之间的差异可以通过以下方式计算:

  1. 确保两个日期都是上课日期
  2. 使用减法返回两个日期之间的“difftime”差异
  3. 如有必要,将结果转换为数值类以执行后续数学计算

下面计算并显示两个日期之间的间隔。您可以通过对 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_onsetas.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()

  1. mutate()使用floor_date()with创建一个新的 'week' 列unit = "week"
  2. count()使用;获取每周的行数(案例)过滤掉任何缺少日期的案例
  3. 完成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
在线教程 日期格式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值