>>>>> Spencer Graves
>>>>> on Tue, 28 Jan 2020 17:24:14 -0600 writes:
> 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?
Getting the full source of R, either
1) from svn.r-project.org :
svn checkout https://svn.r-project.org/R/trunk R-devel
where the R source is maintained, or more easily if you have never
worked with 'svn'
2) if you know git well, you can use the github *mirror* of svn.r-project.org,
at https://github.com/wch/r-source/
3) most easily for most : as tarball from CRAN
wget https://cloud.r-project.org/src/base-prerelease/R-devel.tar.gz
tar xf R-devel.tar.gz
cd R-devel
ls -lt src/library/graphics/{R,man}/matplot*
> 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")?
well... this would be for you or anybody else who'd like to help
the R project advance here.
HOWEVER, see below ..
> 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?
that's correct.
However: Thanks to the R-devel conversation with you, my
thoughts have continued after writing my previous
e-mail, and I've started to look into the source,
i.e., matplot.R,
*and* worked out the solution myself: It now looks as I've been
able to change matplot() such that it typically does *not* use
matrix() nor as.matrix() for input 'x' of class "Date" or
"POSIXct" (or many similar S3 objects x) but rather uses the
dim(x) <- c(n, m)
trick to turn x into a matrix .. which BTW does work for fine to
turn "Date" or "POSIXct" into matrices though you do *not* notice
that (!!) from print()ing them nor from str(.) --- the latter IMO
a buglet in the corresponding str() method).
I've spent some time to ensure matplot(x) continues to work when
'x' is a numeric data frame or a Matrix-package sparse matrix, etc,
I've run checks and will do some more but plan to commit this
version of matplot() to R-devel within a few days,
so there's no need for now for anybody else to work on this.
Martin
> An answer to question "1" with "yes" to questions "2" and "3"
> should get me started.
which for now should not be necessary:
I attach a cut'n'paste version of my new (not yet committed)
version of matplot() for you to test (file name 'matplot-1.R')
Best, Martin
matplot <- function(x, y, type = "p",
lty = 1:5, lwd = 1, lend = par("lend"),
pch = NULL, col = 1:6, cex = NULL, bg = NA,
xlab = NULL, ylab = NULL, xlim = NULL, ylim = NULL,
log = "",
..., add = FALSE, verbose = getOption("verbose"))
{
paste.ch <- function(chv) paste0('"',chv,'"', collapse=" ")
str2vec <- function(string) {
if(nchar(string, type="c")[1L] > 1L) strsplit(string[1L], NULL)[[1L]]
else string
}
## These from plot.default :
xlabel <- if (!missing(x)) deparse1(substitute(x))# else NULL
ylabel <- if (!missing(y)) deparse1(substitute(y))
##
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 <- ""
}
## To preserve class, typically don't use as.matrix() or matrix() but only
`dim<-`:
if(is.matrix(x)) {
n <- nrow(x)
} else if(!is.null(dim(x))) { # matrix-like: data.frame, sparseMatrix, ..
n <- nrow(x <- as.matrix(x))
} else {
n <- length(x)
dim(x) <- c(n, 1L)
}
if(is.matrix(y)) {
## nothing
} else if(!is.null(dim(y))) { # matrix-like
y <- as.matrix(y)
} else {
dim(y) <- c(length(y), 1L)
}
if(n != nrow(y)) stop("'x' and 'y' must have same number of rows")
kx <- ncol(x)
ky <- ncol(y)
if(kx != 1L && ky != 1L && kx != ky)
stop("'x' and 'y' must have only 1 or the same number of columns")
k <- max(kx, ky)
type <- str2vec(type)
if(is.null(pch)) {
pch <- c(1L:9L, 0L, letters, LETTERS)
if(k > length(pch) && any(type %in% c("p","o","b")))
warning("default 'pch' is smaller than number of columns and hence
recycled")
} else if(is.character(pch)) pch <- str2vec(pch)
## else pch is numeric supposedly
if(verbose)
message("matplot: doing ", k, " plots with ",
paste0(" col= (", paste.ch(col), ")"),
paste0(" pch= (", paste.ch(pch), ")"),
" ...\n", domain=NA)
xy <- xy.coords(x, y, xlabel, ylabel, log = log, recycle=TRUE) # recycle if
kx or ky is 1
if(is.null(xlab)) xlab <- xy$xlab
if(is.null(ylab)) ylab <- xy$ylab
if(is.null(xlim)) xlim <- range(xy$x[is.finite(xy$x)])
if(is.null(ylim)) ylim <- range(xy$y[is.finite(xy$y)])
if(length(type)< k) type <- rep_len(type,k)
if(length(lty) < k) lty <- rep_len(lty, k)
if(length(lend)< k) lend <- rep_len(lend,k)
## sciplot passes NULL
if(length(lwd) < k && !is.null(lwd)) lwd <- rep_len(lwd, k)
if(length(pch) < k) pch <- rep_len(pch, k)
if(length(col) < k) col <- rep_len(col, k)
if(length(bg) < k) bg <- rep_len(bg, k)
## should not be able to call rep() on NULL
if(is.null(cex)) cex <- 1
if(length(cex) < k) cex <- rep_len(cex, k)
ii <- seq_len(k)
dev.hold(); on.exit(dev.flush())
if(!add) {
ii <- ii[-1L]
plot(x[, 1L],y[, 1L], type = type[1L], xlab = xlab, ylab = ylab,
xlim = xlim, ylim = ylim, lty = lty[1L], lwd = lwd[1L],
lend = lend[1L], pch = pch[1L], col = col[1L], cex = cex[1L],
bg = bg[1L], log = log, ...)
}
for (i in ii)
lines(x[, 1L + (i-1L) %% kx], y[, 1L + (i-1L) %% ky],
type = type[i], lty = lty[i], lwd = lwd[i],
lend = lend[i], pch = pch[i], col = col[i], cex = cex[i],
bg = bg[i])
invisible()
}
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel