????? 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...?????? Can you provide an example? ????? 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. ????? 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. ????? 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? ????? Thanks again for the reply. ????? Spencer Graves> > B.
> > 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...? > Can you provide an example?------ #date and time objects x = Sys.Date () + 1:16 y = as.POSIXct (x) #matrices str (matrix (x, 4, 4) ) str (matrix (y, 4, 4) ) ------ Creating a matrix from a Date or POSIXct object, results in a numeric matrix, not a date/time matrix. I think that date/time matrices could be useful. It's possible that this has been discussed before. But if not, it may be good to discuss it. And returning to your original post... I re-read the documentation for the matplot function. And I feel that it's ambiguous. The description says: "Plot the columns of one matrix against the columns of another." i.e. The matplot function is for *matrices*. However, then it says: "x,y vectors or matrices of data for plotting. The number of rows should match." I'm guessing the current intention is that standard vectors (without a dim attribute) would be coerce-ible to single-column matrices, implying that using this function with date and time objects, is contrary to the way it's currently designed to work. But... After reading your examples and re-reading the documentation, your main suggestion that matplot should support Date and POSIXct objects, is still *probably* a good one. I note that function is not generic, and modifications to it would not necessarily be trivial.
Whether something "is" a matrix depends on whether you listen to is.matrix(x) or to inherits(x, "matrix"): x = Sys.Date () + 1:16 y = as.POSIXct (x) dim(y) = c(4,4) is.matrix(y) # [1] TRUE inherits(y, "matrix") # [1] FALSE f = factor(letters[1:9]) dim(f) = c(3,3) is.matrix(f) # [1] TRUE inherits(f, "matrix") # [1] FALSE I'm using (abusing?) this in the stars package, where it is convenient to have n-D arrays of type factor, Date or POSIXct, mostly because the [ method works: (f2 <- f[1:2,1:2]) # [,1] [,2] # [1,] a d # [2,] b e # Levels: a b c d e f g h i is.matrix(f2) # [1] TRUE On 1/28/20 9:09 AM, 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...? >> Can you provide an example? > > ------ > #date and time objects > x = Sys.Date () + 1:16 > y = as.POSIXct (x) > > #matrices > str (matrix (x, 4, 4) ) > str (matrix (y, 4, 4) ) > ------ > > Creating a matrix from a Date or POSIXct object, results in a numeric > matrix, not a date/time matrix. > > I think that date/time matrices could be useful. > It's possible that this has been discussed before. > But if not, it may be good to discuss it. > > And returning to your original post... > > I re-read the documentation for the matplot function. > And I feel that it's ambiguous. > > The description says: > "Plot the columns of one matrix against the columns of another." > i.e. The matplot function is for *matrices*. > > However, then it says: > "x,y vectors or matrices of data for plotting. The number of rows should match." > > I'm guessing the current intention is that standard vectors (without a > dim attribute) would be coerce-ible to single-column matrices, > implying that using this function with date and time objects, is > contrary to the way it's currently designed to work. > > But... > > After reading your examples and re-reading the documentation, your > main suggestion that matplot should support Date and POSIXct objects, > is still *probably* a good one. I note that function is not generic, > and modifications to it would not necessarily be trivial. > > ______________________________________________ > R-devel at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel >-- Edzer Pebesma Institute for Geoinformatics Heisenbergstrasse 2, 48151 Muenster, Germany Phone: +49 251 8333081
>>>>> 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.
On 2020-01-28 05:13, Martin Maechler wrote:>>>>>> Spencer Graves >>>>>> on Mon, 27 Jan 2020 23:02:28 -0600 writes:<snip>> > 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).????? 1.? What do you suggest I do to get acceptable copies of ~man/matplot.Rd and ~R/matplot.R -- and preferably the entire "graphics" package, so I can do R CMD build, check, etc., as I've done for 15 years or so with other R packages? ????? 2.? Then you'd like me to revise matplot.Rd to include appropriate examples that work fine with fda::matplot but malfunction with graphics::malfunction, then revise matplot.R so it fixed the problem?? And you want a fix that does NOT convert "matplot" to generic, and retains the current "as.numeric(x)" step except when inherits(x, "Date") or inherits(x, "POSIXct")? ????? 3.? Then you want me to submit a "wishlist" "bug" report to "https://bugs.r-project.org/bugzilla/index.cgi" including all changes to matplot.Rd and matplot.R?? If I don't convert "matplot" to generic, then there should be no need for changes to NAMESPACE, correct? ????? An answer to question "1" with "yes" to questions "2" and "3" should get me started. ????? Thanks, ????? Spencer Graves> > Best, > Martin > > > ????? Thanks again for the reply. > > ????? Spencer Graves > >> > >> B.