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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to