按中午而不是午夜对日期进行分组
Group dates by midday instead of midnight
我有一个数据集,有些日子每天都有多个集合。我想创建一个可用于捆绑 'days' 的字段,但我想在中午而不是午夜拆分。不幸的是,当我执行 "midday split" 时,日期值是整数而不是日期值。
一些示例代码:
library(tidyverse)
x <- as.POSIXct(Sys.time())
y <- as.tibble(x)
#midnights comes through correctly as a date
y %>%
mutate(midnights=as.Date(value))
#middays comes through as an integer instead of a date
y %>%
mutate(middays=ifelse(as.numeric(format(value,"%H")) >= 12,
as.Date(value),
as.Date(value)-1))
我应该怎么做?
您可以使用的一个技巧是通过调用 as.numeric(x)
将 x
转换为纪元以来的秒数。然后要获得自纪元以来的天数,它只是 as.numeric(x) %/% 86400
(因为一天有 86400 秒)。因此,您可以使用此值按天拆分(即在午夜拆分)。如果你想 'shift' 这 12 小时,你需要做的就是将 x
移动 12 小时,即 运行 as.numeric(dates + 12 * 3600) %/% 86400
。
例如
dates <- structure(c(1505771227.18457, 1505814427.18457, 1505857627.18457,
1505900827.18457, 1505944027.18457, 1505987227.18457,
1506030427.18457), class = c("POSIXct", "POSIXt"))
#[1] "2017-09-18 22:47:07 BST" "2017-09-19 10:47:07 BST" "2017-09-19 22:47:07 BST" "2017-09-20 10:47:07 BST"
#[5] "2017-09-20 22:47:07 BST" "2017-09-21 10:47:07 BST" "2017-09-21 22:47:07 BST"
as.numeric(dates) %/% 86400 # use this to group by day (split at midnight)
#[1] 17427 17428 17428 17429 17429 17430 17430
as.numeric(dates + 12 * 3600) %/% 86400 # use this to split at noon
#[1] 17428 17428 17429 17429 17430 17430 17431
或者,如果你想使用 lubridate
,你可以玩同样的把戏,即计算 lubridate::floor_date(dates + lubridate::hours(12), 'day')
将日期移动 12 小时,然后找到日期,并以此为基础进行分组。
ifelse
returns 一个数字,因为它去除了 class 信息。只需将整个内容包装在另一个 as.Date()
:
y %>%
mutate(middays=as.Date(ifelse(as.numeric(format(value,"%H")) >= 12,
as.Date(value),
as.Date(value)-1),origin="1970-01-01"))
或使用 dplyr
中的 if_else
来解决
y %>%
mutate(middays=if_else(as.numeric(format(value,"%H")) >= 12,
as.Date(value),
as.Date(value)-1))
## A tibble: 1 × 2
# value middays
# <dttm> <date>
#1 2017-09-21 08:28:05 2017-09-19
我有一个数据集,有些日子每天都有多个集合。我想创建一个可用于捆绑 'days' 的字段,但我想在中午而不是午夜拆分。不幸的是,当我执行 "midday split" 时,日期值是整数而不是日期值。
一些示例代码:
library(tidyverse)
x <- as.POSIXct(Sys.time())
y <- as.tibble(x)
#midnights comes through correctly as a date
y %>%
mutate(midnights=as.Date(value))
#middays comes through as an integer instead of a date
y %>%
mutate(middays=ifelse(as.numeric(format(value,"%H")) >= 12,
as.Date(value),
as.Date(value)-1))
我应该怎么做?
您可以使用的一个技巧是通过调用 as.numeric(x)
将 x
转换为纪元以来的秒数。然后要获得自纪元以来的天数,它只是 as.numeric(x) %/% 86400
(因为一天有 86400 秒)。因此,您可以使用此值按天拆分(即在午夜拆分)。如果你想 'shift' 这 12 小时,你需要做的就是将 x
移动 12 小时,即 运行 as.numeric(dates + 12 * 3600) %/% 86400
。
例如
dates <- structure(c(1505771227.18457, 1505814427.18457, 1505857627.18457,
1505900827.18457, 1505944027.18457, 1505987227.18457,
1506030427.18457), class = c("POSIXct", "POSIXt"))
#[1] "2017-09-18 22:47:07 BST" "2017-09-19 10:47:07 BST" "2017-09-19 22:47:07 BST" "2017-09-20 10:47:07 BST"
#[5] "2017-09-20 22:47:07 BST" "2017-09-21 10:47:07 BST" "2017-09-21 22:47:07 BST"
as.numeric(dates) %/% 86400 # use this to group by day (split at midnight)
#[1] 17427 17428 17428 17429 17429 17430 17430
as.numeric(dates + 12 * 3600) %/% 86400 # use this to split at noon
#[1] 17428 17428 17429 17429 17430 17430 17431
或者,如果你想使用 lubridate
,你可以玩同样的把戏,即计算 lubridate::floor_date(dates + lubridate::hours(12), 'day')
将日期移动 12 小时,然后找到日期,并以此为基础进行分组。
ifelse
returns 一个数字,因为它去除了 class 信息。只需将整个内容包装在另一个 as.Date()
:
y %>%
mutate(middays=as.Date(ifelse(as.numeric(format(value,"%H")) >= 12,
as.Date(value),
as.Date(value)-1),origin="1970-01-01"))
或使用 dplyr
中的 if_else
来解决
y %>%
mutate(middays=if_else(as.numeric(format(value,"%H")) >= 12,
as.Date(value),
as.Date(value)-1))
## A tibble: 1 × 2
# value middays
# <dttm> <date>
#1 2017-09-21 08:28:05 2017-09-19