计算最后n个工作日

时间:2011-05-24 17:01:48

标签: datetime r

我在R中有一个函数,给定n天,返回最后n个工作日的列表。我的解决方案运行良好,但感觉不够优雅,我想知道是否有任何简单的方法来改进它。

WeekdayList <- function(n) {
    Today <- as.Date(Sys.time())
    days <- c(Today)
    i <- 1
    while (length(days) < n) {
        NewDay <- as.Date(Today-i)
        if (!weekdays(NewDay) %in% c("Saturday", "Sunday")) {
            days <- c(days,NewDay)
        }
        i <- i+1
    }
    days
}

WeekdayList(30)
WeekdayList(2)

排除假期也是一个不错的功能。

2 个答案:

答案 0 :(得分:6)

在R中,矢量化代码是必不可少的。以下是示例:

WeekdayList2 <- function(n) {
  Today <- as.Date(Sys.time())
  dayz <- seq(Today, Today - 2 * n, "-1 days")
  dayz <- dayz[!(weekdays(dayz) %in% c("Saturday", "Sunday"))]
  dayz <- dayz[seq_len(n)]
  return(dayz)
}
identical(WeekdayList2(1000), WeekdayList(1000))
system.time(WeekdayList2(10000))
system.time(WeekdayList(10000))
[1] TRUE
   user  system elapsed 
      0       0       0 
   user  system elapsed 
   4.90    0.00    4.91 

正如你所看到的,即使我的函数创建了两次几乎两倍大小的向量(然后删除了周末),它比使用“for”循环要快得多。我的计算机甚至无法使用n = 100000来运行你的功能(不管你多少天都关心它),但是WeekdayList2几乎立即运行它。

由于假期与您所处的位置相关,您可能需要手动上传日期列表,并添加其他条件以从数据中过滤掉这些日期。

答案 1 :(得分:4)

我在Rguy的代码中添加了假期计算。

WeekdayList3 <- function(n) {
    library(timeDate)
    Today <- as.Date(Sys.time())
    dayz <- rev(seq(Today - 2 * n, Today, "days"))
    years <- as.numeric(unique(format(dayz,'%Y')))
    holidays <- as.Date(holidayNYSE(years))
    dayz <- dayz[!(weekdays(dayz) %in% c("Saturday", "Sunday"))]
    dayz <- dayz[!(dayz %in% holidays)]
    dayz <- dayz[1 : n]
    return(dayz)
}

WeekdayList3(100)