Skip to content

seq.Date bug?

8 messages · Sarah Goslee, Duncan Murdoch, Marc Schwartz +2 more

#
R> seq(as.Date(Sys.Date()), by="-1 months", length=6)
[1] "2012-01-31" "2011-12-31" "2011-12-01" "2011-10-31" "2011-10-01" "2011-08-31"
R> 

Notice how October appears twice.

Now, date arithmetic is gruesome but the documentation for seq.Date et al
does not hint it wouldn't honour the by= argument.  So a bug, or merely a
somewhat less than desirable features.

(And yes, I think I know that Hadley's lubridate has code for this too, but
so may my RcppBDT which is sitting on top of Boost::DateTime code ...)

Dirk
#
I was prompted to try it myself:
On Tue, Jan 31, 2012 at 2:56 PM, Dirk Eddelbuettel <edd at debian.org> wrote:
As does December.
The by argument chokes on "month" if the current day is greater than the
shortest month in the sequence (presumably due to the irregular nature
of month lengths):

For leap year 2012:
[1] "2012-01-29" "2012-02-29" "2012-03-29" "2012-04-29" "2012-05-29"
 [6] "2012-06-29" "2012-07-29" "2012-08-29" "2012-09-29" "2012-10-29"
[11] "2012-11-29" "2012-12-29"
[1] "2012-01-30" "2012-03-01" "2012-03-30" "2012-04-30" "2012-05-30"
 [6] "2012-06-30" "2012-07-30" "2012-08-30" "2012-09-30" "2012-10-30"
[11] "2012-11-30" "2012-12-30"

While for non-leap year 2011:
[1] "2011-01-28" "2011-02-28" "2011-03-28" "2011-04-28" "2011-05-28"
 [6] "2011-06-28" "2011-07-28" "2011-08-28" "2011-09-28" "2011-10-28"
[11] "2011-11-28" "2011-12-28"
[1] "2011-01-29" "2011-03-01" "2011-03-29" "2011-04-29" "2011-05-29"
 [6] "2011-06-29" "2011-07-29" "2011-08-29" "2011-09-29" "2011-10-29"
[11] "2011-11-29" "2011-12-29"
R version 2.14.1 (2011-12-22)
Platform: x86_64-redhat-linux-gnu (64-bit)

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
 [7] LC_PAPER=C                 LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

loaded via a namespace (and not attached):
[1] tools_2.14.1
#
On 12-01-31 2:56 PM, Dirk Eddelbuettel wrote:
It is giving you Jan 31, Dec 31, Nov 31, Oct 31, Sep 31, Aug 31 -- 
except some of those months don't have 31 days, so it is converting 
those dates to ones that really exist.  (This is documented in ?seq.POSIXt.)

Isn't this what you asked for?

Duncan Murdoch
#
On Jan 31, 2012, at 2:07 PM, Sarah Goslee wrote:

            
The issue is the if the next month in sequence does not contain the date, then the date is advanced until the next valid date. For example:
[1] "2012-01-30" "2012-03-01" "2012-03-30"

February 30th does not exist, thus that date is advanced to March 1st, then the next date in the sequence is March 30th. Thus, two days in March.
[1] "2012-10-31" "2012-12-01" "2012-12-31"

Here, November 31st does not exist, so the date is advanced to the next valid date, December 1 and then the next date is December 31. Thus, two days in December.


So it appears to be working correctly.

HTH,

Marc Schwartz
#
As Duncan pointed out, this is documented in ?seq.POSIXt:

     Using ?"month"? first advances the month without changing the day:
     if this results in an invalid day of the month, it is counted
     forward into the next month: see the examples.

But ?seq.Date gives the impression that the construct Dirk and I tried
should work:

     ## find all 7th of the month between two dates, the last being a 7th.
     st <- as.Date("1998-12-17")
     en <- as.Date("2000-1-7")
     ll <- seq(en, st, by="-1 month")
     rev(ll[ll > st & ll < en])

is given as an example, and it is not pointed out that this won't work for
the 30th of the month. Normally one can extrapolate from patterns given
in the examples, and here that isn't true. So perhaps the help should
be modified slightly instead?

Sarah
#
On 31 January 2012 at 15:17, Duncan Murdoch wrote:
| On 12-01-31 2:56 PM, Dirk Eddelbuettel wrote:
| >
| > R>  seq(as.Date(Sys.Date()), by="-1 months", length=6)
| > [1] "2012-01-31" "2011-12-31" "2011-12-01" "2011-10-31" "2011-10-01" "2011-08-31"
| > R>
| >
| > Notice how October appears twice.
| 
| >
| > Now, date arithmetic is gruesome but the documentation for seq.Date et al
| > does not hint it wouldn't honour the by= argument.  So a bug, or merely a
| > somewhat less than desirable features.
| 
| It is giving you Jan 31, Dec 31, Nov 31, Oct 31, Sep 31, Aug 31 -- 
| except some of those months don't have 31 days, so it is converting 
| those dates to ones that really exist.  (This is documented in ?seq.POSIXt.)
| 
| Isn't this what you asked for?

No as I was feeding this into format(..., "%b-%y") to create 'pretty' names,
and the double entries screw that.

Morale:  pick a mid-month date, and shift that.

Dirk
 
| Duncan Murdoch
| 
| 
| >
| > (And yes, I think I know that Hadley's lubridate has code for this too, but
| > so may my RcppBDT which is sitting on top of Boost::DateTime code ...)
| >
| > Dirk
| >
|
#
format(ISOdate(2012,1:12,1),"%b-%Y")

[1] "Jan-2012" "Feb-2012" "Mar-2012" "Apr-2012" "May-2012" "Jun-2012"
[7] "Jul-2012" "Aug-2012" "Sep-2012" "Oct-2012" "Nov-2012" "Dec-2012"

First of the month is just as clean, and AFAIR they all have a first ;-)

Jeff
On Tue, Jan 31, 2012 at 2:37 PM, Dirk Eddelbuettel <edd at debian.org> wrote:

  
    
#
On 31 January 2012 at 15:28, Sarah Goslee wrote:
| As Duncan pointed out, this is documented in ?seq.POSIXt:
| 
|      Using ?"month"? first advances the month without changing the day:
|      if this results in an invalid day of the month, it is counted
|      forward into the next month: see the examples.
| 
| But ?seq.Date gives the impression that the construct Dirk and I tried
| should work:
| 
|      ## find all 7th of the month between two dates, the last being a 7th.
|      st <- as.Date("1998-12-17")
|      en <- as.Date("2000-1-7")
|      ll <- seq(en, st, by="-1 month")
|      rev(ll[ll > st & ll < en])
| 
| is given as an example, and it is not pointed out that this won't work for
| the 30th of the month. Normally one can extrapolate from patterns given
| in the examples, and here that isn't true. So perhaps the help should
| be modified slightly instead?

Yup, that would indeed help with this "infelicity".

Dirk