[Rd] cdplot() with 'POSIXct' x
Achim Zeileis
Achim.Zeileis at uibk.ac.at
Thu May 13 22:18:26 CEST 2010
On Thu, 13 May 2010, Sebastian P. Luque wrote:
> Hi,
>
> Given that cdplot() is used to produce the conditional density of a
> categorical y along a numerical x, it seems natural that it could be
> used with a date or time x (such as 'POSIXct'). Is this desirable? If
> so, I've created a patch that would allow this, by coercing the POSIXct
> x variable to produce the density, but use the original POSIXct x to
> draw the x axis.
I don't think we should special case "POSIXct". The general question would
be whether we allow "x" variables that can be coerced to numeric. The
approach would be:
- Omit all checking of the original "x".
- Compute
xorig <- x
x <- as.numeric(xorig)
and then proceed as before except for one change.
- For drawing the axis use
Axis(xorig, side = 1)
rather than axis(1).
This would work for POSIXct, Date, and other classes of the same type,
e.g., yearmon in package "zoo". Also, we could easily write time series
methods for cdplot() and spineplot() in package "zoo".
The downside is that there is no more checking of the "x" argument and
weird things could happen without a useful error message when users
specify awkward x arguments.
I played around with modified versions of cdplot() and also spineplot()
(where the new labeling is a bit more involved but based on the same
principles) and could supply code/docs for both.
So the question is whether the more flexible code with reduced checking is
suitable/acceptable for base R or not.
Best,
Z
>
> Index: src/library/graphics/R/cdplot.R
> ===================================================================
> --- src/library/graphics/R/cdplot.R (revision 51984)
> +++ src/library/graphics/R/cdplot.R (working copy)
> @@ -43,8 +43,8 @@
> if(!is.null(ylevels))
> y <- factor(y, levels = if(is.numeric(ylevels)) levels(y)[ylevels] else ylevels)
> x <- mf[,2]
> - if(!is.numeric(x))
> - stop("explanatory variable should be numeric")
> + if (!(is.numeric(x) || is(x, "POSIXct")))
> + stop("explanatory variable should be numeric or POSIXct")
>
> ## graphical parameters
> if(is.null(xlab)) xlab <- names(mf)[2L]
> @@ -66,7 +66,8 @@
> yaxlabels = NULL, xlim = NULL, ylim = c(0, 1), ...)
> {
> ## check x and y
> - if(!is.numeric(x)) stop("explanatory variable should be numeric")
> + if (!(is.numeric(x) || is(x, "POSIXct")))
> + stop("explanatory variable should be numeric or POSIXct")
> if(!is.factor(y)) stop("dependent variable should be a factor")
> if(!is.null(ylevels))
> y <- factor(y, levels = if(is.numeric(ylevels)) levels(y)[ylevels] else ylevels)
> @@ -79,10 +80,12 @@
> if(is.null(yaxlabels)) yaxlabels <- levels(y)
>
> ## unconditional density of x
> - dx <- if(is.null(from) & is.null(to))
> - stats::density(x, bw = bw, n = n, ...)
> - else
> - stats::density(x, bw = bw, from = from, to = to, n = n, ...)
> + xnum <- as.numeric(x)
> + dx <- if (is.null(from) & is.null(to)) {
> + stats::density(xnum, bw = bw, n = n, ...)
> + } else {
> + stats::density(xnum, bw = bw, from = from, to = to, n = n, ...)
> + }
> x1 <- dx$x
>
> ## setup conditional values
> @@ -94,7 +97,7 @@
> rval <- list()
>
> for(i in seq_len(ny-1L)) {
> - dxi <- stats::density(x[y %in% levels(y)[seq_len(i)]], bw = dx$bw, n = n,
> + dxi <- stats::density(xnum[y %in% levels(y)[seq_len(i)]], bw = dx$bw, n = n,
> from = min(dx$x), to = max(dx$x), ...)
> y1[i,] <- dxi$y/dx$y * yprop[i]
> rval[[i]] <- stats::approxfun(x1, y1[i,], rule = 2)
> @@ -103,8 +106,8 @@
>
> ## use known ranges
> y1 <- rbind(0, y1, 1)
> - y1 <- y1[,which(x1 >= min(x) & x1 <= max(x))]
> - x1 <- x1[x1 >= min(x) & x1 <= max(x)]
> + y1 <- y1[,which(x1 >= min(xnum) & x1 <= max(xnum))]
> + x1 <- x1[x1 >= min(xnum) & x1 <= max(xnum)]
>
> if(is.null(xlim)) xlim <- range(x1)
> if(any(ylim < 0) || any(ylim > 1)) {
> @@ -120,7 +123,9 @@
> for(i in seq_len(NROW(y1)-1))
> polygon(c(x1, rev(x1)), c(y1[i+1,], rev(y1[i,])), col = col[i],
> border = border)
> - axis(1)
> + if (is(x, "POSIXct")) {
> + axis.POSIXct(1, x)
> + } else axis(1)
>
> equidist <- any(diff(y1[,1L]) < tol.ylab)
> if(equidist)
>
>
> --
> Seb
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
More information about the R-devel
mailing list