2010-12-30 10 views
6

Mam kilka lat danych (tylko w dni robocze (bez weekendów lub świąt)) w ramce danych [r] i chciałbym znaleźć różnicę między danymi na 2 i 5 dzień roboczy każdego miesiąca. Tak więc rozwiązanie musi przejść przez listę, określić drugi i piąty dzień roboczy, uzyskać dane i pełną datę dla odpowiednich dat, a następnie znaleźć różnicę.r - ustalenie różnicy między dniami roboczymi

danych wygląda następująco:

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) 

Próbowałem, używając dateTime(), ale nie utrudniać na weekendy i święta. Wszelkie sugestie będą mile widziane, dziękuję.

+0

Szczerze mówiąc, po prostu zrozumiałem pytanie, kiedy przeczytałem odpowiedź Dirka. –

+0

http://stackoverflow.com/questions/38448310/r-finding-difference-in-business-days/38448463#38448463 – Sathish

Odpowiedz

2

Zakładam, że przez 2 i 5 dnia roboczego To znaczy, że 2. i 5. dzień danych, które są faktycznie obecne w danych dla każdego miesiąca. Jeśli to jest pytanie, to w następujący sposób. Odczytujemy dane i przekształcamy pierwszą kolumnę w klasę "Date". Następnie agregujemy dane według miesiąca, przyjmując wymaganą różnicę.

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) 

Korzystanie zoo i Kron można to zrobić wyłącznie za pośrednictwem 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) 

Aktualizacja Ponieważ ta została po raz pierwszy napisał text= argument read.table i read.zoo dodano w badania i odpowiedzi został zaktualizowany, aby móc z niego korzystać.

+0

Dokładnie tego potrzebowałem ... Dziękuję bardzo! – acesnap

16

Podstawowy typ Date działa w dni kalendarzowe, ale nie w dni robocze. Potrzebujesz dodatkowej logiki, aby zająć się dniami pracy. Zdaję sobie sprawę z dwóch działań:

  1. pakiet timeDate który jest częścią rMetrics ma wiele kalendarzy

  2. mój pakiet RQuantLib może zrobić tak samo, opierając się w logice z QuantLib

Oto tylko dwa przykłady z RQuantLib, istnieje szereg innych funkcji związanych z:

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>  

i

R>  from <- as.Date("2009-04-07") 
R>  to<-as.Date("2009-04-14") 
R>  businessDaysBetween("UnitedStates", from, to) 
[1] 5 
R> 
+1

Myślę, że należy zauważyć, że "dzień roboczy" nie jest super dobrze zdefiniowany poza daną domeną . Na przykład wiele biur rządowych jest zamkniętych w dniu Columbus, ale nowojorska giełda nie jest. – frankc

+1

Możesz wybrać, który "kalendarz" potrzebujesz: Stany Zjednoczone, Stany Zjednoczone/Osiedle, Stany Zjednoczone/Nowy Jork, Stany Zjednoczone/Rząd Stanów Zjednoczonych, Stany Zjednoczone/NERC i Weekendy Tylko. – nvogen

1

Oto mała funkcja, która umożliwia wprowadzenie daty rozpoczęcia, daty zakończenia i wektora dat odpowiadających świątom (przydatne, jeśli korzystasz z niestandardowego kalendarza świąt) i zwraca liczbę dni roboczych między nimi, licząc zarówno datę rozpoczęcia i zakończenia

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)) 
} 
1

można zobaczyć różnicę między czasem dni roboczych wykorzystujących pakiet bizdays, ale trzeba mieć listę świąt (dni wolne od pracy) i to nie twoja sprawa. W każdym razie myślę, że może pomóc innym.

W przypadku znaków firmowych następujący kod obliczałby liczbę dni roboczych między 2 datami.

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:

Od wersji 1.0.0 bizdays pochodzi z kilkoma wybudowany w kalendarzach

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

Funkcja Calendar będą przestarzałe.

Powiązane problemy