R利用位置切割日期,而不是实际日期

时间:2018-05-16 19:38:49

标签: r

我知道我可以通过以下方式缩短日期:

library(tidyverse)
dates <- parse_date(c("2018-02-01", "2018-02-15", "2018-02-20", "2018-03-20"))
cut.dates <- cut(dates, breaks = parse_date(c("2018-01-01", "2018-02-10", "2018-12-31")))
table(cut.dates)

但是,我如何根据每个日期来缩短日期&#39;在列表中的位置,而不是实际日期?我想用以下内容替换上面显示的第三行:

cut.dates <- cut(dates, c(0, 2, nrow(dates))

0将是开始削减的初始位置

2将在列表 1st 2nd 条目之间剪切

nrow(dates)将是最终裁员 - 我名单中的最后一个位置

1 个答案:

答案 0 :(得分:1)

我认为您想要的是根据数据动态确定切割日期,而不是手动指定它们。

我会生成更多日期,因为当它们都在同一季度时,很难按季度测试四个日期。

set.seed(2)
( dates <- sort(Sys.Date() + sample(365, size=20)) )
#  [1] "2018-06-12" "2018-07-03" "2018-07-17" "2018-07-20" "2018-07-24"
#  [6] "2018-08-04" "2018-08-10" "2018-10-07" "2018-10-19" "2018-11-01"
# [11] "2018-11-29" "2018-11-30" "2018-12-12" "2019-01-28" "2019-02-10"
# [16] "2019-03-12" "2019-04-22" "2019-04-23" "2019-05-10" "2019-05-13"

提出开始和结束日期:

( start <- lubridate::floor_date(min(dates), unit="quarter") )
# [1] "2018-04-01"
( end <- lubridate::ceiling_date(max(dates), unit="quarter") )
# [1] "2019-07-01"

我们对宿舍感兴趣:

( brks <- seq(start, end, by="quarter") )
# [1] "2018-04-01" "2018-07-01" "2018-10-01" "2019-01-01" "2019-04-01"
# [6] "2019-07-01"
cut(dates, breaks=brks)
#  [1] 2018-04-01 2018-07-01 2018-07-01 2018-07-01 2018-07-01 2018-07-01
#  [7] 2018-07-01 2018-10-01 2018-10-01 2018-10-01 2018-10-01 2018-10-01
# [13] 2018-10-01 2019-01-01 2019-01-01 2019-01-01 2019-04-01 2019-04-01
# [19] 2019-04-01 2019-04-01
# Levels: 2018-04-01 2018-07-01 2018-10-01 2019-01-01 2019-04-01

如果您不需要在日历季度上对齐 - 只需将数据分成三个月 - 那么您可以这样做:

( start_m <- lubridate::floor_date(min(dates), unit="month") )
# [1] "2018-06-01"
( end_m <- lubridate::ceiling_date(max(dates) + 93L, unit="month") )
# [1] "2019-09-01"
( brks_m <- seq(start_m, end_m, by="quarter") )
# [1] "2018-06-01" "2018-09-01" "2018-12-01" "2019-03-01" "2019-06-01"
# [6] "2019-09-01"

(神奇的93L是为了确保我们在当月之外至少有另外一个季度,这是必要的,因为ceiling(month)可能不足以捕获上一个自定义季度的三个月。太多的休息并不是一件坏事,额外的东西将会被闲置。)