我在[r]数据框中有几年的数据(仅限工作日(没有周末或假日)),并希望找到每月第2个工作日和第5个工作日的数据之间的差异。因此,解决方案需要通过列表,确定第2个工作日和第5个工作日,获取相应日期的数据和完整日期,然后找出差异。
数据如下:
1/19/1990 1.22
1/20/1990 1.25
1/23/1990 1.26 ## (Gap in date is weekend)
...
2/1/1990 1.34
2/2/1990 1.36
2/5/1990 1.22 ## (Gap in date is weekend)
我已经尝试过使用dateTime(),但它不会在周末和假期出现问题。任何建议都将不胜感激,谢谢。
答案 0 :(得分:16)
基本Date
类型适用于日历日,但不适用于工作日。你需要额外的逻辑来照顾工作日。我知道有两项努力:
作为rMetrics一部分的timeDate包有多个日历
以下是RQuantLib的两个例子,还有许多相关的其他功能:
R> from <- as.Date("2009-04-07")
R> to <-as.Date("2009-04-14")
R> getHolidayList("UnitedStates", from, to)
NULL
R> to <- as.Date("2009-10-7")
R> getHolidayList("UnitedStates", from, to)
[1] "2009-05-25" "2009-07-03" "2009-09-07"
R>
和
R> from <- as.Date("2009-04-07")
R> to<-as.Date("2009-04-14")
R> businessDaysBetween("UnitedStates", from, to)
[1] 5
R>
答案 1 :(得分:2)
我假设在第2个工作日和第5个工作日,您指的是每个月数据中实际存在的数据的第2天和第5天。如果这是问题,那么如下。我们读入数据并将第一列转换为"Date"
类。然后我们按月汇总数据,取得所需的差异。
Lines <- "1/19/1990 1.22
1/20/1990 1.25
1/23/1990 1.26
1/24/1990 1.26
1/25/1990 1.26
1/26/1990 1.26
2/1/1990 1.34
2/2/1990 1.36
2/5/1990 1.22
2/6/1990 1.22
2/7/1990 1.22
2/8/1990 1.22"
DF <- read.table(text = Lines, col.names = c("Date", "Value"))
DF$Date <- as.Date(DF$Date, "%m/%d/%Y")
aggregate(DF$Value, list(ym = format(DF$Date, "%Y-%m")),
function(x) if (length(x) >= 5) x[5] - x[2] else NA)
使用zoo和chron可以完全通过read.zoo
:
library(zoo)
library(chron)
read.zoo(text = Lines, FUN = chron, FUN2 = as.yearmon,
aggregate = function(x) if (length(x) >= 5) x[5] - x[2] else NA)
更新由于首次编写,text=
read.table
参数已添加到read.zoo
,{{1}}已添加到R中,答案已更新为使用此内容。< / p>
答案 2 :(得分:2)
这是一个小功能,可让您输入开始日期,结束日期和与假期相对应的日期向量(如果您使用非标准假日日历,则非常有用)并返回它们之间的工作日数,开始和结束日期
workdays = function(iniDate, endDate, holidays) {
theDates = seq(from=iniDate,to=endDate,by="day")
isHoliday = theDates %in% holidays
isWeekend = (as.POSIXlt(theDates)$wday) %in% (c(0,6))
return (sum(!isHoliday & !isWeekend))
}
答案 3 :(得分:1)
您可以使用包bizdays
找到工作日之间的差异,但您必须有一个假期列表(非工作日),而不是您的情况。无论如何,我认为它可以帮助别人。
使用bizdays时,以下代码将计算两个日期之间的工作日数。
library(bizdays)
cal <- Calendar(holidaysANBIMA, weekdays=c('sunday', 'saturday'), dib=252)
from_dates <- c('2013-07-12', '2012-06-13')
to_dates <- seq(as.Date('2014-02-17'), as.Date('2016-07-21'), by='months')
bizdays(from_dates, to_dates, cal = cal)
## [1] 153 442 194 483 234 526 276 570 321 613 364 655 404 695
## [15] 446 735 486 779 529 822 571 863 614 904 654 946 695 987
## [29] 738 1029
编辑:
从版本1.0.0起,bizdays附带一些内置日历
library(bizdays)
from_dates <- c('2013-07-12', '2012-06-13')
to_dates <- seq(as.Date('2014-02-17'), as.Date('2016-07-21'), by='months')
bizdays(from_dates, to_dates, cal = "Brazil/ANBIMA")
{@ 1}}函数将被弃用。