下面的代码列出了日期,如果日期是该月的最后一天,那么对于数据集中的所有日期(不在日历上),它将日期标记为该月的最后一天。

data = data.frame(day  = seq(as.Date("2014-01-01"),as.Date("2016-05-10"),"day"), weekday = weekdays ( seq(as.Date("2014-01-01"),as.Date("2016-05-10"),"day")))
excludeDays <- c("Saturday", "Sunday")
data <- subset(data, !weekdays(data$day) %in% excludeDays) #exclude weekend
setDT(data)
data[, LastDayInMonth := day == max(day), by = list(year(day),month(day)  )]
head(data,100)

我还需要添加一个列,该列在该月的第三个星期五的数据中的每个星期五标记(真/假)。有什么想法吗?

例如2014年1月17日,2014年2月21日,...... 2014年5月16日等...是第3个星期五。

谢谢。

最佳答案

要涵盖当月中旬开始数据时的极端情况,您可以尝试以下操作:

occ <- 3L   # 3rd occurrence of selected weekday
data[, ThirdFridayInMonth := weekday == "Friday" &
       as.integer(day - lubridate::floor_date(day, "month")) %/% 7L + 1L == occ]

这也适用于该月的其他工作日,例如标记每个第一个星期一。

编辑:根据要求进行解释。

基本思想是,每个月的第一个星期五必须是每个月的前7天之一,第二个星期五必须是第8到14天之一,依此类推。因此,lubridate::floor_date(day, "month")计算day所在月份的第一天。现在,您建立差异,它是一个difftime对象,需要将其转换为integer。如果day恰好是一个月的第一天,则为0。现在,您使用整数除法%/%,它在该月的前7天返回0,在后7天返回1,依此类推,然后通过加1进行调整。

编辑2:改进的代码

在编写说明时,我意识到可以进一步改进代码。

我们可以直接使用一个月中的某天,从而避免了计算日期差以及随后转换为整数的麻烦:
data[, ThirdFridayInMonth := weekday == "Friday" &
       (mday(day) - 1) %/% 7L + 1L == occ]

在这里,我使用mday(data.table包的一部分)而不是as.integer(format(day, "%d"))

09-26 22:06