Bill.Venables@csiro.au
2005-Apr-30 11:16 UTC
[Rd] 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/
M. Edward (Ed) Borasky
2005-Apr-30 19:05 UTC
[Rd] as.numeric method for objects of class "difftime"
Yes, this bit me just about a week ago. I subtracted the start time from the end time of a benchmark, and it came back with a duration in minutes, so I assumed it always yielded minutes and coded accordingly. If left to its own choices, a benchmark over an hour came back in hours, and one of the benchmarks ran three hours. So I had benchmark durations of 30, 30, 30, 30, 30, ... 3. The difftime function does have an optional argument to force the units to your choice, which in my case was seconds. I should have read the manual, discovered you could pick your units, and done so, which I did eventually. So I would definitely put a warning in the difftime documentation. The whole process only cost me an hour, though -- not a great loss of time. Well, maybe 3607 seconds ... <ducking> Bill.Venables@csiro.au wrote:>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/ > >______________________________________________ >R-devel@stat.math.ethz.ch mailing list >https://stat.ethz.ch/mailman/listinfo/r-devel > > >
Bill.Venables@csiro.au
2005-May-01 04:28 UTC
[Rd] RE: as.numeric method for objects of class "difftime"
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/ : :
Bill.Venables@csiro.au
2005-May-01 08:33 UTC
[Rd] RE: as.numeric method for objects of class "difftime"
Brian, : -----Original Message----- : From: Prof Brian Ripley [mailto:ripley@stats.ox.ac.uk] : Sent: Sunday, 1 May 2005 2:41 PM : To: Venables, Bill (CMIS, Cleveland) : Cc: r-devel@stat.math.ethz.ch : Subject: Re: [Rd] RE: as.numeric method for objects of class : "difftime" : : : I am very surprised that people would expect as.numeric to do : something : meaningful on time differences (or times, come to that). : Perhaps the best : thing is to stop it altogether. This would enforce one particular interpretation that may inhibit legitimate but unanticipated alternative uses. : : The selection of "auto" was the best for the original : purpose: people in : general do not want a difference of 3 days expressed in seconds. The : problems only arise if the result is unclassed, and I still do not : understand why that is a reasonable thing to do. No, they may not want the answer in seconds, but if they have a vector of time differences that includes zero they'll get them all in seconds anyway. Let me encapsulate my problem with an example. I want to use "elapsed time" as a predictor. I don't particularly care what units the time lag is in, so long as they are all in the _same_ units. What I don't like about the present default is this kind of possibility:> d <- as.POSIXct(paste(2005, 5, 1:3, sep="-")) > origin <- d[1]> as.numeric(d - origin)[1] 0 86400 172800> as.numeric(d[-1] - origin)[1] 1 2 Bill. : On Sun, 1 May 2005 Bill.Venables@csiro.au wrote: : : > 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/ : > : : > : : > : > ______________________________________________ : > R-devel@stat.math.ethz.ch mailing list : > https://stat.ethz.ch/mailman/listinfo/r-devel : > : > : : -- : Brian D. Ripley, ripley@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 :