From Bill.Venables at csiro.au  Sun May  1 04:28:11 2005
From: Bill.Venables at csiro.au (Bill.Venables@csiro.au)
Date: Sun May  1 04:28:24 2005
Subject: [Rd] RE: as.numeric method for objects of class "difftime"
Message-ID: <B998A44C8986644EA8029CFE6396A9241B32D6@exqld2-bne.qld.csiro.au>

I had a couple of private replies to the message below, all very
supportive of the idea.  I see that where I should have looked first is
at the function difftime, the constructor (which will hardly ever be
used except by people who know about its separate existence from
Ops.POSIXt).

Thus encouraged I formally propose that a method for as.numeric be
provided that will not break existing code, but will issue a warning if
people convert from difftime to numeric without specifying a time unit
to which the resulting numerical quantity will implicitly refer.

This is the simplest acceptable solution I could think of.  The code I
propose is as follows:

###
### S3 method for objects of class 'difftime'
###
as.double.difftime <- function(x, units = attr(x, "units"), ...) {
  if(missing(units)) {
    warning('No time units specified for conversion to numeric.\n"',
             units, '" has been assumed.')
    return(as.vector(x))
  }
  cfToSecs <- cumprod(c(secs = 1, mins = 60, hours = 60, days = 24,
weeks = 7))
  if(!is.element(units, names(cfToSecs)))
    stop("Unknown time units. Acceptable time units are\n\t",
         paste('"', names(cfToSecs), '", ', sep = "", collapse = ""),
         "only.")
  as.vector(x) * (cfToSecs[attr(x, "units")]/cfToSecs[units])
}
###
### End S3 method
###

Note that if people want to continue business as usual and the warning
irritates them, the simplest solution is to use as.vector instead of
as.numeric.  I think this is reasonable: to me as.vector implies simply
a change of structure to the object, whereas as.numeric implies a
conversion to a reasonably intuitive numerical object corresponding to
the original.

In retrospect the best thing to have done would have been not to make
"auto" the default units for difftime, but "secs" instead, but I think
that particular horse has bolted by now.

I would welcome further discussion.

Bill.

: -----Original Message-----
: From: Venables, Bill (CMIS, Cleveland) 
: Sent: Saturday, 30 April 2005 4:03 PM
: To: 'R-Devel (r-devel@stat.math.ethz.ch)'
: Subject: as.numeric method for objects of class "difftime"
: 
: 
: I have just become painfully aware that objects of class 
: "difftime", generated by the difference of two POSIXct 
: objects, carry a "units" attribute, which flashes by when the 
: object is printed, for example.
: 
: The pain was occasioned when I tried to turn these objects 
: into numberic objects for use elsewhere as a covariate.  
: 
: as.numeric(difftime object)
: 
: simply turns off the units attribute and provides a numeric 
: object which may represent a number of seconds or a number of 
: days, with no warning as to which.
: 
: I think this is an unfortunate situation, but I can't see how 
: to rectify it without breaking code that may rely on this 
: quirky feature.  My inclination is to suggest a method for 
: as.numeric (ie for as.double) that settles on a single unit, 
: which for consistency with as.numeric(POSIXct object) should 
: probably be seconds:
: 
: as.double.difftime <- function(x, ...)
:   if(attr(x, "units") == "days") as.vector(x) * 86400 else 
: as.vector(x)
: 
: but there must now be lots of code out there that has 
: blythely assumed that the difference will always be a number 
: of days and others assume it is always seconds.
: 
: At the very least I think the help information should carry a 
: big red warning about this rather unusual feature.  (It may, 
: I suppose, but I couldn't find it.)
: 
: Comments?
: 
: Bill Venables, 
: CMIS, CSIRO Laboratories, 
: PO Box 120, Cleveland, Qld. 4163
: AUSTRALIA
: Phone:  +61 7 3826 7251  
: Fax:    +61 7 3826 7304
: Mobile: +61 4 1963 4642
: Home:   +61 7 3286 7700
: mailto:Bill.Venables@csiro.au
: http://www.cmis.csiro.au/bill.venables/
: 
:


[Rd] RE: as.numeric method for objects of class "difftime"
Bill.Venables@csiro.au