From Thorn.Thaler at rdls.nestle.com  Fri Oct 21 14:57:16 2011
From: Thorn.Thaler at rdls.nestle.com (Thaler, Thorn, LAUSANNE,
	Applied Mathematics)
Date: Fri, 21 Oct 2011 14:57:16 +0200
Subject: [Rd] droplevels: drops contrasts as well
Message-ID: <F54EF8F1B477CF448729593FE421F646645E50@HQVEVE0032.nestle.com>

Dear all,

Today I figured out that there is a neat function called droplevels,
which, well, drops unused levels in a data frame. I tried the function
with some of my data sets and it turned out that not only the unused
levels were dropped but also the contrasts I set via "C". I had a look
into the code, and this behaviour arises from the fact that droplevels
uses simply factor to drop the unused levels, which uses the default
contrasts as set by options("contrasts").

I think this behaviour is annoying, because if one does not look
carefully enough, one looses the contrasts silently. Hence may I suggest
to change the code of droplevels to something like the following:

droplevels <- function (x, except = NULL, ...) {
    ix <- vapply(x, is.factor, NA)
    if (!is.null(except)) 
        ix[except] <- FALSE
    co <- lapply(x[ix], function(fa) attr(fa, "contrasts"))
    x[ix] <- mapply(function(fa, co) {
      if (nlevels(factor(fa)) == 1) {
        factor(fa)
      } else {
        C(factor(fa), co)
      }
    }, x[ix], co, SIMPLIFY = FALSE)
    x
}

which keeps the original contrasts AND drops the unused levels?
Similarly, droplevels.factor should be changed to

droplevels.factor  <- function (x, ...) {
  co <- attr(x, "contrasts")
  if (nlevels(factor(x)) == 1) {
    factor(x)
  } else {
    C(factor(x), co)
  }
}

The nlevels statement is necessary since C does not work if there are
less than 2 levels.

Any comments appreciated.


KR,

-Thorn



[Rd] droplevels: drops contrasts as well
Thorn.Thaler at rdls.nestle.com (Thaler, Thorn, LAUSANNE,