2010-04-29 1 views
1

Supposons que j'ai un vecteur nommé, bar:Sélectionner les valeurs de vecteur en utilisant la date comme indice

bar=c() 
bar["1997-10-14"]=1 
bar["2001-10-14"]=2 
bar["2007-10-14"]=1 

Comment puis-je choisir de bar toutes les valeurs pour lesquelles l'indice se situe dans une plage de dates? Donc, si je cherche toutes les valeurs entre "1995-01-01" et "2000-06-01", je devrais obtenir 1. Et de même pour la période entre "2001-09-01" et "2007-11-04", je devrais obtenir 2 et 1.

+3

FYI: Vous créez un vecteur numérique nommé, pas une liste. – Shane

Répondre

4

Ce problème a été résolu pour de bon avec le package xts qui étend les fonctionnalités du package 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> 

Il y a beaucoup plus ici - mais le point de base est de ne pas fonctionnent sur les chaînes se faisant passer pour les dates.

Utilisez un type Date, ou de préférence même un package d'extension conçu pour indexer efficacement des millions de dates.

2

Vous devez convertir vos dates de caractères en un type Date avec as.Date() (ou un type POSIX si vous avez plus d'informations comme l'heure du jour). Ensuite, vous pouvez faire des comparaisons avec la norme relational operators comme < = et> =.

Vous devez envisager d'utiliser un package de timeseries tel que zoo pour cela.

Modifier:

Juste pour répondre à votre commentaire, voici un exemple d'utilisation dates avec votre vecteur existant:

> 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 

Bien que vous devriez vraiment utiliser un ensemble de séries chronologiques. Voici comment vous pouvez le faire avec zoo (ou xts, timeSeries, fts, etc.):

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

Comme l'indice est maintenant un type Date, vous pouvez faire autant de comparaisons que vous le souhaitez. Lisez la vignette zoo pour plus d'informations.

+0

Hmmm, je vais peut-être mal le faire mais si je fais quelque chose comme bar [as.Date ("2001-10-14")] je reçois des résultats très étranges impliquant beaucoup de NAs – Pieter

1

Utiliser fait que les dates sont dans l'ordre lexical:

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 

Le résultat est nommé vecteur (comme vous d'origine bar, ce n'est pas une liste, il est nommé vecteur). Comme dira Dirk dans sa réponse, il est préférable d'utiliser Date pour des raisons d'efficacité. Sans packages externes, vous pouvez vous réorganiser les données et créer deux vecteurs (ou deux colonnes data.frame) une pour les dates, une des valeurs:

bar_dates <- as.Date(c("1997-10-14", "2001-10-14", "2007-10-14")) 
bar_values <- c(1,2,1) 

puis utilisez l'indexation simple:

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 
Questions connexes