seq () for POSIXct

mon but est de créer un vecteur de pointeurs temporels POSIXct avec un départ, une fin et un delta (15min, 1hour, 1jour). J'espère que je pourrais utiliser seq pour cela, mais j'ai un problème de conversion entre la représentation numérique et POSIXct:

now <- Sys.time()
now
# [1] "2012-01-19 10:30:39 CET"
as.POSIXct(as.double(now), origin="1970-01-01", tz="CET")
# [1] "2012-01-19 09:30:39 CET"
as.POSIXct(as.double(now), origin=as.POSIXct("1970-01-01", tz="CET"), tz="CET")
# [1] "2012-01-19 09:30:39 CET"

une heure se perd lors de cette conversion. Ce que je fais mal?

16
demandé sur Richie Cotton 2012-01-19 14:03:38

6 réponses

il y a un seq() méthode pour les objets de la classe "POSIXt" qui est la super classe de l' "POSIXlt" et "POSIXct" classes. En tant que tel, vous n'avez pas besoin de faire la conversion.

> now <- Sys.time()
> tseq <- seq(from = now, length.out = 100, by = "mins")
> length(tseq)
[1] 100
> head(tseq)
[1] "2012-01-19 10:52:38 GMT" "2012-01-19 10:53:38 GMT"
[3] "2012-01-19 10:54:38 GMT" "2012-01-19 10:55:38 GMT"
[5] "2012-01-19 10:56:38 GMT" "2012-01-19 10:57:38 GMT"
22
répondu Gavin Simpson 2016-02-11 16:48:39

vous devez être conscient que lors de la conversion de POSIXct en numérique, R prend en compte le fuseau horaire mais commence toujours à compter à partir D'une origine GMT :

> xgmt <- as.POSIXct('2011-01-01 14:00:00',tz='GMT')
> xest <- as.POSIXct('2011-01-01 14:00:00',tz='EST')
> (as.numeric(xgmt) - as.numeric(xest)) / 3600
[1] -5

comme vous le voyez, le temps en EST est conçu pour être cinq heures plus tôt que le temps en GMT, qui est le décalage horaire entre les deux fuseaux horaires. C'est cette valeur qui est sauvegardée en interne.

as.POSIXCT() fonction ajoute un attribut contenant le fuseau horaire. Cela ne modifie pas la valeur, donc vous obtenez le heure présentée en heure GMT, mais avec un attribut indiquant qu'il est EST. Cela signifie aussi qu'une fois que vous passez de POSIXct numérique, vous devez traiter vos données comme si c'est l'heure GMT. (C'est un ensemble beaucoup plus complexe que ça, mais c'est l'idée générale). Donc, vous devez calculer le décalage comme suit:

> nest <- as.numeric(xest)
> origin <- as.POSIXct('1970-01-01 00:00:00',tz='EST')
> offset <- as.numeric(origin)
> as.POSIXct(nest-offset,origin=origin)
[1] "2011-01-01 14:00:00 EST"

cela fonctionne quel que soit le fuseau horaire dans votre localité (dans mon cas, c'est en fait CET). Notez également que le comportement des données de fuseau horaire peut différer d'un système à l'autre.

10
répondu Joris Meys 2012-01-19 12:11:47

ces problèmes de fuseaux horaires sont toujours fiddly, mais je pense que le problème est que votre origine est calculée dans le mauvais fuseau horaire (puisque la chaîne ne spécifie que la date).

Essayez d'utiliser origin <- now - as.numeric(now).

vous pouvez également utiliser lubridate::origin, qui est la chaîne de caractères "1970-01-01 UTC".


une solution complète, en utilisant lubridate.

start <- now()
seq(start, start + days(3), by = "15 min")
7
répondu Richie Cotton 2012-01-19 10:57:52

Une alternative à l'utilisation de seq.POSIXtxts::timeBasedSeq, qui permet de spécifier la séquence comme une chaîne de caractères:

library(xts)
now <- Sys.time()
timeBasedSeq(paste("2012-01-01/",format(now),"/H",sep=""))  # Hourly steps
timeBasedSeq(paste("2012-01-01/",format(now),"/d",sep=""))  # Daily steps
4
répondu Joshua Ulrich 2012-01-19 14:10:30

je n'ai pas de réponse à votre problème, mais j'ai un autre moyen de créer des vecteurs de POSIXct objets. Si, par exemple, vous voulez créer un vecteur de 1000 horodateurs à partir de maintenant avec un delta_t de 15 minutes:

now = Sys.time()
dt = 15 * 60 # in seconds
timestamps = now + seq(0, 1000) * dt
> head(timestamps)
[1] "2012-01-19 11:17:46 CET" "2012-01-19 11:32:46 CET"
[3] "2012-01-19 11:47:46 CET" "2012-01-19 12:02:46 CET"
[5] "2012-01-19 12:17:46 CET" "2012-01-19 12:32:46 CET"

le truc est d'ajouter un vecteur de secondes à un POSIXct objet.

3
répondu Paul Hiemstra 2012-01-19 10:18:39

Vous devez utiliser seq(from=pour=fin=étape). Notez que dans step vous pouvez utiliser "days" ou un Entier définissant combien de secondes s'écoulent d'un élément à l'autre.

1
répondu Marcelo Bielsa 2015-11-09 15:13:09