数据:
DB <- data.frame(orderID = c(1,2,3,4,5,6,7,8,9,10),
orderDate = c("1.1.14","8.4.14","17.4.14","29.3.12","29.7.14",
"2.8.14","21.9.14","4.10.14","30.11.14","9.4.06"),
预期结果[希望我算出正确的天数]:
orderDuringPresentShoppingWeekseasternpast =c("No", "Yes", "Yes", "Yes", "No", "No", "No", "No", "No", "Yes")
大家好,
我想我现在遇到的问题是迄今为止我遇到的最复杂/最困难的问题:但也许某人比我更聪明,可以在一分钟内解决问题:)
我在公共假期东部有不同的时间跨度和日期。但不仅是今年 - 也是过去10年。因为每个人都知道东方每年的日期不同:所以我不能在每年的特定日期修复它。
1.如果订单发生在复活节或过去几年复活节星期日前14天内,我想发出“是”,如果不是,则发出“否”。在过去的10年里,我已经制作了一些时间片:
spanEasternpast
[1] 2015-03-22 UTC--2015-04-05 UTC 2014-04-06 UTC--2014-04-20 UTC 2013-03-17 UTC--2013-03-31 UTC 2012-03-25 UTC--2012-04-08 UTC
[5] 2011-04-10 UTC--2011-04-24 UTC 2010-03-21 UTC--2010-04-04 UTC 2009-03-29 UTC--2009-04-12 UTC 2008-03-09 UTC--2008-03-23 UTC
[9] 2007-03-25 UTC--2007-04-08 UTC 2006-04-02 UTC--2006-04-16 UTC 2005-03-13 UTC--2005-03-27 UTC
已经尝试过这样,但它不起作用:
Easternpast <- Easter(currentYear:(currentYear -10))
spanEasternpast <- new_interval (ymd(Easternpast-ddays(14)), ymd(Easternpast))
spanEasternpast
[1] 2015-03-22 UTC--2015-04-05 UTC 2014-04-06 UTC--2014-04-20 UTC 2013-03-17 UTC--2013-03-31 UTC 2012-03-25 UTC--2012-04-08 UTC
[5] 2011-04-10 UTC--2011-04-24 UTC 2010-03-21 UTC--2010-04-04 UTC 2009-03-29 UTC--2009-04-12 UTC 2008-03-09 UTC--2008-03-23 UTC
[9] 2007-03-25 UTC--2007-04-08 UTC 2006-04-02 UTC--2006-04-16 UTC 2005-03-13 UTC--2005-03-27 UTC (so this part with the right span is working)
DB$orderDuringPresentShoppingWeekseasternpast <- ifelse(DB$orderDate%within%spanEasternpast == TRUE, "Yes", "No")
希望你能告诉我什么是错的,或者告诉我另一个解决问题的可能性......
干杯和THX!
答案 0 :(得分:2)
这是使用foverlaps
包中的data.table
的另一种可能性。
library(timeDate)
library(data.table)
# first, some dummy data
# create easter interval for 2000-2002
easter <- data.table(start = as.Date(Easter(2000:2002, -14)),
end = as.Date(Easter(2000:2002)))
# start end
# 1: 2000-04-09 2000-04-23
# 2: 2001-04-01 2001-04-15
# 3: 2002-03-17 2002-03-31
# set key for overlap join
setkey(easter)
# create some order dates
# 3 dates before (>14 days) easter holiday
# 3 dates during holiday
set.seed(1)
order <- data.table(order_date = as.Date(Easter(2000:2002)) + sample(c(-17:-15, -2:0)))
# create an 'end date' for the order_date
order[, order_date2 := order_date]
# overlap join
# use nomatch = NA (default) to keep track of dates within and outside holiday period
# convert NA to "No" and non-NA to "Yes" using vector indexing
# remove columns (I deliberately kept start and end just to check the join)
order <- foverlaps(x = order, y = easter, by.x = names(order),
type = "within", mult = "all", nomatch = NA)[
, easter_order := c("Yes", "No")[as.integer(is.na(end)) + 1]][
, order_date2 := NULL]
order
# start end order_date easter_order
# 1: 2000-04-09 2000-04-23 2000-04-23 Yes
# 2: 2001-04-01 2001-04-15 2001-04-13 Yes
# 3: <NA> <NA> 2002-03-16 No
# 4: <NA> <NA> 2000-04-06 No
# 5: 2001-04-01 2001-04-15 2001-04-14 Yes
# 6: <NA> <NA> 2002-03-15 No
请参阅@Arun的this nice answer,其中foverlaps
的描述更为彻底。
更新以下来自OP的评论
与复活节和圣诞假期相匹配日期
# create intervals for easter and christmas holidays 2000-2002
holiday <- data.table(start = c(as.Date(Easter(2000:2002, -14)),
as.Date(ChristmasDay(year = 2000:2002)) - 14),
end = c(as.Date(Easter(2000:2002)),
as.Date(ChristmasDay(year = 2000:2002))))
# holiday
# set key for overlap join
setkey(holiday)
# create some order dates
# 3 dates before (>14 days) and 3 during easter holiday
# 3 dates before (>14 days) and 3 during christmas holiday
set.seed(1)
order <- data.table(order_date = c(as.Date(Easter(2000:2002)) + sample(c(-17:-15, -2:0)),
as.Date(ChristmasDay(2000:2002)) + sample(c(-17:-15, -2:0))))
# create a 'end' date for the order
order[, order_date2 := order_date]
# overlap join
# use nomatch = NA (default) to keep track of dates within and outside holiday period
# convert NA to "No" and non-NA to "Yes"
# remove columns (I deliberately kept start and end just to check the join)
order <- foverlaps(x = order, y = holiday, by.x = names(order),
type = "within", mult = "all", nomatch = NA)[
, holiday_order := c("Yes", "No")[as.integer(is.na(end)) + 1]][
, order_date2 := NULL]
order
# start end order_date holiday_order
# 1: <NA> <NA> 2000-04-07 No
# 2: 2001-04-01 2001-04-15 2001-04-15 Yes
# 3: <NA> <NA> 2002-03-16 No
# 4: 2000-04-09 2000-04-23 2000-04-21 Yes
# 5: <NA> <NA> 2001-03-29 No
# 6: 2002-03-17 2002-03-31 2002-03-30 Yes
# 7: 2000-12-11 2000-12-25 2000-12-25 Yes
# 8: 2001-12-11 2001-12-25 2001-12-23 Yes
# 9: <NA> <NA> 2002-12-10 No
# 10: <NA> <NA> 2000-12-08 No
# 11: 2001-12-11 2001-12-25 2001-12-24 Yes
# 12: <NA> <NA> 2002-12-09 No
答案 1 :(得分:0)
library(lubridate)
library(timeDate) # For function Easter() above
DB$orderDuringPresentShoppingWeekeasternpast <- apply(sapply(dmy(DB$orderDate), function(x) x %within% spanEasternpast), 2, any)
为什么这样做......考虑两个步骤:
sapply(dmy(DB$orderDate), function(x) x %within% spanEasternpast)
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [2,] FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [3,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
# [5,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [6,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [7,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [8,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [9,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [10,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE
# [11,] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
然后按列检查是否有任何内容TRUE
通过apply(x, margin=2, ...)