背景
在 R 中处理日期和日期时间时,lubridate 包是您的朋友。据我所知,YYYY-MM-DD 通常比 DD-MM-YYYY(或更糟糕的 MM-DD-YYYY)更受欢迎,并且通常是日期时间的默认格式。这是有道理的,因为这样日期时间组件是根据层次结构排列的,并且可以仅根据数值对多个值进行排序,如果使用没有实际日期/日期时间格式的数据(例如,以字符格式,或如果在其他程序中工作)。
所以,我认为 MS Excel 和 R 之间的日期格式值 看起来 不同的原因是,一旦 R 检测到/被告知它是日期格式,它可能默认为 YYYY-MM -DD外观。然而,根据我的经验,Excel 因日期和时间的误导性外观而臭名昭著,有时甚至无法解释。即使 Excel 将日期显示为 DD-MM-YYYY(或您设置的任何内容),它实际上可能不会以这种格式存储。如果您在文本编辑器中查看 .csv 版本,而不是在不告诉您的情况下尝试智能并更改值外观的 Excel,这可能会变得很明显。底线是:如果您遇到问题并且涉及 Excel,请不要相信 Excel。
在 R 中导入日期和日期时间
现在,谈谈你的问题。
- 因此,我们决定 YYYY-MM-DD 是显示日期和日期时间的首选方式,并且通常是 R 和
lubridate 中的默认设置。
- 如果您在 R 中有日期/日期时间数据,最好确保 R 知道这一点并以日期时间而不是字符格式存储值。如果您想操作、修改或可视化数据,这将特别有用。
首先我加载lubridate 包,然后以 YYYY-MM-DD HH:MM:SS 和 DD-MM-YYYY HH:MM:SS 格式写出一些示例值。
library(lubridate)
tibble(
date1 = "2019-01-01 22:05:00",
date2 = "02-01-2019 16:45:00"
) %>%
{. ->> my_dates}
# # A tibble: 1 x 2
# date1 date2
# <chr> <chr>
# 2019-01-01 22:05:00 02-01-2019 16:45:00
请注意,两个日期时间都是字符格式,如列名下的 <chr> 所示。
要将这些转换为日期时间格式,我们使用ymd_hms() 和朋友或as_datetime() 的lubridate 函数。正如?as_datetime 和?ymd_hms 所见,这些函数采用字符或数字格式的日期时间,并将它们转换为日期时间格式 - 它们不是用于修改现有日期时间格式的日期时间的显示方式(与设置 CRS 和重新投影空间数据之间的重要区别。
ymd_hms() 采用字符格式的日期时间,必须在 year-month-d ay hour-minute-s第二种格式,并将其转换为日期时间格式。如果日期时间字符不是该格式,则必须使用与字符格式匹配的不同函数,例如dmy_hms()、mdy_hm() 等。因此,让我们使用适当的函数将这些字符中的每一个转换为日期时间格式:
my_dates %>%
mutate(
date1 = ymd_hms(date1),
date2 = dmy_hms(date2)
) %>%
{. ->> my_dates_dttm}
my_dates_dttm
# # A tibble: 1 x 2
# date1 date2
# <dttm> <dttm>
# 2019-01-01 22:05:00 2019-01-02 16:45:00
或者,我们可以使用as_datetime() 并使用符号和符号outlined here 指定日期时间的确切格式。在本例中,%d 表示日期编号,%m 表示月份编号,%Y 表示年份编号(大写 Y 表示 4 位版本,小写为 2 位),%H 是小时数,%M 是分钟数(注意大写 - 不同于月份数),%S 是秒数。
my_dates %>%
mutate(
date1 = as_datetime(date1, format = '%Y-%m-%d %H:%M:%S'),
date2 = as_datetime(date2, format = '%d-%m-%Y %H:%M:%S')
) %>%
{. ->> my_dates_dttm}
# # A tibble: 1 x 2
# date1 date2
# <dttm> <dttm>
# 2019-01-01 22:05:00 2019-01-02 16:45:00
这些函数不能用于尝试转换日期时间的显示方式;如果你很幸运,你会得到NA,如果你不走运,你会得到格式不正确的数据。这就是All formats failed to parse. No formats found.等常见错误的来源,这经常发生在你使用dmy()而不是ymd(),或者指定format = 部分as_datetime()错误时;因为您告诉 R 年值是日值,例如数字 2019 不能是一天(最多 31)或一个月(最多 12)。例如,如果我们在date2 上错误地使用ymd_hms() 而不是dmy_hms(),我们会收到一条错误消息,并且日期时间格式的值为NA:
my_dates %>%
mutate(
date1 = ymd_hms(date1),
date2 = ymd_hms(date2)
)
# # A tibble: 1 x 2
# date1 date2
# <dttm> <dttm>
# 2019-01-01 22:05:00 NA
# Warning message:
# Problem with `mutate()` column `date2`.
# i `date2 = ymd_hms(date2)`.
# i All formats failed to parse. No formats found.
或者更糟糕的是,您混淆了日和月,而 R 没有意识到,因为这两个数字都小于 12,并且是月或日的可接受值。没有警告或错误消息,R 很高兴。这会在操作日期时间或计算时间差等时引起巨大的麻烦。
my_dates %>%
mutate(
date1 = ymd_hms(date1),
date2 = mdy_hms(date2)
)
# # A tibble: 1 x 2
# date1 date2
# <dttm> <dttm>
# 2019-01-01 22:05:00 2019-02-01 16:45:00
好吧,够了厄运和忧郁,回到我们格式化前后的示例数据。
my_dates
# # A tibble: 1 x 2
# date1 date2
# <chr> <chr>
# 2019-01-01 22:05:00 02-01-2019 16:45:00
my_dates_dttm
# # A tibble: 1 x 2
# date1 date2
# <dttm> <dttm>
# 2019-01-01 22:05:00 2019-01-02 16:45:00
所以,my_dates 和 my_dates_dttm 之间有两个区别。
- 两列现在都采用
<dttm> 格式,而不是<chr>(写在列名下)
- 因为两列现在都是 R 的日期时间格式,所以它们默认为 YYYY-MM-DD HH:MM:SS 显示样式。我建议让它们保持这种状态,然后继续您的计算/操作。
以不同的格式显示日期和日期时间
但是,如果您想以不同的格式显示日期时间,您可以使用format() 函数来实现。您必须使用我们在上面as_datetime() 中使用的相同符号指定您希望它们如何打印。
请注意,这会以字符格式返回日期时间,因此这对于任何计算或操作都没有多大用处,而应仅用作标签。
my_dates_dttm %>%
mutate(
date1_dmy = format(date1, format = '%d-%m-%Y %H:%M:%S')
)
# # A tibble: 1 x 3
# date1 date2 date1_dmy
# <dttm> <dttm> <chr>
# 2019-01-01 22:05:00 2019-01-02 16:45:00 01-01-2019 22:05:00
因为format() 返回一个字符,所以您选择的格式不需要是标准的日期时间格式。例如,这里我们只是混淆了日期时间的不同组成部分:
my_dates_dttm %>%
mutate(
date1_jumble = format(date1, format = '%S/%b-%H:%y-%d.%M')
) %>%
{. ->> my_dates_jumbled}
my_dates_jumbled
# # A tibble: 1 x 3
# date1 date2 date1_jumble
# <dttm> <dttm> <chr>
# 2019-01-01 22:05:00 2019-01-02 16:45:00 00/Jan-22:19-01.05
但是,这并不妨碍我们转换回日期时间格式 - 如果我们知道打印的确切格式。
my_dates_jumbled %>%
mutate(
date_1_unjumble = as_datetime(date1_jumble, format = '%S/%b-%H:%y-%d.%M')
)
# # A tibble: 1 x 4
# date1 date2 date1_jumble date_1_unjumble
# <dttm> <dttm> <chr> <dttm>
# 2019-01-01 22:05:00 2019-01-02 16:45:00 00/Jan-22:19-01.05 2019-01-01 22:05:00
更多信息
R for Data Science 一书是学习 R 的绝佳资源,如果您要使用此类数据,我强烈建议您阅读并完成 Chapter 16 - Dates and times 中的示例。