Question

J'utilise lubridate et pensé que ce serait si facile

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

Mais regardez ce que l'on obtient. Il est tout 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"

Alors je lis comment Caters de lubridate à des phénomènes tels que l'intervalle, la durée et la période. Alors, 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. Alors j'ai essayé de faire preuve d'intelligence et de réécrire comme

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

Mais cela vient de donner une erreur.

Error in as.period.default(months(0:23)) : 
  (list) object cannot be coerced to type 'double'
Était-ce utile?

La solution

Yes, you found the correct trick: going back a day from the first of the next month.

Here is as a one-liner in 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> 

So no need for lubridate which (while being a fine package) isn't needed for simple task like this. Plus, its overloading of existing base functions still strikes me as somewhat dangerous...

Autres conseils

It is amazing how typing out a question focuses creative energy. I think I worked out the answer. I may as well post it here for the next poor soul who finds themselves wasting time.

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

Simply specify the first day of the next month and generate a sequence from that but subtract 1 days from it to get the last day of the preceding month.

[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"

By the way, how do I get rid of the pesky "UTC" designations. Time zones are a life saver when they are needed. The rest of the time they are a nuisance.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top