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

Posted

技术标签:

【中文标题】Lubridate hour() 不适用于派生自 parse_date_time() 的时间【英文标题】:Lubridate hour() does not function with times derived from parse_date_time() 【发布时间】:2022-01-22 12:00:33 【问题描述】:

我不明白为什么从函数 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))

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

【问题讨论】:

这是因为strftime()生成了字符类型的变量,而hour()需要不同类型的变量(有很多选项,包括POSIXct、Date、chron、zoo等)。见?strftime?hour 【参考方案1】:

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 可能会更好。

【讨论】:

【参考方案2】:

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

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 日创建

【讨论】:

以上是关于Lubridate hour() 不适用于派生自 parse_date_time() 的时间的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data:休眠查询缓存不适用于派生查询

为啥派生列组件的表达式不适用于 SSIS 中的空值?

Fortran 派生类型:重载赋值运算符不适用于“参数”属性

MPI 派生数据类型适用于浮点数,但不适用于双精度数。是对齐问题吗?

mpifort -DMPI 编译错误:派生类型“mpi_status”用作实际参数。适用于英特尔 Fortran,但不适用于 GNU Fortran

计划通知不适用于警报应用程序