【问题标题】:Optimizing business-day check (R)优化工作日检查 (R)
【发布时间】:2016-03-09 02:06:22
【问题描述】:

我的目标是从数据框中获取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,因为我正在尝试掌握这个包:)

谢谢!

【问题讨论】:

标签: r dplyr


【解决方案1】:

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

一个警告:is.holiday 需要一个假期列表(默认情况下,它使用 1992 年以来的六个美国假期)。我们可以只使用Business == FALSE 所在的第二个data.frame 中的日期,其中可能包括周末,但这没关系。确实,如果您的周末数据已经很好,使用这种方法您可以完全跳过is.weekend。在这种情况下,两者的日期不一致,所以它不是非常有用。无论如何,该方法将适用于正确的数据。总之,df1df2 分别是您的第一个和第二个 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 函数可以完成一半的工作。包裹在函数中,您可以轻松地将函数夹在 dplyrmutate/transmute 中,因此它可以整齐地放入您的链中。


数据:

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")

【讨论】:

    猜你喜欢
    • 2018-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多