【发布时间】:2020-06-21 17:32:46
【问题描述】:
在 R 中,如何生成指定日期范围内所有第二个到最后一个星期三的日期列表?我尝试了一些方法,但在五个星期三的几个月里得到了不一致的结果。
【问题讨论】:
-
你能展示一下你尝试过的东西吗?
在 R 中,如何生成指定日期范围内所有第二个到最后一个星期三的日期列表?我尝试了一些方法,但在五个星期三的几个月里得到了不一致的结果。
【问题讨论】:
要生成规则的日期序列,您可以将seq 与参数from 和to 的日期一起使用。请参阅seq.Date documentation 了解更多选项。
创建一个包含日期、月份和工作日的数据框。然后在aggregate的帮助下获取每个月的倒数第二个星期三。
day_sequence = seq(as.Date("2020/1/1"), as.Date("2020/12/31"), "day")
df = data.frame(day = day_sequence,
month = months(day_sequence),
weekday = weekdays(day_sequence))
#Filter only wednesdays
df = df[df$weekday == "Wednesday",]
result = aggregate(day ~ month, df, function(x){head(tail(x,2),1)})
tail(x,2) 将返回最后两行,然后head(.., 1) 将返回最后两行中的第一行。
结果:
month day
1 April 2020-04-22
2 August 2020-08-19
3 December 2020-12-23
4 February 2020-02-19
5 January 2020-01-22
6 July 2020-07-22
7 June 2020-06-17
8 March 2020-03-18
9 May 2020-05-20
10 November 2020-11-18
11 October 2020-10-21
12 September 2020-09-23
【讨论】:
可能有更简单的方法可以做到这一点,但下面的函数可以满足问题的要求。它返回一个命名的天数,这样
from 和to 之间。day,其中 1 是星期一。n 到本月最后一天。n 指的是从月底算起的第 n 个。
whichWeekday <- function(from, to, day, n, format = "%Y-%m-%d"){
from <- as.Date(from, format = format)
to <- as.Date(to, format = format)
day <- as.character(day)
d <- seq(from, to, by = "days")
m <- format(d, "%Y-%m")
f <- c(TRUE, m[-1] != m[-length(m)])
f <- cumsum(f)
wed <- tapply(d, f, function(x){
i <- which(format(x, "%u") == day)
x[tail(i, n)[1]]
})
y <- as.Date(wed, origin = "1970-01-01")
setNames(y, format(y, "%Y-%m"))
}
whichWeekday("2019-01-01", "2020-03-31", 4, 2)
# 2019-01 2019-02 2019-03 2019-04 2019-05
#"2019-01-23" "2019-02-20" "2019-03-20" "2019-04-17" "2019-05-22"
# 2019-06 2019-07 2019-08 2019-09 2019-10
#"2019-06-19" "2019-07-24" "2019-08-21" "2019-09-18" "2019-10-23"
# 2019-11 2019-12 2020-01 2020-02 2020-03
#"2019-11-20" "2019-12-18" "2020-01-22" "2020-02-19" "2020-03-18"
【讨论】: