On 22 January 2021 at 21:35, Jens Heumann wrote: | Dear r-devel, | | Today I came across what I would call inconsistencies in the `c.Date` | method compared to what happens when concatenating other classes: 1. | Non-commutativity: The type in the arrangements of the elements does | matter (first element is critical), 2. the resulting value is numeric | instead of expected integer (as in the case with factors). | | > ## | Examples#################################################################### | > ## 1. Non-commutativity: | > c(.1, Sys.Date()) | [1] 0.1 18649.0 | > c(as.integer(.1), Sys.Date()) | [1] 0 18649 | > ## whereas: | > c(Sys.Date(), .1) | Error in as.Date.numeric(e) : 'origin' must be supplied | > c(Sys.Date(), as.integer(.1)) | Error in as.Date.numeric(e) : 'origin' must be supplied | > | > ## 2. Numeric instead of numeric value | > str(c(as.integer(.1), Sys.Date())) | num [1:2] 0 18649 ## not integer | > | ################################################################################ | | | I'm not sure if `c.Date` should redefined, since there would probably be | many more classes to consider. However, the error message "'origin' must | be supplied" cannot be served by the user and appears to me like an | imperfection in the design. | | It would be desirable if `c.Date` harmonizes with the hierarchy stated | in `?c`: "NULL < raw < logical < integer < double < complex < character | < list < expression. [...] factors are treated only via their internal | integer codes" and behaves best like a factor (and also throws integer | values as in 2. above). | | Or maybe disabling non-dates at all `if (!all(sapply(list(Sys.Date(), | .1), "class") == "Date")) stop...`, but this is a little beyond my | knowledge. | | Anyway, I hope my remark is of relevance and contributes to the | continuous development of our great programming language R!
Nice analysis, well done. Sadly it is also a "known feature" of the c() operator and documented as such -- S3 class attributes drop. C'est la vie. >From ?c ‘c’ is sometimes used for its side effect of removing attributes except names, for example to turn an array into a vector. ‘as.vector’ is a more intuitive way to do this, but also drops names. Note that methods other than the default are not required to do this (and they will almost certainly preserve a class attribute). I have into that trap approximately 4.56e8 times in this idiom > for (d in Sys.Date() + 0:2) print(d) [1] 18649 [1] 18650 [1] 18651 > Eventually one learns to switch to an iterator, and to pick the dates from a vector preserving their class. Dirk -- https://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel