I wrote the date package long ago, and it has been useful. In my current task of reunifying the R (Tom Lumley) and Splus (me) code trees for survival, I'm removing the explicit dependence on 'date' objects from the expected survival routines so that they better integrate. Comparison of 'date' to 'Date' has raised a couple of questions. Clearly Date is more mature -- more options for conversion, better plotting, etc (a long list of etc). I see three things where date is better. Only the last of these really matters, and is the point on which I would like comment. (Well, actually I'd like to talk you all into a change, of course). 1. Since date uses 1/1/1960 as the base, and so does SAS, those of us who contantly pass files back and forth between those two packages have a slightly easier time. 2. as.date(10) works, as.Date(10) does not. Sometimes I have done a manipluation that the date package does not understand, and I know that the result is still of the right type, but the package does not. However, this is fairly rare and I can work around it. (It mostly occurs in processing the rate tables for expected survival). 3. temp <- as.Date('1990/1/1') - as.date('1953/2/5') sqrt(temp) Error in Math.difftime(temp3) : sqrtnot defined for "difftime" objects Minor bug: no space before the word 'not' Major: this shouldn't fail. People will do things with time intervals that you have not thought of. Fitting a growth curve that uses a square root, for instance. I firmly believe that the superior behavior in the face of something unexpected is to assume that the user knows what they are doing, and return a numeric. I recognize that "assume the user knows what they are doing" is an anathema to the more zealous OO types, but in designing a class I have found that they often know more than me! 4. Variation on #3 above> (as.Date('2007-9-14') - as.Date('1953-3-10')) / 365.25Time difference of 54.51335 days No, I am not 54.5 days old. Both hair color and knee creaking most definitely proclaim otherwise, I am sorry to say. Time difference / number should be a number. 5. This is only amusing. Im not saying that as.Date should necessarily work, but the format is certainly not ambiguous. (Not standard, but not ambiguous). Not important to fix, not something that date does any better.> as.Date('09Sep2007')Error in fromchar(x) : character string is not in a standard unambiguous format Terry Therneau
Terry Therneau wrote:> I wrote the date package long ago, and it has been useful. In my current task > of reunifying the R (Tom Lumley) and Splus (me) code trees for survival, I'm > removing the explicit dependence on 'date' objects from the expected survival > routines so that they better integrate. Comparison of 'date' to 'Date' has > raised a couple of questions. > > Clearly Date is more mature -- more options for conversion, better plotting, > etc (a long list of etc). I see three things where date is better. Only the > last of these really matters, and is the point on which I would like comment. > (Well, actually I'd like to talk you all into a change, of course). > > 1. Since date uses 1/1/1960 as the base, and so does SAS, those of us who > contantly pass files back and forth between those two packages have a slightly > easier time. > > 2. as.date(10) works, as.Date(10) does not. Sometimes I have done a > manipluation that the date package does not understand, and I know that the > result is still of the right type, but the package does not. However, this is > fairly rare and I can work around it. (It mostly occurs in processing the rate > tables for expected survival). >The ideology here is that the origin is an implementation detail which users are not really expected to know. as.Date("1960-1-1")+10 works, and if you insist, so does structure(10, class="Date") (albeit not with the same result).> > 3. temp <- as.Date('1990/1/1') - as.date('1953/2/5') > sqrt(temp) > Error in Math.difftime(temp3) : sqrtnot defined for "difftime" objects > > Minor bug: no space before the word 'not' > Major: this shouldn't fail. > >Arguably, it should (Is this a difftime object? Which units?). I'd advise against numeric operation on difftime objects in general, because of the unspecified units. These are always "days" when working with Date objects, but with general time objects it is not predictable. So I'd recommend sqrt(as.numeric(temp, units="days")).> People will do things with time intervals that you have not thought of. Fitting > a growth curve that uses a square root, for instance. I firmly believe that the > superior behavior in the face of something unexpected is to assume that the user > knows what they are doing, and return a numeric. > I recognize that "assume the user knows what they are doing" is an anathema > to the more zealous OO types, but in designing a class I have found that they > often know more than me! > > 4. Variation on #3 above > > >> (as.Date('2007-9-14') - as.Date('1953-3-10')) / 365.25 >> > Time difference of 54.51335 days > > No, I am not 54.5 days old. Both hair color and knee creaking most > definitely proclaim otherwise, I am sorry to say. Time difference / number > should be a number. >Same story as above. It is assumed that the divisor is unit-less. Convert to numeric first to avoid this. (The idea has been raised to introduce new units: epiyears and epimonths, in which case you might do x <- as.Date('2007-9-14') - as.Date('1953-3-10') units(x) <- "epiyears" which would give you the age in years for those purposes where you don't care missing the exact birthday by a day or so.)> > 5. This is only amusing. Im not saying that as.Date should necessarily work, > but the format is certainly not ambiguous. (Not standard, but not ambiguous). > Not important to fix, not something that date does any better. > > >> as.Date('09Sep2007') >> > Error in fromchar(x) : character string is not in a standard unambiguous format > > >Yes. Also: this _is_ ambiguous, but does not cause an error > as.Date("05-06-07") [1] "5-06-07" Not that it should or even could, but it demonstrates that the error message above is beside the point. Can you suggest a better wording? -- O__ ---- Peter Dalgaard ?ster Farimagsgade 5, Entr.B c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K (*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918 ~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk) FAX: (+45) 35327907
On 9/14/07, Terry Therneau <therneau at mayo.edu> wrote:> I wrote the date package long ago, and it has been useful. In my current task > of reunifying the R (Tom Lumley) and Splus (me) code trees for survival, I'm > removing the explicit dependence on 'date' objects from the expected survival > routines so that they better integrate. Comparison of 'date' to 'Date' has > raised a couple of questions. > > Clearly Date is more mature -- more options for conversion, better plotting, > etc (a long list of etc). I see three things where date is better. Only the > last of these really matters, and is the point on which I would like comment. > (Well, actually I'd like to talk you all into a change, of course). > > 1. Since date uses 1/1/1960 as the base, and so does SAS, those of us who > contantly pass files back and forth between those two packages have a slightly > easier time.There are some other programs that use 1/1/70. See the R Help Desk article in R News 4/1 that discusses a few origins.> > 2. as.date(10) works, as.Date(10) does not. Sometimes I have done a > manipluation that the date package does not understand, and I know that the > result is still of the right type, but the package does not. However, this is > fairly rare and I can work around it. (It mostly occurs in processing the rate > tables for expected survival).You can define as.Date.numeric in your package and then it will work. zoo has done that. library(zoo) as.Date(10) Some other things you can do: today <- Sys.Date() Epoch <- today - as.numeric(today) Epoch + 10 # similar to as.Date(10)> > 3. temp <- as.Date('1990/1/1') - as.date('1953/2/5') > sqrt(temp) > Error in Math.difftime(temp3) : sqrtnot defined for "difftime" objects > > Minor bug: no space before the word 'not' > Major: this shouldn't fail. > > People will do things with time intervals that you have not thought of. Fitting > a growth curve that uses a square root, for instance. I firmly believe that the > superior behavior in the face of something unexpected is to assume that the user > knows what they are doing, and return a numeric. > I recognize that "assume the user knows what they are doing" is an anathema > to the more zealous OO types, but in designing a class I have found that they > often know more than me! > > 4. Variation on #3 above > > > (as.Date('2007-9-14') - as.Date('1953-3-10')) / 365.25 > Time difference of 54.51335 days > > No, I am not 54.5 days old. Both hair color and knee creaking most > definitely proclaim otherwise, I am sorry to say. Time difference / number > should be a number.Note that you can write: x <- Sys.Date() y <- x + 1 as.numeric(x-y) as.numeric(x) - as.numeric(y)> > 5. This is only amusing. Im not saying that as.Date should necessarily work, > but the format is certainly not ambiguous. (Not standard, but not ambiguous). > Not important to fix, not something that date does any better. > > > as.Date('09Sep2007') > Error in fromchar(x) : character string is not in a standard unambiguous formatas.Date("09Sep2007", "%d%b%Y")> > > > Terry Therneau