From maechler at stat.math.ethz.ch  Wed Jan  5 16:26:59 2011
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Wed, 5 Jan 2011 16:26:59 +0100
Subject: [Rd] Minimum of an ordered factor
In-Reply-To: <F54EF8F1B477CF448729593FE421F6464A22AE@HQVEVE0032.nestle.com>
References: <F54EF8F1B477CF448729593FE421F6464A22AE@HQVEVE0032.nestle.com>
Message-ID: <19748.36291.498450.670163@lynne.math.ethz.ch>

>>>>> Thaler, Thorn, LAUSANNE, Applied Mathematics <Thorn.Thaler at rdls.nestle.com>
>>>>>     on Wed, 5 Jan 2011 11:20:47 +0100 writes:

    > Hi everybody, Is there a particular reason, why this code
    > does not work as intended:

    > z <- factor(LETTERS[1:3], ordered = TRUE)
    > u <- 4:6
    > min(z[u > 4])

    > Error in Summary.factor(2:3, na.rm = FALSE) :
    >   min not meaningful for factors



    > I agree that min is indeed not meaningful for not ordered
    > factors, but it makes sense for ordered
    > factors. Especially since

    > z[3] < z[2]
    > sort(z)

    > _ARE_ defined and work as expected. 

I agree that it is natural then, to expect  min(), max() and
range() to work as well.

    > Of course I can do something like

    > sort(z[u>4])[1]

    > but this does not enhance readability of my code. Thus, I
    > overloaded Summary.ordered as follows:


 

    > Summary.ordered <- function(..., na.rm) {

    >   ok <- switch(.Generic, max = , min = , range = TRUE,
    > FALSE)

    >   if (!ok) {

    >     warning(sprintf("'%s' is not meaningful for ordered
    > factors", .Generic))

    >     return(NA)

    >   }

    >   args <- list(...)

    >   level.list <- lapply(args, levels)

    >   level.set <- Reduce(union, level.list)

    >   if (!all(sapply(args, is.ordered)) ||
    > !all(sapply(level.list, identical, y = level.set))) {

    >     stop(sprintf("'%s' is only meaningful for ordered
    > factors if all arguments are ordered factors with the same
    > level sets",

    >                  .Generic))

    >   }

 

    >   codes <- lapply(args, as.integer)

    >   ind <- do.call(.Generic, c(codes, na.rm = na.rm))

 

    >   factor(level.set[ind], levels = level.set, ordered =
    > TRUE)

    > }

(the above is now even more garbled than it was already by your
 use of HTML-ified e-mail ..)

But your code is fine, even nice, in most parts,
and I will add (most of) it (and some documentation) to R-devel
 
unless we get contradicting comments :

    > Any comments appreciated.
(still)


Thank you, Thorn!

With regards,
Martin Maechler, ETH Zurich



[Rd] Minimum of an ordered factor
Martin Maechler