现在我有了一个新问题。我需要计算两个日期之间的时间跨度。我的问题是:必须排除周末,时间跨度可以减去或加上。 例如:
Planed delivery Real delivery
2017-11-28 2018-11-17
2016-05-10 2016-09-22
2016-06-08 2016-11-07
2016-07-08 2016-06-07
等等。 我有以下代码:
getDuration <- function(date_scheduled, date_received,fmt="%Y-%m-%d") {
myDays <- ifelse(date_received > date_scheduled,
seq.Date(to = as.Date(date_received, format=fmt),
from = as.Date(date_scheduled, format =fmt),
by = 1),
seq.Date(to = as.Date(date_scheduled, format=fmt),
from = as.Date(date_received, format =fmt),
by = 1))
length(myDays[!is.weekend(myDays)])
}
当我使用命令时:
getDataPart(prep_DPM_All_new$Goods_received_date, prep_DPM_All_new$Schedule_Line_Delivery)
我收到以下错误:
Error in seq.Date(to = as.Date(date_received, format = fmt), from = as.Date(date_scheduled, :'from' must be of length 1
起初我认为日期列没有以正确的方式格式化,但我觉得它看起来不错。
str(prep_DPM_All_new$Goods_received_date)
POSIXct[1:33078], format: "2016-03-24"
str(prep_DPM_All_new$Schedule_Line_Delivery)
POSIXct[1:33078], format: "2016-03-29"
任何人都可以帮助我并解释,为什么我会收到错误? 如果没有if else语句,我会收到错误,即“错误登录”。
输出应该像这样:
Row 1: 254
Row 2: 109
Row 3: 98
Row 4: -24
我试图通过对类似问题使用一些解决方案来解决问题,但这些问题只有积极的价值。我认为负值是主要问题。
答案 0 :(得分:0)
seq.Date()
有点棘手,原因有两个:
from
,to
和by
参数必须对应,即如果to
低于from
则必须by
负。这是一个解决方案,按行号分组以克服问题1.并使用sign()
和range()
函数来克服问题2.此外,chron
包用于OP已采用is.weekend()
函数。
library(data.table)
library(chron)
# coerce to data.table and chron
DF <- setDT(DF)[, lapply(.SD, chron, format = "y-m-d")]
DF[, rn := .I][, {
s <- sign(Actual_delivery - Planned_delivery)
r <- range(Actual_delivery, Planned_delivery)
.(diff.working.days = s * sum(!is.weekend(seq(r[1], r[2]))))
}, by = rn]
rn diff.working.days 1: 1 254 2: 2 98 3: 3 109 4: 4 -24
library(data.table)
DF <- fread(
"Planned_delivery Actual_delivery
2017-11-28 2018-11-17
2016-05-10 2016-09-22
2016-06-08 2016-11-07
2016-07-08 2016-06-07"
)