Генерировать последовательность последнего дня месяца за два года
Вопрос
Я использую Lubridate и подумал, что это было бы так просто
ymd("2010-01-31")+months(0:23)
Но посмотрите, что получает. Это все испорчено!
[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"
Затем я прочитал, как Lubridate обслуживает явления, такие как интервал, продолжительность и период. Итак, хорошо, я понимаю, что месяц на самом деле является количеством дней, определенных (365*4+1)/48 = 30,438 дней. Поэтому я пытался стать умным и переписать это как
ymd("2010-01-31")+ as.period(months(0:23))
Но это просто дало ошибку.
Error in as.period.default(months(0:23)) : (list) object cannot be coerced to type 'double'
Решение
Да, вы нашли правильный трюк: возвращаясь на день с первого из в следующем месяце.
Вот как однострочная в базе 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>
Так что нет необходимости Lubridate Что (хотя и отличная упаковка) не нужна для простой задачи, подобной этой. Кроме того, его перегрузка существующих базовых функций по -прежнему поражает меня как несколько опасную ...
Другие советы
Удивительно, как напечатание вопроса фокусирует творческую энергию. Думаю, я разработал ответ. Я могу также опубликовать это здесь для следующей бедной души, которая оказывается тратясь время.
ymd("2010-02-01")+ months(0:23)-days(1)
Просто укажите первый день следующего месяца и генерируйте последовательность из этого, но вычтите от 1 дня, чтобы получить последний день предыдущего месяца.
[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"
Кстати, как мне избавиться от надоедливых обозначений «UTC». Часовые пояса являются спасательными, когда они нужны. В остальное время они неудобно.