From maechler at stat.math.ethz.ch  Fri Oct  9 12:14:55 2015
From: maechler at stat.math.ethz.ch (Martin Maechler)
Date: Fri, 9 Oct 2015 12:14:55 +0200
Subject: [Rd] rank(, ties.method="last")
In-Reply-To: <CAM3-KjZ=d1a4sUFckw83RZu-phZffY7KvZeQ1WtAjNB6ysoeJw@mail.gmail.com>
References: <CAM3-KjZ=d1a4sUFckw83RZu-phZffY7KvZeQ1WtAjNB6ysoeJw@mail.gmail.com>
Message-ID: <22039.37791.6045.955899@stat.math.ethz.ch>


> I ran into a problem where I actually need rank(, ties.method="last"). It would
> be great to have this feature in base and it's also simple to get (see below).

> Thanks & cheers,
> Marius


> rank2 <- function (x, na.last = TRUE, ties.method = c("average",
> "first", "last", # new "last"
>     "random", "max", "min"))
> {
>     nas <- is.na(x)
>     nm <- names(x)
>     ties.method <- match.arg(ties.method)
>     if (is.factor(x))
>         x <- as.integer(x)
>     x <- x[!nas]
>     y <- switch(ties.method, average = , min = , max = .Internal(rank(x,
>         length(x), ties.method)), first = sort.list(sort.list(x)),
>         last = sort.list(sort.list(x, decreasing=TRUE), decreasing=TRUE), # change
>         random = sort.list(order(x, stats::runif(sum(!nas)))))
>     if (!is.na(na.last) && any(nas)) {
>         yy <- NA
>         NAkeep <- (na.last == "keep")
>         if (NAkeep || na.last) {
>             yy[!nas] <- y
>             if (!NAkeep)
>                 yy[nas] <- (length(y) + 1L):length(yy)
>         }
>         else {
>             len <- sum(nas)
>             yy[!nas] <- y + len
>             yy[nas] <- seq_len(len)
>         }
>         y <- yy
>         names(y) <- nm
>     }
>     else names(y) <- nm[!nas]
>     y
> }

> ## MWE
> x <- c(10, 11, 11, 12, 12, 13)
> rank(x, ties.method="first")
> rank2(x, ties.method="last")

Indeed, this makes sense to me, and is easy enough to document
and maintain, and preferable to asking useRs to use  rev(.) and
similar "easy" (but somewhat costly for large data!)
transformations to get the same....

Or have (Marius Hofert and I) overlooked something obvious ?

Martin Maechler,
ETH Zurich



[Rd] rank(, ties.method="last")
Martin Maechler