优化工作日检查(R)

优化工作日检查(R),r,dplyr,R,Dplyr,我的目标是从数据框中获取一个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 GO

我的目标是从数据框中获取一个
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>
日期工作日业务事件
1 2001-01-01星期一假元旦
2 2001-01-02星期二真实
3 2001-01-03星期三真实
4 2001-01-04星期四真实
5 2001-01-05星期五真实
6 2001-01-06星期六假
因此,我使用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)))
}
for(1:10中的i){
股票1%
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
,因为我正试图掌握这个软件包:)


谢谢

chron软件包有一些令人愉快的功能,称为
is.weekend
is.holiday
,在这里非常有用。至于优化,这实际上似乎是一种罕见的情况,在R中使用
while
循环似乎是值得的。您仍然需要两个循环,除非您希望以编程的方式进行

有一个警告:
是。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
}
看见
df1 <- structure(list(tickers = structure(c(1L, 1L, 1L, 1L, 1L, 1L), .Label = "GOOGL", class = "factor"), 
    startDate = structure(c(16831, 16729, 16631, 16547, 16463, 
    16358), class = "Date"), endDate = structure(c(16833, 16731, 
    16633, 16549, 16465, 16360), class = "Date")), .Names = c("tickers", 
    "startDate", "endDate"), row.names = c(NA, -6L), class = "data.frame")

df2 <- structure(list(Date = structure(c(11323, 11324, 11325, 11326, 
    11327, 11328), class = "Date"), Weekday = structure(c(2L, 5L, 
    6L, 4L, 1L, 3L), .Label = c("Friday", "Monday", "Saturday", "Thursday", 
    "Tuesday", "Wednesday"), class = "factor"), Business = c(FALSE, 
    TRUE, TRUE, TRUE, TRUE, FALSE), Event = structure(c(2L, 1L, 1L, 
    1L, 1L, 1L), .Label = c("<NA>", "New_Years_Day"), class = "factor")), .Names = c("Date", 
    "Weekday", "Business", "Event"), row.names = c(NA, -6L), class = "data.frame")