2016-04-07 145 views
0

我正試圖使用​​包bizdays來計算兩個日期之間的營業日數。有很多帖子都提到這樣一個事實,即在兩個日期之間計算工作日是一個很好的選擇,但是在使用它的特定問題上不會發布帖子。我目前遇到了輸出問題。Bizdays函數返回不正確的值

我有日期範圍從幾秒到幾個月的數據,但在我的示例DF下面,我只會顯示小於一天的差異(這些是問題似乎出現的地方)。

這裏是我的DF:

Transition_Dates <- data.frame(Enter = as.POSIXct(c("2015-06-28 19:48:00", 
              "2015-06-14 04:05:00", 
              "2013-11-21 04:56:59", 
              "2016-01-16 11:18:00", 
              "2015-12-19 14:02:59")), 
         Exit = as.POSIXct(c("2015-06-28 19:48:59", 
              "2015-06-14 04:06:59", 
              "2013-11-21 10:24:00", 
              "2016-01-18 06:21:00", 
              "2015-12-19 14:11:00")), 
         Time_in_State = c(0.00, 0.00, 0.23, 1.79, 0.01)) 

正如你所看到的,是具有不刪除非營業日計算(下文好比較的bizdays輸出)第三列。

這是我bizdays日曆:

library(bizdays) 
library(lubridate) 
Non_Working_Calendar <- Calendar(holidays = as.Date(c("2013-07-04", "2013-09-02", "2013-10-14", "2013-11-11", "2013-11-21", "2013-11-22", as.character(seq(ymd("2013-12-24"), ymd("2014-01-01"), "days")), 
              "2014-01-20", "2014-02-17", "2014-05-26", "2014-07-04", "2014-09-01", "2014-10-13", "2014-11-11", "2014-11-27", "2014-11-28", as.character(seq(ymd("2014-12-24"), ymd("2015-01-01"), "days")), 
              "2015-01-19", "2015-02-16", "2015-05-25", "2015-07-03", "2015-09-07", "2015-10-12", "2015-11-11", "2015-11-26", "2015-11-27", as.character(seq(ymd("2015-12-24"), ymd("2016-01-01"), "days")), 
              "2016-01-18", "2016-02-15", "2016-05-30", "2016-07-04", "2016-09-05", "2016-10-10", "2016-11-11", "2016-11-24", "2016-11-25", as.character(seq(ymd("2016-12-24"), ymd("2017-01-01"), "days")), 
              "2017-01-16", "2017-02-20", "2017-05-29", "2017-07-04", "2017-09-04", "2017-10-09", "2017-11-10", "2017-11-23", "2017-11-24", as.character(seq(ymd("2016-12-24"), ymd("2017-01-01"), "days")))), start.date = as.Date("2010-01-01"), end.date = as.Date("2020-01-01"), weekdays = c("saturday", "sunday")) 
bizdays.options$set(default.calendar = Non_Working_Calendar) 

bizdays輸出添加到DF:

Transition_Dates$bdays <- bizdays(Transition_Dates$Enter, Transition_Dates$Exit) 
Transition_Dates 
       Enter    Exit Time_in_State bdays 
1 2015-06-28 19:48:00 2015-06-28 19:48:59   0.00 -1 
2 2015-06-14 04:05:00 2015-06-14 04:06:59   0.00 -1 
3 2013-11-21 04:56:59 2013-11-21 10:24:00   0.23 -1 
4 2016-01-16 11:18:00 2016-01-18 06:21:00   1.79 -1 
5 2015-12-19 14:02:59 2015-12-19 14:11:00   0.01 -1 

有沒有人碰到類似的問題還是我完全失去了一些東西?對於大多數觀察,bdays列正確地從Time_in_State列向上或向下舍入,但我還沒有弄清楚爲什麼它會給我一些這些。另外,有沒有辦法讓bizdays輸出帶小數(例如5.5,12.11)?我沒有看到手冊中的任何內容。非常感謝你提前。

回答

1

我是bizdays的父親。 這是一個BUG,我會努力,現在爲了得到你想要的,我建議下面的代碼。

