在 R 中处理日期和日期时间时,lubridate 包是您的朋友。它有许多有用的功能,并且有专门设计用于返回日期时间的日期和时间组件的功能。
如果您是 R 新手,我强烈建议您阅读和通读 R for Data Science ebook,尤其是 Chapter 16 - Dates and times,以便使用 lubridate 包很好地了解日期和时间处理。
对于您的示例,您只有两列要提取日期和时间,这可以通过为每一列重复相同的代码相对容易地完成。如果您有很多列,@akrun 建议的 for 循环可能是可行的,或者您可以将数据从宽格式转换为长格式。
首先,我们制作一些样本数据
tibble(
start = '2021-09-18 16:45:32',
end = '2021-09-18 16:50:15'
) %>%
{. ->> my_data}
my_data
# # A tibble: 1 x 2
# start end
# <chr> <chr>
# 2021-09-18 16:45:32 2021-09-18 16:50:15
到目前为止,日期时间都是字符格式的(如 tibble 预览中列名下的 <chr> 所示)。因此,接下来我们使用lubridate::ymd_hms() 将它们转换为“正确的”日期时间格式。 ymd_hms() 采用以 'YYYY-MM-DD HH:MM:SS' 样式排列的字符格式日期时间,并将其转换为 R 中的日期时间 dttm 格式。
my_data %>%
mutate_all(ymd_hms) %>%
{. ->> my_data_2}
my_data_2
# # A tibble: 1 x 2
# start end
# <dttm> <dttm>
# 2021-09-18 16:45:32 2021-09-18 16:50:15
然后,我们可以使用lubridate::date() 仅提取日期时间的“日期”部分,并使用hms::as_hms 提取“时间”部分(参见this answer 解释hms::as_hms)。
my_data_2 %>%
mutate(
start_date = date(start),
start_time = hms::as_hms(start),
end_date = date(end),
end_time = hms::as_hms(end)
) %>%
{. ->> my_data_3}
my_data_3
# # A tibble: 1 x 6
# start end start_date start_time end_date end_time
# <dttm> <dttm> <date> <time> <date> <time>
# 2021-09-18 16:45:32 2021-09-18 16:50:15 2021-09-18 16:45:32 2021-09-18 16:50:15
根据您想要做什么,将您的“时间”存储为日期时间而不仅仅是时间组件可能是明智之举。这使得持续时间或时间差的计算更容易,尤其是当时间段跨越多个日期时。
此外,lubridate 还可以提取单独的时间组件,例如小时、分钟和秒,如果需要的话。例如,仅查找 start 列的这些组件:
my_data %>%
select(start) %>%
mutate(
start_hour = hour(start),
start_min = minute(start),
start_sec = second(start)
)
# # A tibble: 1 x 4
# start start_hour start_min start_sec
# <chr> <int> <int> <dbl>
# 2021-09-18 16:45:32 16 45 32