10

I'm getting unexpected output from the all.equal method in R, specifically the implementation for POSIXct, all.equal.POSIXct.

t <- Sys.time()
isTRUE(all.equal(t, t+1))

returns TRUE, and

isTRUE(all.equal(t, t+1, scale = 1))

returns FALSE.

However, if you look at the definition of all.equal.POSIXct, you can see that the scale parameter has a default of 1:

> all.equal.POSIXct
function (target, current, ..., scale = 1) 
{
    check_tzones(target, current)
    NextMethod("all.equal")
}
<bytecode: 0x22eac90>
<environment: namespace:base>

You get the same results if you explicitly call all.equal.POSIXct instead of all.equal.

Why isn't the default parameter scale = 1 being picked up in the first call to all.equal.POSIXct? Am I doing something wrong, or have I fundamentally misunderstood something, or is this a bug?

Thanks in advance for any help.

Ash
  • 237
  • 2
  • 11
  • This is a great question. Both answers below suggest it might be a bug, so I have filed a bug report at https://bugs.r-project.org/bugzilla3/show_bug.cgi?id=14969 – Andrie Jul 02 '12 at 13:26
  • Cool, thanks for submitting the bug report! I was just about to do the same! – Ash Jul 02 '12 at 13:52

2 Answers2

8

I'm going out on a slight limb here, but I think you have discovered a bug.

Here is my suggested fix:

all.equal.POSIXct <- function (target, current, ..., scale = 1) {
  check_tzones(target, current)
  NextMethod("all.equal", scale=scale, ...)
}

Then the function gives the correct results:

all.equal(t, t+1)
[1] "Mean scaled difference: 1"

all.equal(t, t+1, scale=10)
[1] "Mean scaled difference: 0.1"

This is why the existing code doesn't work:

The definition for all.equal is:

all.equal <- function (target, current, ...) UseMethod("all.equal")
  • Notice that there are three arguments: target, current and ....

  • Thus, whenever you use NextMethod these three arguments will be passed to the next method.

  • However, in the case of all.equal.POSIXct there is an additional argument scale=, but this doesn't get passed on either implicitly or explicitly.

Andrie
  • 176,377
  • 47
  • 447
  • 496
7

Looks like a bug. I'm not an expert on method dispatch, but a quick reading of ?NextMethod suggests scale=scale needs to be added to the NextMethod call in all.equal.POSIXct:

all.equal.POSIXct <-
function (target, current, ..., scale = 1) 
{
    check_tzones(target, current)
    NextMethod("all.equal", scale=scale)
}
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418