2010-12-30 59 views
6

Ho diversi anni di dati (solo per giorni lavorativi (no fine settimana o giorni festivi)) in un frame [r] e vorrei trovare la differenza tra i dati sul 2 ° e 5 ° giorno lavorativo di ogni mese. Quindi la soluzione deve passare attraverso l'elenco, determinare il 2 ° e il 5 ° giorno lavorativo, ottenere i dati e la data completa per le date corrispondenti e quindi trovare la differenza.r - trovare la differenza tra giorni lavorativi

i dati si presenta come:

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) 

Ho provato con dateTime() ma non handicap per fine settimana e festivi. Qualsiasi suggerimento sarebbe apprezzato, grazie.

+0

Onestamente, ho appena capito la domanda quando ho letto la risposta di Dirk. –

+0

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

risposta

2

Suppongo che dal 2 ° e 5 ° giorno lavorativo vuoi dire che 2 ° e 5 ° giorno di dati che è effettivamente presente nei dati per ogni mese. Se questa è la domanda, allora è la seguente. Leggiamo i dati e convertiamo la prima colonna nella classe "Date". Quindi aggreghiamo i dati per mese prendendo la differenza richiesta.

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) 

Utilizzando zoo e chron si può fare tutto via 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) 

aggiornamento Dal momento che questo è stato prima scritto l'argomento text=-read.table e read.zoo è stato aggiunto in R e la risposta è stata aggiornato per usare questo.

+0

Questo è esattamente quello di cui avevo bisogno .... Grazie mille !!!! – acesnap

16

Il tipo base Date funziona per i giorni di calendario, ma non per i giorni lavorativi. Hai bisogno di una logica extra per prendersi cura dei giorni lavorativi. Sono a conoscenza di due sforzi:

  1. il pacchetto timeDate che fa parte di rMetrics ha una serie di calendari

  2. mio pacchetto RQuantLib può farlo anche facendo affidamento nella logica da QuantLib

Ecco solo due esempi di RQuantLib, ci sono un certo numero di altre funzioni correlate:

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>  

e

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

Penso che si dovrebbe notare che il "giorno lavorativo" non è ben definito al di fuori di un dominio particolare . Ad esempio, molti uffici governativi sono chiusi il giorno di Columbus, ma la Borsa di New York non lo è. – frankc

+1

È possibile scegliere quale "calendario" è necessario: Stati Uniti, Stati Uniti/Stati Uniti, Stati Uniti/Stati Uniti, Stati Uniti/Stati Uniti/Stati Uniti/Stati Uniti e Stati Uniti/Stati Uniti. – nvogen

1

Ecco una piccola funzione che consente di inserire una data di inizio, una data di fine e un vettore di date corrispondenti alle festività (utile se si utilizza un calendario festivo non standard) e restituisce il numero di giorni lavorativi tra di loro, contando sia la data di inizio e di fine

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

È possibile calcolare la differenza tra giorni usando il pacchetto bizdays, ma è necessario disporre di un elenco di (giorni non lavorativi) e che non è il tuo caso. Comunque penso che possa aiutare gli altri.

Con i due giorni il codice seguente calcola la quantità di giorni lavorativi tra 2 date.

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:

A partire dalla versione 1.0.0 bizdays viene fornito con un paio di costruito in calendari

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

sarà deprecato La funzione Calendar.

Problemi correlati