Lubridate hour() 不适用于从 parse_date_time() 派生的时间

Lubridate hour() does not function with times derived from parse_date_time()

我不明白为什么从函数 parse_date_time 派生的时间不能被 lubridate() 中的另一个函数使用。 这会生成一个 df,其中 am/pm 的日期已正确解析。

  dt2 <- data.frame('date_time' = c("11/24/19 06:00:00 PM", 
                              "11/25/19 12:00:00 AM", 
                              "11/25/19 06:00:00 AM", 
                              "11/25/19 12:00:00 PM", 
                              "11/25/19 06:00:00 PM", 
                              "11/26/19 12:00:00 AM"), 
              'date' = c(1:6), 'time' = c(1:6)) %>% 
mutate(date_time = parse_date_time(date_time, orders = "mdy IMS %p"),
     date = date(date_time), 
     time = strftime(date_time,"%H:%M:%S", tz = "UTC"))

当我尝试从小时列中提取小时时出现错误:

  dt2 <- dt2 %>% mutate(hour_from_hour = hour(time))

错误:mutate()hour_from_hour 有问题。 我hour_from_hour = hour(time)。 x 字符串不是标准的明确格式

但是当我使用原始变量“date_time”时它工作正常。

  dt2 <- dt2 %>% mutate(hour_from_date_time = hour(date_time))

我的数据集有变量headers(有些是日期时间,有些已经解析)。如果我可以在时间列上使用 hour() 就好了。

如果我正确理解了您的问题,则此代码可以解答。它首先将小时的两位数字提取为字符串,然后将它们转换为整数。该代码假定前导零且无前导空格。如果要处理具有不同格式的案例,则需要编辑正则表达式。一旦找到要使用的功能,解决方案就相当简单,但我认为这并不简单。

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(stringr)

dt2 <- data.frame('date_time' = c("11/24/19 06:00:00 PM", 
                                  "11/25/19 12:00:00 AM", 
                                  "11/25/19 06:00:00 AM", 
                                  "11/25/19 12:00:00 PM", 
                                  "11/25/19 06:00:00 PM", 
                                  "11/26/19 12:00:00 AM"), 
                  'date' = c(1:6), 'time' = c(1:6)) %>% 
  mutate(date_time = parse_date_time(date_time, orders = "mdy IMS %p"),
         date = date(date_time), 
         time = strftime(date_time,"%H:%M:%S", tz = "UTC"))

# hour is of mode character, assuming that TZ is always UTC
dt2 <- dt2 %>% mutate(hour_from_hour = as.integer(str_extract(time, "^[0-2][0-9]")),
                      hour_from_date_time = hour(date_time))

identical(dt2$hour_from_hour, dt2$hour_from_date_time)
#> [1] TRUE

dt2
#>             date_time       date     time hour_from_hour hour_from_date_time
#> 1 2019-11-24 18:00:00 2019-11-24 18:00:00             18                  18
#> 2 2019-11-25 00:00:00 2019-11-25 00:00:00              0                   0
#> 3 2019-11-25 06:00:00 2019-11-25 06:00:00              6                   6
#> 4 2019-11-25 12:00:00 2019-11-25 12:00:00             12                  12
#> 5 2019-11-25 18:00:00 2019-11-25 18:00:00             18                  18
#> 6 2019-11-26 00:00:00 2019-11-26 00:00:00              0                   0

reprex package (v2.0.1)

于 2021-12-21 创建

R 没有原生方法来处理与一天无关的时间。但是你可以使用像 hms 这样的包。例如:

library(tidyverse)
library(lubridate)
library(hms)

dt2 <- data.frame('date_time' = c("11/24/19 06:00:00 PM", 
                                  "11/25/19 12:00:00 AM", 
                                  "11/25/19 06:00:00 AM", 
                                  "11/25/19 12:00:00 PM", 
                                  "11/25/19 06:00:00 PM", 
                                  "11/26/19 12:00:00 AM"), 
                  'date' = c(1:6), 'time' = c(1:6)) %>% 
    mutate(date_time = parse_date_time(date_time, orders = "mdy IMS %p"),
           date = date(date_time), 
           time = as_hms(date_time),
           hour = hour(time))

但老实说,最好保留 date_time 列并直接在其上使用 hour