Sélectionnez des valeurs de vecteur par date comme indice
Question
Supposons que j'ai un vecteur nommé, bar
:
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 spécifique? Donc, si je cherche toutes les valeurs entre "1995-01-01"
et "2000-06-01"
, je devrais 1
. Et de même pour la période entre "2001-09-01"
et "2007-11-04"
, je devrais 2
et 1
.
La solution
Ce problème a été résolu pour de bon avec le paquet XTS qui étend les fonctionnalités de paquet 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 fondamental est de faire pas fonctionner sur les chaînes se faisant passer pour les dates.
Utilisez un type de Date
, ou de préférence même un paquet d'extension conçu pour efficacement index sur des millions de dates.
Autres conseils
Vous devez convertir vos dates de caractères en un type de 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 ce standard opérateurs relationnels <= et> =.
Vous devriez envisager d'utiliser un ensemble de séries chronologiques telles 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 de Date
, vous pouvez faire autant de comparaisons que vous le souhaitez. Lire la vignette de zoo
pour plus d'informations.
L'utilisation 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 appelé vecteur (comme vous bar
original, ce n'est pas une liste, il est nommé vecteur).
Comme Dirk dit 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 data.frame
deux colonnes) 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