【问题标题】:Calculate the last n weekdays计算最后n个工作日
【发布时间】:2011-05-24 17:01:48
【问题描述】:

我在 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)

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

【问题讨论】:

  • 您可能会在这里找到答案:stackoverflow.com/questions/5046708/…
  • @Sacha Epskamp 我认为这涵盖了不同的领域。在这种情况下,我有一个开始日期,但结束日期是未知的。在上一个问题中,开始和结束都是已知的。
  • 如果您有开始日期和天数,那么您有结束日期,对吗?
  • @Sacha Epskamp 不,因为不知道您在寻找恰好 n 个工作日时会遇到多少个周末。
  • 啊,给定 n 个工作日而不是 n 天?

标签: datetime r


【解决方案1】:

矢量化代码在 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 几乎可以立即运行它。

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

【讨论】:

  • @感谢有关矢量化的提示。我离开了,我应该尽可能地矢量化,但是对于这个特殊的问题,我在用矢量构建它时遇到了麻烦,最终在循环中思考。
  • 已将其修复为 n = 0。1:n 很危险! seq_len 很高兴知道。
  • @Richie 你能详细说明一下吗?当您将“0”插入我的原始函数时,它只会输出今天的日期。 1:n 哪里有危险?可能发生的最坏情况是错误消息,对吧?并且感谢谁将序列更改为自动反转,我不知道您可以使用“-1 天”之类的字符串作为增量!
【解决方案2】:

我在 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)

【讨论】:

    猜你喜欢
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 2010-12-02
    • 1970-01-01
    • 1970-01-01
    • 2012-06-12
    • 2010-09-25
    相关资源
    最近更新 更多