【问题标题】:Bizdays function returning incorrect valuesBizdays 函数返回不正确的值
【发布时间】:2016-04-07 23:54:59
【问题描述】:

我正在尝试使用包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 列向上或向下舍入,但我还没有弄清楚为什么它会给我其中一些-1。另外,有没有办法让bizdays 输出带小数(例如,5.5、12.11)?我没有在手册中看到任何内容。非常感谢您。

【问题讨论】:

    标签: r date datetime


    【解决方案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

    【讨论】:

    • 感谢您的周到回复。我仍然对其他一些日期有疑问。使用上面的日历:bizdays("2014-10-10 11:33:00", "2014-10-16 10:03:00") 返回 3 个工作日,但应四舍五入为 4(周五上午 11:30 至周四上午 10:03)。如果我运行bizseq("2014-10-10 11:33:00", "2014-10-16 10:03:00"),它会返回一个 4 天的向量。您现在建议将其作为解决方法吗?我可以将它与日期向量结合起来吗?我会尝试尝试。
    • 现在我建议将 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 是为财务目的而设计的,我会想出新的方法让它更适合其他用途。
    • 哎呀,我在上面的评论中错过了哥伦布日。您的第一个答案效果很好。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-06
    相关资源
    最近更新 更多