79

Hi I'm trying to get a sequence of dates with lubridate

This doesn't work

seq(ymd('2012-04-07'),ymd('2013-03-22'),by=week(1))

the base command

seq(as.Date('2012-04-7'),as.Date('2013-03-22'),'weeks')

does, but I'd like to know if there is an elegant way to do this with lubridate.

EDIT

Please ignore : solved myself so leaving up for posterity only. Happy to have this deleted if necessary.

seq(ymd('2012-04-07'),ymd('2013-03-22'),by='weeks')

Does the trick

Tahnoon Pasha
  • 5,196
  • 12
  • 42
  • 71

2 Answers2

93

ymd is a wrapper to parse date strings and returns a POSIXct object.

You simply need to use standard terminology described in ?seq.POSIXt (not lubridate) to define weeks

seq(ymd('2012-04-07'),ymd('2013-03-22'), by = '1 week')
seq(ymd('2012-04-07'),ymd('2013-03-22'), by = 'weeks')

will works

as will

seq(ymd('2012-04-07'),ymd('2013-03-22'), by = '2 week')

You could coerce the lubridate Period class object to a difftime, but that seems rather unnecessary

seq(ymd('2012-04-07'),ymd('2013-03-22'), by = as.difftime(weeks(1)))
mnel
  • 105,872
  • 25
  • 248
  • 242
  • Is there any way to get a sequence of `POSIXct` formatted objects? I want to use my date-sequence for a custom x-axis, and `POSIXt` doesn't match the plot's data (it's all POSIXct from lubridate output). – rrr Aug 01 '18 at 03:54
  • A caution that the base R approach doesn't always do the same as lubridate's Period. `seq(as.Date("2001-01-31"), as.Date("2001-12-31"), "months")` gives surprising results, for instance. – dash2 Mar 09 '20 at 20:05
8

This is a way to stick within the POSIXct universe of lubridate and not change date formats to base R's POSIXt. I avoid changing the date format in my scripts because I find it is a common place where bugs (for example time-zone changes or losing timestamps) are introduced. It follows this advice to use %m+%: R: adding 1 month to a date

# example date is a leap day for a "worst case scenario"
library("lubridate")
posixct.in <- parse_date_time(x = "2016-02-29", orders = "ymd")
# [1] "2016-02-29 UTC"

posixct.seq <- posixct.in %m+% years(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" "2017-02-28 UTC" "2018-02-28 UTC" "2019-02-28 UTC"

posixct.seq <- posixct.in %m+% months(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" "2016-03-29 UTC" "2016-04-29 UTC" "2016-05-29 UTC"

posixct.seq <- posixct.in %m+% days(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" "2016-03-01 UTC" "2016-03-02 UTC" "2016-03-03 UTC"

posixct.seq <- posixct.in %m+% weeks(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" "2016-03-07 UTC" "2016-03-14 UTC" "2016-03-21 UTC"

A regular + also works sometimes, but the %m+% prevents errors like this:

posixct.seq <- posixct.in + years(x = seq.int(from = 0, to = 3, by = 1))
# [1] "2016-02-29 UTC" NA               NA               NA

At first I was confused because I thought %m+ was just a way to add months, and similar lubridate commands like %y+% etc. do not exist. But, turns out the "m" doesn't stand for "month addition". My best guess is "magic" =)

rrr
  • 1,173
  • 1
  • 15
  • 22