Date Format
On Wed, 12 Jul 2006, Martyn Plummer wrote:
On Tue, 2006-07-11 at 20:05 +0200, Peter Dalgaard wrote:
Martyn Plummer <plummer at iarc.fr> writes:
I moved this to R-devel because I am wondering why the base package does
not allow you to convert from numeric to Date. Could we not have
something like this?
as.Date.numeric <- function(x, epoch="1970-01-01", ...) {
if (!is.character(epoch) || length(epoch) != 1)
stop("invalid epoch")
as.Date(epoch, ...) + x
}
We could, but you might as well do it explicitly. There's something to be said for not confusing the concept of dates with a particular implementation, which is effectively what happens if you can convert them to and from numeric too seamlessly.
Currently you can easily convert one way, but not the other. I just find that a bit odd. Pierre's problem was that his Date objects were converted internally by some function. His first instinct, to use as.Date to convert them back, was, I think, correct. But that doesn't work. So now we say "You have to understand how Date objects are implemented to get your dates back"? I don't know about that.
I agree with what we say: it was deliberate not to interpret plain numbers.
I'm more perplexed by the failure of adding difftimes to dates:
as.Date("2006-1-1") + (as.Date("2006-1-1") - as.Date("2006-1-2"))
[1] "2005-12-31"
Warning message:
Incompatible methods ("+.Date", "Ops.difftime") for "+"
and if you have a difftime in non-days units, you'll actually get a
wrong result:
D1 <- as.Date("2006-1-1")
D2 <- as.Date("2006-1-2")
difftime(D2,D1,units="hours")
Time difference of 24 hours
dd <- difftime(D2,D1,units="hours") D1+dd
[1] "2006-01-25"
Warning message:
Incompatible methods ("+.Date", "Ops.difftime") for "+"
[I raised this problem earlier in private discussions with Peter] It certainly is perplexing. There is code in "+.Date" that correctly handles the case where the second argument is a difftime. But it will never get called! I wonder if it ever worked.
Yes, it worked before Ops.difftime was added.
The warning is coming from DispatchGroup (in eval.c). When it finds different methods for two arguments of a binary group generic, it gives up and the default method is called - in this case R_binary in arithmetic.c - which is why the results depends on the implementation of the difftime object. I guessed that this was a limitation of S3 generics, and I suppose I was right. To allow mixing arguments of two classes, you would need code in Ops.foo to handle objects of class bar *and* vice versa. It's a bad idea to have two separate bits of code to do the same job, so I can't fault the logic of forbidding this, but it does leave us with some usability problems. While we are on the topic, is there no function to convert a difftime object from one time scale to another? I found a couple of private functions, but nothing public.
There is none: the intention is that the user should leave this to the functions he uses.
Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595