Skip to content

Weird issue when iterating through dates

9 messages · Gábor Csárdi, Luca Cerone, William Dunlap +2 more

#
Dear all,
I am experiencing a weird issue when iterating through dates in R
(3.1.2 and 3.2.1 on 64bit linux machines)

I am bit surprised about the behaviour of this snippet of code:

d1 <- as.Date('2015-01-01')
d2 <- as.Date('2015-01-31')

for ( dt in seq(d1,d2, by=1) ) {
  dt <- as.character(dt)
  print(dt)
}

for ( dt in as.character(seq(d1,d2, by=1)) ) {
  print(dt)
}

I can't find a good explanation why the first for loop would convert
to string the numeric interpretation
of the dates while the second one correctly (at least in my
intentions) prints the dates as string.

I am sure that it is not a bug in R but I would like to understand why
I am getting different outputs from the two for loops.

Thanks a lot in advance for your help!

Cheers,
Luca
#
Date has a `[.Date` method and also `[[.Date`, but it looks like a for
loop does not consider the class of the object you are iterating over,
so these are ignored and the internal representation is used.

I think this is a bug, at least in the documentation of ?"for".

Interestingly, lapply and co. do consider the class:

invisible(lapply(seq(d1, d2, by = 1), print))

works as you would expect. (The invisible() is to suppress printing
the return value.)

Gabor
On Thu, Aug 6, 2015 at 3:24 AM, Luca Cerone <luca.cerone at gmail.com> wrote:
#
Thanks G?bor,
I thought there was some mistake in my logic on how casting works in R
and wanted to be sure.

Just a quick question: what's the difference between  `[.Date` and  `[[.Date`?
Is it supposed to be the method for accessing the value right?

Thanks again for your help,
Cheers,
Luca
On Thu, Aug 6, 2015 at 10:10 AM, G?bor Cs?rdi <csardi.gabor at gmail.com> wrote:
#
On Thu, Aug 6, 2015 at 6:30 AM, Luca Cerone <luca.cerone at gmail.com> wrote:
[...]
For Dates and atomic vectors in general they are the same, but in
general they are two different operators that behave differently on
some data types. E.g. on lists [ selects a sub-list and [[ selects a
single element.

Gabor

[...]
#
`[[.Date`?
Even for atomic vectors with names they are not quite the same
    > c(One=1, Two=2)[[2]]
    [1] 2
    > c(One=1, Two=2)[2]
    Two
      2
(and [[ will only return 1 item, unlike [).


Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Thu, Aug 6, 2015 at 5:36 AM, G?bor Cs?rdi <csardi.gabor at gmail.com> wrote:

            

  
  
6 days later
#
Following up on this, should I report a bug? can you drive me through
the process?

Cheers,
Luca
On Thu, Aug 6, 2015 at 4:55 PM, William Dunlap <wdunlap at tibco.com> wrote:
#
I am not sure if this is a bug or not.

Gabor
On Wed, Aug 12, 2015 at 11:51 AM, Luca Cerone <luca.cerone at gmail.com> wrote:
#
On Wed, Aug 12, 2015 at 10:55 AM, G?bor Cs?rdi <csardi.gabor at gmail.com> wrote:
I would argue that this isn't a bug, not even in the documentation of
"for" (even though it might be clearer).  ?"for" says that `seq` is
"[A]n expression evaluating to a vector (including a list and an
expression) or to a pairlist or 'NULL'".  Date objects aren't strictly
vectors, so they're treated as integer/numeric.

This answer on StackOverflow said that "for" does not copy any of the
iterators attributes (including class), which causes this behavior.
http://stackoverflow.com/a/23278464/271616

To respond to the original question regarding why the code below,
"prints the dates as a string".  Quite simply, you convert seq(d1,d2,
by=1) to character, so it's no longer a Date.  The fact that
Sys.Date() and as.character(Sys.Date()) both *print* the same thing
does not mean they are the same.

for ( dt in as.character(seq(d1,d2, by=1)) ) {
  print(dt)
}

Best,
Josh

  
    
#
(Resend: was meant for R-devel, not just Joshua)
Thank you, Joshua.  Definitely no bug ... 
but possibly something where the documentation (== the help
page, not Google, not Stackoverflow, ... ;-\ ) can be improved.

Indeed, one could add  what  
	``evaluating to a vector''
means; 
I don't have time now, but am almost sure that we could state that

      for(n in obj) { ... }

should be semantically equivalent to

      for(n in as.vector(obj)) { ... }

but there may be subtleties here....
--> posting back to R-devel  so people can experiment if the
above is true, and if not *where*.

Martin