Bug 17387 - missing `length<-` methods for Date, POSIXct, POSIXlt
Summary: missing `length<-` methods for Date, POSIXct, POSIXlt
Status: CLOSED FIXED
Alias: None
Product: R
Classification: Unclassified
Component: Misc (show other bugs)
Version: R 3.4.3
Hardware: All All
: P5 minor
Assignee: R-core
URL:
Depends on:
Blocks:
 
Reported: 2018-03-04 16:23 UTC by Patrick Perry
Modified: 2018-03-26 16:11 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Patrick Perry 2018-03-04 16:23:39 UTC
> (x <- Sys.Date())
[1] "2018-03-04"
> length(x) <- 5
> x
[1] 17594    NA    NA    NA    NA


> (y <- Sys.time())
[1] "2018-03-04 11:13:51 EST"
> length(y) <- 5
> y
[1] 1520180032         NA         NA         NA         NA


> (z <- as.POSIXlt(Sys.time()))
[1] "2018-03-04 11:14:25 EST"
> length(z) <- 5
> z
$sec
[1] 25.20675

$min
[1] 14

$hour
[1] 11

$mday
[1] 4

$mon
[1] 2


Expected behavior in all three cases is to append `NA` and keep the class of the argument.

--

> sessionInfo()
R Under development (unstable) (2018-03-02 r74345)
Platform: x86_64-apple-darwin17.4.0 (64-bit)
Running under: macOS High Sierra 10.13.3

Matrix products: default
BLAS: /Users/ptrck/Code/r-source/lib/libRblas.dylib
LAPACK: /Users/ptrck/Code/r-source/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

loaded via a namespace (and not attached):
[1] compiler_3.5.0
Comment 1 Martin Maechler 2018-03-21 20:48:01 UTC
One option which would solve 2 of the 3 cases, namely "Date" and "POSIXct",
would be to slightly change the semantic of the internal default method:

It is documented to only preserve 'names' and drop all other attributes, which of course includes 'class'.
It could be changed for atomic vectors (not for list-alikes!) to also keep "class",... something which seems desirable to me for objects that are "basically" an atomic vector plus a class.

Note that the only `length<-` method in the standard R packages is `length<-.factor`   which needs fiddle with both 'levels' and 'class'.

My current proposal to fulfill your wish:

1) write a POSIXlt method for length<- 
   ... I've already done that (not yet committed)

2) Change the C code such that the C "default" method for atomic vectors
   also preserves the "class"
   ==> The   "Date"  and "POSIXct"  cases work automagically.

Martin
Comment 2 Patrick Perry 2018-03-21 21:01:08 UTC
Thanks for taking this up.


I'm not convinced that changing the default behavior for `length<-` is a good idea. Your proposal has reasonable behavior for `Data` and `POSIXct` classes, but it seems dangerous to assume that your default behavior will always result in a well-formed object (according to its `class` attribute).


Here's an example where I'd argue that the current behavior is better than your proposed change:

x <- mtcars
length(x) <- 20

It makes more sense to me that `x` is a `list` after this operation, not a `data.frame`.


Further, it seems desirable for the following two sequences of operations to be equivalent with the default implementations:

x <- structure(1:10, class = "foo")
y1 <- x[1:5]

y2 <- x
length(y2) <- 5

In your proposal, `y1` would not have a class attribute, but `y2` would.
Comment 3 Martin Maechler 2018-03-21 22:04:32 UTC
(In reply to Patrick Perry from comment #2)
> Thanks for taking this up.
> 
> 
> I'm not convinced that changing the default behavior for `length<-` is a
> good idea. Your proposal has reasonable behavior for `Data` and `POSIXct`
> classes, but it seems dangerous to assume that your default behavior will
> always result in a well-formed object (according to its `class` attribute).
> 
> 
> Here's an example where I'd argue that the current behavior is better than
> your proposed change:
> 
> x <- mtcars
> length(x) <- 20
> 
> It makes more sense to me that `x` is a `list` after this operation, not a
> `data.frame`.

Yes,... that's why I said  for *atomic* vectors and emphasized *not* for list..  (did you really read what I wrote ?)

> 
> 
> Further, it seems desirable for the following two sequences of operations to
> be equivalent with the default implementations:
> 
> x <- structure(1:10, class = "foo")
> y1 <- x[1:5]
> 
> y2 <- x
> length(y2) <- 5
> 
> In your proposal, `y1` would not have a class attribute, but `y2` would.

This is a much better argument against changing, indeed!

length(.) <- k   *should* be compatible i.e., equivalent to subsetting / indexing with `[1:k]`

Martin
Comment 4 Martin Maechler 2018-03-26 16:11:43 UTC
This is in R-devel  and  R 3.5.0 alpha now.