>>>>> Spencer Graves >>>>> on Mon, 27 Jan 2020 23:02:28 -0600 writes:
> Thanks for the reply. > On 2020-01-27 19:56, Abby Spurdle wrote: >> Maybe I'm missing something really obvious here, but I was unable to >> create a matrix out of POSIXct object(s). >> Perhaps that deserves a separate discussion...? yes, very much a separate discussion. Let's come back to Spencer's topic of matplot() : [....] > The standard matplot application that concerns me is with > matplot(x, y, ...) where x has class Date or POSIXct and y is a matrix. > The "fda" package on CRAN includes a "matplot" help page with examples > that worked when I tested them recently. Indeed. That's how I understood you well. matplot() has been one of my favorite plotting functions in S and Splus in the 1990s ... and that's why the R source code of matplot(), matpoints(), and matlines() still has a comment mentioning that I wrote (the first version of) it for R on June 27, 1997. By design (from S), matplot() {etc} has always been thought as a convenience wrapper to calling plot() and lines(), lines(), lines() or plot() and points(), points(), points() {plot() : for setting up coord.system, draw axes, titles, ...}, -- notably also for adhering to the DRY (instead of WET) programming principle (-> "Don't Repeat Yourself") -- *and* -- be assured -- more than 99% of its use has been for the special case where x has been a numeric vector and y a matrix with several columns and indeed, the following part from the beginning of matplot()'s source code has basically already been in the version from 1997 and is all about having it work for vectors treated as 1-column matrices : ------------------------------------------------------------------------ if(missing(x)) { if(missing(y)) stop("must specify at least one of 'x' and 'y'") else x <- seq_len(NROW(y)) } else if(missing(y)) { y <- x; ylabel <- xlabel x <- seq_len(NROW(y)); xlabel <- "" } kx <- ncol(x <- as.matrix(x)) ky <- ncol(y <- as.matrix(y)) n <- nrow(x) if(n != nrow(y)) stop("'x' and 'y' must have same number of rows") if(kx > 1L && ky > 1L && kx != ky) stop("'x' and 'y' must have only 1 or the same number of columns") if(kx == 1L) x <- matrix(x, nrow = n, ncol = ky) if(ky == 1L) y <- matrix(y, nrow = n, ncol = kx) k <- max(kx, ky) ## k == kx == ky ------------------------------------------------------------------------ > If you have an example that you think should work but doesn't I'd > like to know. Maybe it should be added to the examples in > fda::matplot.Rd file, then the code should be modified until it works. >> >> Regarding your other comments/questions: >> (1) You should *NOT* mask functions from the graphics package (or >> base, stats, etc), except possibly for personal use. >> (2) The xlab and ylab are fine. > In most situations, I agree with your comment that, "You should > *NOT* mask functions from the graphics package (or base, stats, etc)". > However, when the behavior of the function in graphics, base, or > stats seems patently inappropriate and not adequately considered, then I > think that someone should mask the function in the core distribution > with one whose behavior seems more consistent with what most users would > most likely want. > Ten or twelve years ago, I concluded that the behavior of > graphics::matplot(x, y, ...) was inappropriate when x is either of class > Date or POSIXct. Specifically, it labeled the horizontal axis the same > as graphics::matplot(as.numeric(x), y, ...). I think it should instead > be labeled the same as graphics::plot(x, y[,1], ...) in such cases. To > fix this problem, I made fda::matplot generic; graphics::matplot is not > generic. And a coded methods for x of class numeric, matrix, Date and > POSIXct plus a default. Each calls either graphics::matplot or matlines > as appropriate after first setting up the horizontal axis properly if x > is of class Date or POSIXct. I pretty much agree with your judgement here, Spencer. What you say (and I assume your fda::matplot() does) is still implementing the original basic idea of being a convenience wrapper for a call to plot() and typically several calls to lines() or points()... and indeed in R {graphics}, plot(), lines() and points() all have been S3 generics for a long time and so it seems naturaly that a wrapper to these functions should also dispatch correctly ... possibly *not* by becoming S3 generic itself, but just, conceptually, by ensuring *not* to change the S3 class of 'x' before calling plot(), points() and lines() .... > For specific examples, consider the following taken from > fda::matplot.Rd: > invasion1 <- as.Date('1775-09-04') > invasion2 <- as.Date('1812-07-12') > earlyUS.Canada <- c(invasion1, invasion2) > Y <- matrix(1:4, 2, 2) > graphics::matplot(earlyUS.Canada, Y) > # horizontal axis labeled per as.numeric(earlyUS.Canada), > # NOT as Dates > fda::matplot(earlyUS.Canada, Y) > # problem fixed. > # POSIXct > AmRev.ct <- as.POSIXct1970(c('1776-07-04', '1789-04-30')) > graphics::matplot(AmRev.ct, Y) > # horizontal axis labeled per as.numeric(AmRev.ct), > # NOT as POSIXct > fda::matplot(AmRev.ct, Y) > # problem fixed. > Comments? first parts: see above; from there I hope it's already clear that I am sympathetic to your proposal, ... but (there's alway a "but", ..) Still, as Abby mentioned, turning a simple function into the default method of an S3 generic is easy to do, but comes with a bit of cost, not just S3 dispatch which typically is negligable in graphics, but a bit of maintenance cost and mostly in this case the cost of breaking back compatibility by the improvement. How many plots will change where people have already relied on the current as.numeric(x) behavior? If we'd change this in R's graphics, it will be - me and/or the CRAN team who have to contact CRAN package maintainer about problems (maybe none, as the change may not break any checks) - Users of matplot() {& matlines() & matpoints()} who may have to adopt their calls to these functions {I'm pretty sure all three would have to change for consistency}. ----- and then, there are quite a few other changes, bug assignments to which I have committed which should be dealt with rather before this. If you'd turn this into a proper "wishlist" "bug" report on R's bugzilla, *and* you or another volunteer provided a patch to the R sources (including changes to man/*.Rd, NAMESPACE, ..) which then can be tested to pass 'make check-all', then I'd definitely commit to this (possibly too late for R 4.0.0; teaching starts here soon, etc). Best, Martin > Thanks again for the reply. > Spencer Graves >> >> B. ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel