r - найти разницу между рабочими днями - PullRequest
6 голосов
/ 30 декабря 2010

У меня есть данные за несколько лет (только для рабочих дней (без выходных и праздничных дней)) во фрейме данных [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 (), но это не препятствует выходным и праздничным дням.Любые предложения будут оценены, спасибо.

Ответы [ 4 ]

16 голосов
/ 30 декабря 2010

Базовый тип Date работает для календарных дней, но не для рабочих дней. Вам нужна дополнительная логика, чтобы заботиться о рабочих днях. Я знаю о двух попытках:

  1. пакет timeDate , входящий в состав rMetrics, содержит несколько календарей

  2. мой RQuantLib пакет может сделать это тоже, полагаясь на логику QuantLib

Вот только два примера из 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> 
2 голосов
/ 27 мая 2013

Вот небольшая функция, которая позволяет вам вводить дату начала, дату окончания и вектор дат, которые соответствуют праздникам (полезно, если вы используете нестандартный календарь праздников), и возвращает количество рабочих дней между ними, считая дата начала и окончания

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))
}
2 голосов
/ 30 декабря 2010

Я предполагаю, что под 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 был добавлен в R, и ответ был обновлен для использования этого.

1 голос
/ 23 сентября 2015

Вы можете найти разницу между рабочими днями, используя пакет 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

EDIT:

Начиная с версии 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")

Функция Calendar устарела.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...