2017-09-19 9 views
1

Je voudrais comparer les heures dans la colonne date-heure (qui est la colonne d'index d'un objet xts). Disons que j'ai ensemble de données appelé My_Data donnée comme suit:Comparaison des temps dans les objets XTS dans R

My_Data <- structure(c(5, 2, 4, 8, 9), index = structure(c(1184599268.133, 
    1184602925.231, 1184604481.931, 1184685301.769, 1184685668.133), tzone = "", 
    tclass = c("POSIXct", "POSIXt")), class = c("xts", "zoo"), 
    .indexCLASS = c("POSIXct", "POSIXt"), tclass = c("POSIXct", "POSIXt"), 
    .indexTZ = "", tzone = "", .Dim = c(5L, 1L), .Dimnames = list(NULL, "Price")) 

Notez que puisque les données est un objet xts, la colonne date-heure dans l'index de l'ensemble de données et peut être appelé en utilisant la fonction index(My_Data)

pour mon programme, je suis itérer sur mon jeu de données, et je voudrais savoir quand la date change dans l'indice des données (qui, dans les données ci-dessus, irions des dates 2007-07-16-2007-07-17) À cette fin, j'ai essayé d'utiliser la fonction suivante pour extraire la date à chaque ligne d'index:Lorsque cette fonction va extraire la date de l'index de la première ligne de mes données (2007-07-16) Donc, pour extraire une ligne arbitraire i J'utilise

(format(index(My_Data)[i], format = "%Y-%m-%d")) 

Et, pour comparer deux lignes différentes pour savoir si les dates sont différentes que j'utilise:

(format(index(My_Data)[1], format = "%Y-%m-%d")) < 
(format(index(My_Data)[2], format = "%Y-%m-%d")) 

qui compare la date de la première ligne d'index avec la date de la deuxième ligne d'index.

Cependant, cette comparaison est extrêmement lente - j'ai vérifié cette comparaison en utilisant le paquet microbenchmark et il est de l'ordre de quelques millisecondes! Comme j'ai une grande quantité de données, je me demandais s'il y avait un moyen plus efficace de vérifier quand les dates ont changé dans l'index, puisque cette méthode ralentira beaucoup mon code.

Répondre

1

Vous avez (au moins) quelques meilleures options. Choisissez celui qui fonctionne le mieux pour votre situation.

Vous pouvez utiliser .indexDate() et diff() pour vous informer lorsque la date de l'index change. Souvenez-vous que diff() renvoie un objet dont la longueur a une observation de moins que sa valeur d'entrée. Vous devez donc le concaténer avec un zéro ou NA.

merge(My_Data, newdate = c(0, diff(.indexDate(My_Data)))) 
#      Price newdate 
# 2007-07-16 10:21:08  5  0 
# 2007-07-16 11:22:05  2  0 
# 2007-07-16 11:48:01  4  0 
# 2007-07-17 10:15:01  8  1 
# 2007-07-17 10:21:08  9  0 

Vous pouvez également utiliser endpoints() pour vous dire la dernière observation pour chaque jour de votre série. Rappelez-vous que endpoints() retourne toujours un vecteur qui commence par 0 et se termine par nrow(x).

endpoints(My_Data, "days") 
# [1] 0 3 5 

La raison pour laquelle votre solution prend plus de temps est parce conversion à des chaînes de caractères est cher. Je suppose également que l'utilisation d'opérateurs logiques sur les chaînes de caractères est plus coûteuse que sur les nombres, car le tri des chaînes de caractères dépend de l'ordre de classement de votre locale (donc plus d'opérations sont probables).

+0

Merci, oui, par le look, il vaudrait peut-être mieux que je les convertisse en nombres en utilisant .'.indexDate() 'et ensuite utiliser une comparaison, donc je vais essayer ça :) – reallybadstatdude