2011-05-24 134 views
3

我在R中有一個函數,給定n天,返回最近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) 

排除假期也是一個不錯的功能。

+0

您可能會發現在這裏的答案:http://stackoverflow.com/questions/5046708/calculate-the-number-of-weekdays-between-2-dates-in-r – 2011-05-24 17:14:47

+0

@Sacha Epskamp我認爲這涵蓋了不同的理由。在這種情況下,我有一個開始日期,但結束日期是未知的。在前一個問題中,開始和結束都是已知的。 – Zach 2011-05-24 17:18:05

+0

如果你有一個開始日期和天數你有一個結束的日子嗎? – 2011-05-24 17:42:35

回答

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

@感謝關於矢量化的小技巧。我不知道我應該儘可能地進行矢量化,但是對於這個特殊的問題,我無法用矢量對它進行構圖,並最終陷入循環思考。 – Zach 2011-05-24 18:13:23

+1

固定n = 0。'1:n'很危險! 'seq_len'很好理解。 – 2011-05-25 09:53:14

+0

@ Richie你能詳細說一下嗎?當你將我的原始功能插入「0」時,它只輸出今天的日期。哪裏可能1:n是危險的?可能發生的最糟糕的是一個錯誤信息,對吧?並感謝誰改變序列自動反轉,我不知道你可以使用像「-1天」的字符串作爲增量! – Rguy 2011-05-25 16:22:32

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)