Crea array di dati iniziale/fine del giorno in r
-
28-10-2019 - |
Domanda
Sto usando R per fare qualche analisi delle serie temporali usando Zoo e Chron. Ho un oggetto zoo con molti dati e devo essere in grado di utilizzare il window
Funzionare per sottolineare i dati a un valore di un solo giorno, quindi i giorni successivi, quindi il successivo ecc.
Ho cercato di trovare il modo più semplice per creare un array con la data di ogni giorno in un certo periodo e ho escogitato quanto segue:
orig = c(month=1, day=1, year=2005)
dates <- chron(1:1825, origin=orig, out.format=c(dates="d/m/y", times="h:m"))
Questo usa la notazione di Julian Day e ha 1825 giorni (365*5 - quindi cinque anni), a partire dal primo giorno del mio periodo di data. Quindi provo a fare un loop usando ciascuno degli elementi di questo array:
for (date in dates)
{
s = chron(date, "00:00:00", origin=orig)
e = chron(date, "23:59:59", origin=orig)
aeronet_day = window(aeronet, start=s, end=e)
}
Tuttavia, questo mi dà un avvertimento dicendo che sto usando origini diverse per il aeronet
Oggetto zoo e il s
e e
variabili e non seleziona alcun dato.
C'è un modo migliore per farlo? O un modo per risolvere questo problema? Fondamentalmente quello che voglio è eseguire un ciclo per loop dove nel ciclo posso usare il aeronet_day = window(aeronet, start=s, end=e)
Codice per produrre un oggetto zoo contenente i dati per un giorno (ad es. 1 maggio 2005 dalle 00:00:00 alle 23:59:59.
Soluzione
Supponiamo di avere questi dati:
# create test data
library(zoo)
library(chron)
z <- zooreg(1:30, start = chron("2000-01-01"), freq = 2)
1) aggregatoIl r aggregate
La funzione ha un metodo zoo. Il secondo argomento è ciò che aggregiamo. Se si tratta di una funzione, viene applicata all'indice dell'oggetto zoo. ad esempio qui calcoliamo la media per ogni data:
z.ag <- aggregate(z, as.Date, mean)
Possiamo sostituire mean
con una funzione più complessa se lo desideriamo.
2) diviso. Il r split
La funzione ha un metodo zoo. Se vogliamo davvero dividere z
Per data allora possiamo farlo. Qui z.split.list
è un elenco, ciascuno dei cui componenti contiene l'oggetto zoo per una data.
z.split.list <- split(z, as.Date(time(z)))
Ora (a) sapply
o (b) lapply
In quell'elenco o (c) usa i seguenti (Sostituzione print(zc)
con qualunque elaborazione sia desiderato). Qui zc
è un componente dell'elenco, cioè è l'oggetto zoo formato solo prendendo una data particolare:
for(zc in z.split.list) print(zc)
Notare che as.Date(time(z))
è un vettore con le date corrispondenti agli elementi di z.
MODIFICARE:
Varie elaborazioni minori.
Altri suggerimenti
Non ho familiarità con lo zoo, ma di solito converto la data in un numerico, quindi faccio la sequenza e poi converto di nuovo. Per esempio:
> as.Date(Sys.Date():(Sys.Date()+365), origin='1970-01-01')
[1] "2011-12-06" "2011-12-07" "2011-12-08" "2011-12-09" "2011-12-10" "2011-12-11" "2011-12-12" "2011-12-13"
[9] "2011-12-14" "2011-12-15" "2011-12-16" "2011-12-17" "2011-12-18" "2011-12-19" "2011-12-20" "2011-12-21"
[17] "2011-12-22" "2011-12-23" "2011-12-24" "2011-12-25" "2011-12-26" "2011-12-27" "2011-12-28" "2011-12-29"
[25] "2011-12-30" "2011-12-31" "2012-01-01" "2012-01-02" "2012-01-03" "2012-01-04" "2012-01-05" "2012-01-06"
[33] "2012-01-07" "2012-01-08" "2012-01-09" "2012-01-10" "2012-01-11" "2012-01-12" "2012-01-13" "2012-01-14"
[41] "2012-01-15" "2012-01-16" "2012-01-17" "2012-01-18" "2012-01-19" "2012-01-20" "2012-01-21" "2012-01-22"
...
Se vuoi fare qualcosa su base per data, allora quello che hai va bene.
Qualche campione aeronet
dati.
last_date <- 1825
n <- 10000
aeronet <- data.frame(
some.value = seq_len(n),
date = as.chron(
runif(n, 0, last_date),
origin = orig,
out.format = c(dates = "d/m/y", times = "h:m")
)
)
Ora puoi dividere i dati per data utilizzando split
, o applicare una funzione a ogni data con tapply
o ddply
da plyr
(o usare aggregate
o altro).
with(aeronet, split(some.value, date))
with(aeronet, tapply(some.value, date, sum))
library(plyr)
ddply(aeronet, .(date), summarise, sum(some.value))