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