在一系列日期中确定第3个星期五

时间:2016-06-07 20:14:33

标签: r date data.table lubridate

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

openssl enc  -aes-256-cbc -base64 -d -A -p -K M�>VO���[ދ��  �7^6 -iv ⬧⬧⬧⬧⬧⬧⬧ -in /usr/www/vault/new/d71fd708181573c5f92c8f500ddcb399/787 -out /tmp/decrypted57574484b684c

我还需要在本月第3个星期五的数据中添加一个标记(TRUE / FALSE)的列。有什么想法吗?

例如2014-01-17,2014-02-21,...... 2014-05-16等......是第三个星期五。

谢谢。

4 个答案:

答案 0 :(得分:4)

data[, numWeek := 1:.N, by = .(year(day), month(day), weekday)]

data[numWeek == 3 & weekday == "Friday"]

或者添加为列:

data[, is3rdFriday := numWeek == 3 & weekday == "Friday"]

如果您在日历中寻找第3个星期五,而不是数据中的第3个星期五,那么您可以更简单地进行操作:

data[, is3rdFriday := (mday(day) - 1) %/% 7 + 1 == 3 & weekday == "Friday"]

答案 1 :(得分:2)

试试这个 - 没有data.table:

library(lubridate)
library(dplyr)
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")))
data$year_month <- floor_date(data$day, unit = 'month')
fri3 <- filter(data, weekday == 'Friday') %>%
  group_by(year_month) %>% slice(3)

data$Third_Fri <- data$day %in% fri3$day

您可以删除year_month

答案 2 :(得分:2)

另一种方法:

data[, is3Friday:=cumsum(weekday=="Friday"), by=substring(day, 1, 7)]
data[, is3Friday:=ifelse(weekday=="Friday" & is3Friday==3, TRUE, FALSE)]

data[is3Friday==TRUE]
           day weekday LastDayInMonth is3Friday
 1: 2014-01-17  Friday          FALSE      TRUE
 2: 2014-02-21  Friday          FALSE      TRUE
 3: 2014-03-21  Friday          FALSE      TRUE
 4: 2014-04-18  Friday          FALSE      TRUE
 5: 2014-05-16  Friday          FALSE      TRUE
 6: 2014-06-20  Friday          FALSE      TRUE

答案 3 :(得分:2)

要在月中开始数据时覆盖角落情况,您可以尝试:

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

这也适用于本月的其他工作日,例如,每隔一个星期一举行一次。

编辑:按要求说明。

基本思路是每个月的第1个星期五必须是每个月的前7天之一,第2个星期五必须是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]

在此,我使用mdaydata.table包的一部分)代替as.integer(format(day, "%d"))