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() 的时间的主要内容,如果未能解决你的问题,请参考以下文章
Fortran 派生类型:重载赋值运算符不适用于“参数”属性
MPI 派生数据类型适用于浮点数,但不适用于双精度数。是对齐问题吗?
mpifort -DMPI 编译错误:派生类型“mpi_status”用作实际参数。适用于英特尔 Fortran,但不适用于 GNU Fortran