Transition_Dates <- data.frame(Enter = as.POSIXct(c("2015-06-28 19:48:00", 
               "2015-06-14 04:05:00", 
               "2013-11-21 04:56:59", 
               "2016-01-16 11:18:00", 
               "2015-12-19 14:02:59")), 
          Exit = as.POSIXct(c("2015-06-28 19:48:59", 
               "2015-06-14 04:06:59", 
               "2013-11-21 10:24:00", 
               "2016-01-18 06:21:00", 
               "2015-12-19 14:11:00")), 
          Time_in_State = c(0.00, 0.00, 0.23, 1.79, 0.01)) 

bypass <- function(x, cal) x 

library(bizdays) 
library(lubridate) 
Non_Working_Calendar <- Calendar(holidays=as.Date(c("2013-07-04", "2013-09-02", "2013-10-14", "2013-11-11", "2013-11-21", "2013-11-22", as.character(seq(ymd("2013-12-24"), ymd("2014-01-01"), "days")), 
                "2014-01-20", "2014-02-17", "2014-05-26", "2014-07-04", "2014-09-01", "2014-10-13", "2014-11-11", "2014-11-27", "2014-11-28", as.character(seq(ymd("2014-12-24"), ymd("2015-01-01"), "days")), 
                "2015-01-19", "2015-02-16", "2015-05-25", "2015-07-03", "2015-09-07", "2015-10-12", "2015-11-11", "2015-11-26", "2015-11-27", as.character(seq(ymd("2015-12-24"), ymd("2016-01-01"), "days")), 
                "2016-01-18", "2016-02-15", "2016-05-30", "2016-07-04", "2016-09-05", "2016-10-10", "2016-11-11", "2016-11-24", "2016-11-25", as.character(seq(ymd("2016-12-24"), ymd("2017-01-01"), "days")), 
                "2017-01-16", "2017-02-20", "2017-05-29", "2017-07-04", "2017-09-04", "2017-10-09", "2017-11-10", "2017-11-23", "2017-11-24", as.character(seq(ymd("2016-12-24"), ymd("2017-01-01"), "days")))), 
           start.date=as.Date("2010-01-01"), 
           end.date = as.Date("2020-01-01"), 
           weekdays = c("saturday", "sunday"), 
           adjust.from=bypass, 
           adjust.to=bypass) 

bizdays.options$set(default.calendar = Non_Working_Calendar) 

與此代碼我

> bizdays(Transition_Dates$Enter, Transition_Dates$Exit) 
[1] 0 0 0 0 0 

看來,問題的原因bizdays默認設置(adjust.from和adjust.to)擬複製Excel的NETWORKDAYS行爲。一旦fromto參數是非工作日,日期調整會導致您指出的奇怪結果。

> is.bizday(Transition_Dates$Enter) 
[1] FALSE FALSE FALSE FALSE FALSE 
> is.bizday(Transition_Dates$Exit) 
[1] FALSE FALSE FALSE FALSE FALSE 

功能bypass禁用調整,現在我必須找出一個乾淨的方式納入該功能在bizdays

+0

謝謝你的深思熟慮的答覆。我還有一些其他日期的問題。使用上面的日曆:'bizdays(「2014-10-10 11:33:00」,「2014-10-16 10:03:00」)'返回3個工作日,但它應該四捨五入(星期五11:上午30點至週四上午10點03分)。如果我運行'bizseq(「2014-10-10 11:33:00」,「2014-10-16 10:03:00」)',它會返回一個4天的向量。你現在是否推薦作爲解決方法?我可以將它與日期的向量合併到一起嗎?我會嘗試嘗試。 – Tunn

+0

現在我建議加1到'bizdays'返回。 'bizdays'兩個日期之間的差異,所以如果你打電話給'bizdays(「2014-10-10 11:33:00」,「2014-10-11 11:33:00」)'返回1而不是2,但是如果你調用'bizseq(「2014-10-10 11:33:00」,「2014-10-11 11:33:00」)',它會返回一個包含2個日期的序列。 'bizdays'是爲財務目的而設計的,我會考慮採用新的方法使其更適合其他用途。 –

+0

哎呦我在上面的評論中錯過了哥倫布日。你的第一個答案很好。再次感謝。 – Tunn