[Rd] cdplot() with 'POSIXct' x

Sebastian P. Luque spluque at gmail.com
Thu May 13 20:37:12 CEST 2010


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.


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



More information about the R-devel mailing list