From Kurt.Hornik at wu.ac.at  Thu Jan  6 10:52:17 2011
From: Kurt.Hornik at wu.ac.at (Kurt Hornik)
Date: Thu, 6 Jan 2011 10:52:17 +0100
Subject: [Rd] Minimum of an ordered factor
In-Reply-To: <19748.36291.498450.670163@lynne.math.ethz.ch>
References: <F54EF8F1B477CF448729593FE421F6464A22AE@HQVEVE0032.nestle.com>
	<19748.36291.498450.670163@lynne.math.ethz.ch>
Message-ID: <19749.37073.506112.61897@fangorn.hornik.net>

>>>>> Martin Maechler writes:

I have 3 comments:

>>>>> 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.

Same for me.

>> 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))) {

I think it would be better to use something like

  ll <- lapply(args, levels)

  !all(sapply(ll, identical, ll[[1L]]))

[using union() is not quite right]  

>> 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)

The general comment is that if we support this I don't see why we should
not also support c.ordered (and in fact also c.factor) with the same
restrictions (identical level sequences for ordered and level sets for
factors).  We already have Ops.factor and Ops.ordered using the same
principle afaic.

If we add c.ordered, we should be able to encapsulate the identity of
levels testing into this, and simply use

    x <- c(...)

and then call .Generic on the codes of x etc.

Best
-k


> Thank you, Thorn!

> With regards,
> Martin Maechler, ETH Zurich

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



[Rd] Minimum of an ordered factor
Kurt Hornik