获取每月的第二个和第四个星期六

时间:2019-03-19 10:16:08

标签: r date

d = seq(as.Date("2018-01-01"),Sys.Date(),by='day')
saturdayList = d[weekdays(d)=='Saturday']

如何从上面的星期六日期列表中获取一个月的第二个和第四个星期六?

3 个答案:

答案 0 :(得分:3)

您可以将向量拆分为一个列表,然后每月提取第二个和第四个元素:

lapply(split(saturdayList, format(saturdayList, "%Y-%m")), `[`, c(2, 4))
# $`2018-01`
# [1] "2018-01-13" "2018-01-27"
# 
# $`2018-02`
# [1] "2018-02-10" "2018-02-24"
# 
# $`2018-03`
# [1] "2018-03-10" "2018-03-24"
# 
# $`2018-04`
# [1] "2018-04-14" "2018-04-28"
# ...

没有NA:

lapply(split(saturdayList, format(saturdayList, "%Y-%m")), function(x)
       na.omit(x[c(2,4)]))

假设:

  • 输入按日期排序(如示例中所示)
  • 输入是一个完整的序列,没有丢失星期六(如示例中所示)

答案 1 :(得分:1)

data.table解决方案

解决方案(在样本数据上)比docendo discimus的“ lapply-solution”要慢。但是,它非常灵活,并且在较大的数据集上也将表现出色。

library(data.table)
#build a data.table out of the vector
DT <- data.table(date = d)
#group by month, select the second and 4 row where wday == 7 (i.e. Saturday)
DT[ DT[ , .I[wday(date) == 7][c(2,4)], by = .(month(date)) ]$V1 ]

输出

# date
# 1: 2018-01-13
# 2: 2018-01-27
# 3: 2018-02-10
# 4: 2018-02-24
# 5: 2018-03-10
# 6: 2018-03-24
# 7: 2018-04-14
# 8: 2018-04-28
# 9: 2018-05-12
# 10: 2018-05-26
# 11: 2018-06-09
# 12: 2018-06-23
# 13: 2018-07-14
# 14: 2018-07-28
# 15: 2018-08-11
# 16: 2018-08-25
# 17: 2018-09-08
# 18: 2018-09-22
# 19: 2018-10-13
# 20: 2018-10-27
# 21: 2018-11-10
# 22: 2018-11-24
# 23: 2018-12-08
# 24: 2018-12-22
# date

答案 2 :(得分:1)

1),尽管我们可以将d替换为d,但是它直接从saturdayList计算了第二个星期六和第四个星期六的向量,并且仍然可以使用。

根据zoo quickref vignette中的nextsat定义nextfri,它为输入向量的每个元素提供输入日期或之后的下一个星期六。然后为d的每个元素找到每月的第一天,应用nextsat给出每月的第一个星期六,并加上7以得到每月的第二个星期六。加14得到第四个星期六,并分类为一个向量。不使用任何软件包。

nextsat <- function(x) 7 * ceiling(as.numeric(x-6+4) / 7) + 
  as.Date(6-4, origin = "1970-01-01")

sat2 <- unique(nextsat(as.Date(cut(d, "month")))) + 7
sort(c(sat2, sat2 + 14))

给予:

 [1] "2018-01-13" "2018-01-20" "2018-02-10" "2018-02-17" "2018-03-10"
 [6] "2018-03-17" "2018-04-14" "2018-04-21" "2018-05-12" "2018-05-19"
[11] "2018-06-09" "2018-06-16" "2018-07-14" "2018-07-21" "2018-08-11"
[16] "2018-08-18" "2018-09-08" "2018-09-15" "2018-10-13" "2018-10-20"
[21] "2018-11-10" "2018-11-17" "2018-12-08" "2018-12-15" "2019-01-12"
[26] "2019-01-19" "2019-02-09" "2019-02-16" "2019-03-09" "2019-03-16"

2)这将计算一个向量satno,该向量给出一个月内每个星期六的数目,然后从第二个和第四个开始。这也不使用任何包。

satno <- ave(as.numeric(saturdayList), cut(saturdayList, "month"), FUN = seq_along)
saturdayList[satno %in% c(2, 4)]