Bug 16940

Summary: diff(difftime.Object) loses the 'units' attribute.
Product: R Reporter: Bill Dunlap <wdunlap>
Component: MiscAssignee: R-core <R-core>
Status: ASSIGNED ---    
Severity: normal CC: maechler, swamykumar.melam
Priority: P5    
Version: R 3.3.*   
Hardware: Other   
OS: All   

Description Bill Dunlap 2016-06-08 21:31:12 UTC
When diff is applied to a difftime object its output is of class 'difftime' but it has no 'units' attribute, which difftime objects should have.  If I
use the '-' operator the units are there and I think diff ought to do the
same.

d <- as.POSIXct("2016-06-08 14:21", tz="US/Pacific") + as.difftime(2^(-2:8), units="mins")
str(d)
# POSIXct[1:11], format: "2016-06-08 14:21:15" "2016-06-08 14:21:30" ...
str(diff(d))
#Class 'difftime'  atomic [1:10] 15 30 60 120 240 480 960 1920 3840 7680
#  ..- attr(*, "units")= chr "secs"
str(diff(diff(d)))
#Class 'difftime'  num [1:9] 15 30 60 120 240 480 960 1920 3840

# Compare to '-' function:
mydiff <- function(x)x[-1] - x[-length(x)]
str(mydiff(diff(d)))
#Class 'difftime'  atomic [1:9] 15 30 60 120 240 480 960 1920 3840
#  ..- attr(*, "units")= chr "secs"

I ran into this while computing how rapidly the time of sunrise changed.

> sessionInfo()
R version 3.3.0 (2016-05-03)
Platform: x86_64-pc-linux-gnu (64-bit)
Running under: Ubuntu 14.04.4 LTS

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base
Comment 1 Martin Maechler 2016-06-09 16:25:59 UTC
Indeed, diff() currently uses diff.default() which works almost, via the correct '-' method.

A simple one line  diff.difftime   method seems to suffice:

diff.difftime <- function(x, ...) 
    structure(NextMethod("diff"), class = oldClass(x), units = attr(x, "units"))

actually .. because of  diff.default already "copies" the class, even

diff.difftime <- function(x, ...) 
    structure(NextMethod("diff"), units = attr(x, "units"))

... currently testing