[R] Re: Dotplot with nested factors

Deepayan Sarkar deepayan at stat.wisc.edu
Tue Aug 17 01:54:44 CEST 2004

On Monday 16 August 2004 17:06, Raubertas, Richard wrote:
> I am using the dotplot function from the lattice package to
> display a quantitative variable versus two factors, say 'a' and
> 'b'.  The levels of 'a' are nested within levels of 'b'.  The
> issue is that dotplot includes all the levels of 'a' in each panel
> (conditioning on 'b'), even though many are empty in any given
> panel.  A toy example is
> dat <- data.frame(a=letters[1:5], b=c("A","A","A","B","B"), y=1:5)
> dotplot(y ~ a | b, data=dat)
> (In the real data, there are far more levels of 'a' and 'b', so each
> panel ends up with all its data squashed into a small portion of
> the available space.)
> I would like to show only the levels of 'a' actually present
> in a given panel.  I hoped that setting 'relation="free"' would
> cause each panel to adjust its axis to match the set of 'a' values
> observed in that panel, but unfortunately it seems 'relation' is
> ignored for factors.  Would it make sense to have 'relation' work
> for factors?  Is there some other way to accomplish the same effect?

Yes and no, respectively.

This was recently brought up by John Maindonald off-list, and I had a 
tentative fix planned. Unfortunately, I just realized that it would 
only work when the 'present' levels within each panel are contiguous 
levels of the factor. I'll have to think a bit more about it. Whatever 
the fix, it would have to break the current API, so it's not going to 
be available before R 2.0.0. 

Here's a bad workaround (bad because it would give wrong answers if 
relation != "free"):

dotplot(y ~ a | b, data=dat,
        scales = list(x = list(relation = "free")),
        prepanel = function(x, y, ...) {
            ans <- list()
            if (is.factor(x)) {
                x <- x[drop = TRUE]
                ans$xlim <- levels(x)
            if (is.factor(x)) {
                y <- y[drop = TRUE]
                ans$ylim <- levels(y)
        panel = function (x, y, ...) {
            x <- x[drop = TRUE]
            y <- y[drop = TRUE]
            panel.dotplot(x, y, ...)


More information about the R-help mailing list