[R] diff, POSIXct, POSIXlt, POSIXt

Martin Maechler maechler at stat.math.ethz.ch
Mon Jul 24 11:46:05 CEST 2006


>>>>> "Gabor" == Gabor Grothendieck <ggrothendieck at gmail.com>
>>>>>     on Sun, 23 Jul 2006 09:02:35 -0400 writes:

    Gabor> Moving this to r-devel.

[would have been a good idea ...  but you didn't;
 I think it's too late now; rather keep the msg thread together]

    Gabor> Looking at the diff.POSIXt
    Gabor> code we see the problem is that it takes the length
    Gabor> of the input using length which is wrong since in the
    Gabor> case of POSIXlt the length is always 9 (or maybe
    Gabor> length should be defined differently for POSIXlt?).

Though I agree with Spencer that a user may expect length() to behave
differently, but I don't think this would be a good idea.
Yes, length() is generic, but its help() emphasizes that for
lists, length() should be the number of list elements.
Of course anyone one *can* define  length() methods that behave
differently for his/her classes, but then one would also want to
make sure that e.g.  x[length(x)]  or  'x[length(x)] <- value'
works and -- in a case of simple S3 class built on a list, would
work differently than if x was a the simple list.

In my view, I would only consider redefing length() for "non-basic"
S4 classes, i.e. those with slots,  where no confusion is
possible, since these objects are definitely not simple vectors
nor lists (aka "generic" vectors).


    Gabor> Try this which gives the same problem:

    Gabor>    dts[-1] - dts[-length(dts)]

    Gabor> We get a more sensible answer if length is calculated
    Gabor> correctly:

    Gabor>   dts[-1] - dts[-length(dts[[1]])]

Yes, thanks Gabor, and thanks to Patrick who is right that this
is a bug and diff() should work for both kinds of POSIXt
objects. I'll fix this for both R-patched and R-devel
- but not via redefining  length(<POSIXlt>).

Martin Maechler, ETH Zurich



    Gabor> On 7/23/06, Patrick Giraudoux
    Gabor> <patrick.giraudoux at univ-fcomte.fr> wrote:
    >> > Try converting to POSIXct: That's what I did finally
    >> (see the previous e-mail).
    >> 
    >> dts<-c("15/4/2003","15/7/2003","15/10/2003","15/04/2004","15/07/2004","15/10/2004","15/4/2005","15/07/2005","15/10/2005","15/4/2006")
    >> 
    >> dts <- as.POSIXct(strptime(dts, "%d/%m/%Y")) diff(dts)
    >> 
    >> Time differences of 91, 92, 183, 91, 92, 182, 91, 92, 182
    >> days
    >> 
    >> > What is the problem you are trying to solve?  Actually,
    >> I don't understand why using diff() and POSIXct provides
    >> the expected result and not using POSIXlt. Both POSIXct
    >> and POSIXlt are of class POSIXt. The doc of diff()
    >> stresses that <'diff' is a generic function with a
    >> default method and ones for classes '"ts"', '"POSIXt"'
    >> and '"Date"'>. It does not mention differences between
    >> POSIXct and POSIXlt.
    >> 
    >> Moreover, using diff() with POSIXlt has provided (wrong)
    >> numbers... and not an error. This may be difficult to
    >> detect sometimes along programme lines. Must one keep in
    >> mind that diff() is reliably applicable only on POSIXct?
    >> In this case, should not it bve mentionned in the
    >> documentation?
    >> 
    >> All the best,
    >> 
    >> Patrick
    >> 
    >> 
    >> 
    >> 
    >> 
    >> 
    >> 
    >> jim holtman a écrit : > Try converting to POSIXct:
    >> >
    >> > > str(dts) > 'POSIXlt', format: chr [1:10] "2003-04-15"
    >> "2003-07-15" "2003-10-15" > "2004-04-15" "2004-07-15"
    >> "2004-10-15" "2005-04-15" ...  > > dts > [1] "2003-04-15"
    >> "2003-07-15" "2003-10-15" "2004-04-15" "2004-07-15" >
    >> "2004-10-15" "2005-04-15" "2005-07-15" > [9] "2005-10-15"
    >> "2006-04-15" > > dts <- as.POSIXct(dts) > > dts > [1]
    >> "2003-04-15 EDT" "2003-07-15 EDT" "2003-10-15 EDT"
    >> "2004-04-15 > EDT" "2004-07-15 EDT" "2004-10-15 EDT" >
    >> [7] "2005-04-15 EDT" "2005-07-15 EDT" "2005-10-15 EDT"
    >> "2006-04-15 EDT" > > diff(dts) > Time differences of 91,
    >> 92, 183, 91, 92, 182, 91, 92, 182 days
    >> > >
    >> >
    >> >
    >> >
    >> > On 7/23/06, *Patrick Giraudoux*
    >> <patrick.giraudoux at univ-fcomte.fr >
    >> <mailto:patrick.giraudoux at univ-fcomte.fr>> wrote:
    >> >
    >> > Dear Listers,
    >> >
    >> > I have encountered a strange problem using diff() and
    >> POSIXt:
    >> >
    >> >
    >> dts<-c("15/4/2003","15/7/2003","15/10/2003","15/04/2004","15/07/2004","15/10/2004","15/4/2005","15/07/2005","15/10/2005","15/4/2006")
    >> >
    >> > dts <- strptime(dts, "%d/%m/%Y") > class(dts)
    >> >
    >> > [1] "POSIXt" "POSIXlt"
    >> >
    >> > diff(dts)
    >> >
    >> > Time differences of 7862400, 7948800, 15811200,
    >> 7862400, 7948800, > 15724800, 7862400, 7948800, 0 secs
    >> >
    >> > In this case the result is not the one expected:
    >> expressed in seconds > and not in days, and the
    >> difference between the two last dates is > not 0.
    >> >
    >> > Now, if one use a vector of 9 dates only (whatever the
    >> date removed), > things come well:
    >> >
    >> > diff(dts[-1])
    >> >
    >> > Time differences of 92, 183, 91, 92, 182, 91, 92, 182
    >> days
    >> >
    >> > Also if one contrains dts to POSIXct
    >> >
    >> >
    >> dts<-c("15/4/2003","15/7/2003","15/10/2003","15/04/2004","15/07/2004","15/10/2004","15/4/2005","15/07/2005","15/10/2005","15/4/2006")
    >> >
    >> > dts <- as.POSIXct(strptime(dts, "%d/%m/%Y")) >
    >> diff(dts)
    >> >
    >> > Time differences of 91, 92, 183, 91, 92, 182, 91, 92,
    >> 182 days
    >> >
    >> > Any rational in that?
    >> >
    >> > Patrick



More information about the R-help mailing list