2012-02-27 11 views
5

Ho due dateCOUNT giorni all'anno

begin <- as.Date("2007-05-20") 
end <- as.Date("2010-06-13") 

Come posso contare i giorni all'anno?

L'output dovrebbe forse simile a questa

year days 
2007 226 
2008 366 
2009 365 
2010 164 

risposta

11

si deve prima creare una vera e propria sequenza di date:

R> bd <- as.Date("2007-05-20") 
R> ed <- as.Date("2010-06-13") 
R> seqd <- seq(bd, ed, by="1 day") 
R> head(seqd) 
[1] "2007-05-20" "2007-05-21" "2007-05-22" "2007-05-23" "2007-05-24" "2007-05-25" 

Abbiamo poi creiamo una funzione di supporto, che, dato una data, restituisce il suo anno:

R> getYear <- function(d) as.POSIXlt(d)$year + 1900 
R> getYear(head(seqd)) 
[1] 2007 2007 2007 2007 2007 2007 

Dopo di che, ci basta chiamare table() su cosa restituisce l'helper dalla sequenza di date:

R> table(getYear(seqd)) 

2007 2008 2009 2010 
226 366 365 164 
+3

Una leggera variazione su quanto sopra sarebbe: 'tabella (formato (seq (bd, ed," giorno "),"% Y "))' –

+0

Nice one Gabor. Non riuscivo a ricordare era l'estrattore più succinto; la tua versione sicuramente si qualifica. –

1

Qualcosa di simile dovrebbe fare il trucco:

function daysPerYear(begin, end) 
{ 
    var days = {}; 
    for (var y = begin.getFullYear(); y < end.getFullYear(); y++) 
    { 
     days[y] = Math.ceil((new Date(y+1, 0, 1) - begin)/86400000); 
     begin = new Date(y+1, 0, 1); 
    } 
    days[ end.getFullYear() ] = Math.ceil((end - begin)/86400000); 
    return days; 
} 

Esempio:

console.log(daysPerYear(new Date("2007-05-20"), new Date("2010-06-13"))); 

http://puu.sh/iBgo

Modifica: pensavo che si trattasse di Javascript.

+0

sì mi stavo chiedendo :) ma buona codifica comunque! – speendo

2

Oppure, in alternativa, creare un data.frame con una colonna aggiuntiva year (utilizzando i dati di Dirk):

dat = data.frame(seqd, year = strftime(seqd, "%Y")) 
> head(dat) 
     seqd year 
1 2007-05-20 2007 
2 2007-05-21 2007 
3 2007-05-22 2007 
4 2007-05-23 2007 
5 2007-05-24 2007 
6 2007-05-25 2007 

e quindi utilizzare count dalla confezione plyr:

require(plyr) 
> count(dat, "year") 
    year freq 
1 2007 226 
2 2008 366 
3 2009 365 
4 2010 164 
1

Una soluzione intensivo meno memoria sarebbe, anche se non una fodera:)

begin <- as.POSIXlt("2007-05-20", tz = "GMT") 
end <- as.POSIXlt("2010-06-13", tz = "GMT") 

year <- seq(begin$year, end$year) + 1900 
year.begin <- as.POSIXlt(paste(year, "01", "01", sep="-"), tz="GMT") 
year.begin[1] <- begin 
year.end <- as.POSIXlt(paste(year, "12", "31", sep="-"), tz="GMT") 
year.end[length(year.end)] <- end 
days <- as.numeric(year.end - year.begin) + 1 
cbind(year, days) 

Motivato da Make this process more processor intensive and less memory intensive