Selezionare i valori da vettore con data come indice
Domanda
Supponiamo che io abbia un nome vettore, bar
:
bar=c()
bar["1997-10-14"]=1
bar["2001-10-14"]=2
bar["2007-10-14"]=1
Come faccio a scegliere tra bar
tutti i valori per i quali l'indice è all'interno di un intervallo di date specifico? Quindi, se guardo per tutti i valori tra "1995-01-01"
e "2000-06-01"
, dovrei ottenere 1
. E allo stesso modo per il periodo tra il "2001-09-01"
e "2007-11-04"
, dovrei ottenere 2
e 1
.
Soluzione
Questo problema è stato risolto per sempre con la href="http://cran.r-project.org/packages=xts" rel="nofollow noreferrer"> xts pacchetto che si estende dalla funzionalità pacchetto zoo .
R> library(xts)
Loading required package: zoo
R> bar <- xts(1:3, order.by=as.Date("2001-01-01")+365*0:2)
R> bar
[,1]
2001-01-01 1
2002-01-01 2
2003-01-01 3
R> bar["2002::"] ## open range with a start year
[,1]
2002-01-01 2
2003-01-01 3
R> bar["::2002"] ## or end year
[,1]
2001-01-01 1
2002-01-01 2
R> bar["2002-01-01"] ## or hits a particular date
[,1]
2002-01-01 2
R>
C'è molto di più qui - ma il punto fondamentale è fare non operare su stringhe mascherati da date.
Usa un tipo Date
, o, preferibilmente, anche un pacchetto di estensione costruito in modo efficiente indice su milioni di date.
Altri suggerimenti
È necessario convertire le date da personaggi in un tipo Date
con as.Date()
(o un tipo POSIX se si dispone di ulteriori informazioni come l'ora del giorno). Quindi è possibile fare paragoni con standard di operatori relazionali quali <= e> =.
Si dovrebbe considerare l'utilizzo di un pacchetto timeseries come zoo
per questo.
Modifica :
Proprio per rispondere al tuo commento, ecco un esempio di utilizzo di date con la vostra vettoriale esistente:
> as.Date(names(bar)) < as.Date("2001-10-14")
[1] TRUE FALSE FALSE
> bar[as.Date(names(bar)) < as.Date("2001-10-14")]
1997-10-14
1
Anche se si dovrebbe semplicemente utilizzare un pacchetto di serie storiche. Ecco come si potrebbe fare questo con zoo
(o xts
, timeSeries
, fts
, ecc):
library(zoo)
ts <- zoo(c(1, 2, 1), as.Date(c("1997-10-14", "2001-10-14", "2007-10-14")))
ts[index(ts) < as.Date("2001-10-14"),]
Dal momento che l'indice è ora un tipo di Date
, si può fare come molti paragoni come si desidera. Leggi la vignetta zoo
per ulteriori informazioni.
Utilizzando fatto che sono date in ordine lessicale:
bar[names(bar) > "1995-01-01" & names(bar) < "2000-06-01"]
# 1997-10-14
# 1
bar[names(bar) > "2001-09-01" & names(bar) < "2007-11-04"]
# 2001-10-14 2007-10-14
# 2 1
Il risultato viene chiamato vettore (come si bar
originale, non è una lista è chiamato vettore).
Come Dirk afferma nella sua risposta è meglio utilizzare Date
per ragioni di efficienza. Senza di pacchetti esterni si potrebbe riorganizzare i tuoi dati e creare due vettori (o due colonne data.frame
) uno per le date, una per i valori:
bar_dates <- as.Date(c("1997-10-14", "2001-10-14", "2007-10-14"))
bar_values <- c(1,2,1)
quindi utilizzare semplice indicizzazione:
bar_values[bar_dates > as.Date("1995-01-01") & bar_dates < as.Date("2000-06-01")]
# [1] 1
bar_values[bar_dates > as.Date("2001-09-01") & bar_dates < as.Date("2007-11-04")]
# [1] 2 1