Thaler, Thorn, LAUSANNE, Applied Mathematics
2011-Jan-05 10:20 UTC
[Rd] Minimum of an ordered factor
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. 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)
}
Any comments appreciated.
BR,
Thorn
[[alternative HTML version deleted]]
>>>>> 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