我的目标是从数据框中进行startdate
观察,将其与日历进行比较,如果日期不是营业日期(假日或周末),请将其推回,直到它变为有效工作日。我将对enddate
做同样的事情,但要推进它。
例如,这就是我的数据:
tickers startDate endDate
1 GOOGL 2016-01-31 2016-02-02
2 GOOGL 2015-10-21 2015-10-23
3 GOOGL 2015-07-15 2015-07-17
4 GOOGL 2015-04-22 2015-04-24
5 GOOGL 2015-01-28 2015-01-30
6 GOOGL 2014-10-15 2014-10-17
我的日历信息:
Date Weekday Business Event
1 2001-01-01 Monday FALSE New Years Day
2 2001-01-02 Tuesday TRUE <NA>
3 2001-01-03 Wednesday TRUE <NA>
4 2001-01-04 Thursday TRUE <NA>
5 2001-01-05 Friday TRUE <NA>
6 2001-01-06 Saturday FALSE <NA>
所以我通过以下方式实现这一点,使用dplyr:
for(i in 1:10){
stocks1 <- stocks1 %>%
mutate(startDate = as.Date(ifelse(startDate %in% dates[dates$Business==F,]$Date, startDate - 1, startDate))) %>%
mutate(endDate = as.Date(ifelse(endDate %in% dates[dates$Business==F,]$Date, endDate + 1, endDate)))
}
我想必须有更优雅的方式来做到这一点......任何想法?理想情况下使用dplyr
,因为我正在尝试掌握此包:)
谢谢!
答案 0 :(得分:0)
chron
包有一些名为is.weekend
和is.holiday
的令人愉快的功能,在这里非常有帮助。至于优化,这实际上似乎是罕见的情况,其中while
循环实际上似乎在R中是值得的。除非你想以编程方式进行,否则你仍然需要两个。
一个警告:is.holiday
需要一个假期列表(默认情况下它使用1992年的六个美国假期)。我们可以使用第二个data.frame中的日期Business == FALSE
,其中可能包括周末,但没关系。实际上,如果您的周末数据已经很好,通过这种方法,您可以完全跳过is.weekend
。在这种情况下,两者的日期不对齐,因此它并不十分有用。无论如何,该方法将适用于正确的数据。总之,df1
和df2
分别是您的第一个和第二个data.frames:
library(chron)
# make a vector of holidays in chron's dates form for is.holiday
holidays <- chron(dates. = as.character(df2$Date), format = 'y-m-d')
while(sum(is.weekend(df1$startDate) | is.holiday(df1$startDate, holidays)) > 0){
indices <- is.weekend(df1$startDate) | is.holiday(df1$startDate, holidays)
df1$startDate[indices] <- df1$startDate[indices] - 1
}
while(sum(is.weekend(df1$endDate) | is.holiday(df1$endDate, holidays)) > 0){
indices <- is.weekend(df1$endDate) | is.holiday(df1$endDate, holidays)
df1$endDate[indices] <- df1$endDate[indices] + 1
}
或者,您可以使用或不使用chron
构建自己的函数。无论如何,base
有一个weekday
函数可以完成一半的工作。包含在函数中,您可以轻松地在dplyr
的{{1}} / mutate
内部放置一个函数,这样它就可以整齐地放入您的链中。
数据:
transmute