web-dev-qa-db-fra.com

Générer une séquence du dernier jour du mois sur deux ans

J'utilise du lubrifiant et j'ai pensé que ce serait si facile

ymd("2010-01-31")+months(0:23)

Mais regardez ce que l'on obtient. Tout est foiré!

 [1] "2010-01-31 UTC" "2010-03-03 UTC" "2010-03-31 UTC" "2010-05-01 UTC" "2010-05-31 UTC" "2010-07-01 UTC" "2010-07-31 UTC" "2010-08-31 UTC" "2010-10-01 UTC"
[10] "2010-10-31 UTC" "2010-12-01 UTC" "2010-12-31 UTC" "2011-01-31 UTC" "2011-03-03 UTC" "2011-03-31 UTC" "2011-05-01 UTC" "2011-05-31 UTC" "2011-07-01 UTC"
[19] "2011-07-31 UTC" "2011-08-31 UTC" "2011-10-01 UTC" "2011-10-31 UTC" "2011-12-01 UTC" "2011-12-31 UTC"

J'ai ensuite lu comment la lubrification répond à des phénomènes tels que l'intervalle, la durée et la période. Donc, OK, je me rends compte qu'un mois est en fait le nombre de jours défini par (365 * 4 + 1)/48 = 30,438 jours. J'ai donc essayé d'être intelligent et de le réécrire

ymd("2010-01-31")+ as.period(months(0:23))

Mais cela a juste donné une erreur.

Error in as.period.default(months(0:23)) : 
  (list) object cannot be coerced to type 'double'
38
Farrel

Oui, vous avez trouvé la bonne astuce: remonter d'un jour à partir du premier mois suivant .

Voici comme une doublure en base R:

R> seq(as.Date("2010-02-01"), length=24, by="1 month") - 1
 [1] "2010-01-31" "2010-02-28" "2010-03-31" "2010-04-30" "2010-05-31"
 [6] "2010-06-30" "2010-07-31" "2010-08-31" "2010-09-30" "2010-10-31"
[11] "2010-11-30" "2010-12-31" "2011-01-31" "2011-02-28" "2011-03-31"
[16] "2011-04-30" "2011-05-31" "2011-06-30" "2011-07-31" "2011-08-31"
[21] "2011-09-30" "2011-10-31" "2011-11-30" "2011-12-31"
R> 

Donc pas besoin de lubridate qui (tout en étant un bon paquet) n'est pas nécessaire pour une tâche simple comme celle-ci. De plus, sa surcharge des fonctions de base existantes me semble toujours quelque peu dangereuse ...

85
Dirk Eddelbuettel

C'est incroyable de voir comment taper une question concentre l'énergie créatrice. Je pense que j'ai trouvé la réponse. Je peux aussi bien le poster ici pour la prochaine pauvre âme qui se retrouve à perdre du temps.

ymd("2010-02-01")+ months(0:23)-days(1)

Spécifiez simplement le premier jour du mois suivant et générez une séquence à partir de cela, mais soustrayez-en 1 jours pour obtenir le dernier jour du mois précédent.

[1] "2010-01-31 UTC" "2010-02-28 UTC" "2010-03-31 UTC" "2010-04-30 UTC" "2010-05-31 UTC" "2010-06-30 UTC" "2010-07-31 UTC" "2010-08-31 UTC" "2010-09-30 UTC"
[10] "2010-10-31 UTC" "2010-11-30 UTC" "2010-12-31 UTC" "2011-01-31 UTC" "2011-02-28 UTC" "2011-03-31 UTC" "2011-04-30 UTC" "2011-05-31 UTC" "2011-06-30 UTC"
[19] "2011-07-31 UTC" "2011-08-31 UTC" "2011-09-30 UTC" "2011-10-31 UTC" "2011-11-30 UTC" "2011-12-31 UTC"

Par ailleurs, comment puis-je me débarrasser des désignations "UTC" embêtantes. Les fuseaux horaires permettent de sauver des vies lorsqu'ils sont nécessaires. Le reste du temps, ils sont une nuisance.

14
Farrel