# rank(, ties.method="last")

7 messages
Open this post in threaded view
|

## rank(, ties.method="last")

 Hi, 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") ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Open this post in threaded view
|

## Re: rank(, ties.method="last")

 > 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 ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Open this post in threaded view
|

## Re: rank(, ties.method="last")

 Den 2015-10-09 kl. 12:14, skrev Martin Maechler: > >> 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 ? I think so: the code above doesn't seem to do the right thing.  Consider the following example:  > x <- c(1, 1, 2, 3)  > rank2(x, ties.method = "last") [1] 1 2 4 3 That doesn't look right to me -- I had expected  > rev(sort.list(x, decreasing = TRUE)) [1] 2 1 3 4 Henric Winell > > Martin Maechler, > ETH Zurich > > ______________________________________________ > [hidden email] mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel> ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Open this post in threaded view
|

## Re: rank(, ties.method="last")

 In reply to this post by Martin Maechler On Tue, Oct 20, 2015 at 10:26 AM, Henric Winell <[hidden email]> wrote: > Den 2015-10-09 kl. 12:14, skrev Martin Maechler: > I think so: the code above doesn't seem to do the right thing.  Consider > the following example: > >  > x <- c(1, 1, 2, 3) >  > rank2(x, ties.method = "last") > [1] 1 2 4 3 > > That doesn't look right to me -- I had expected > >  > rev(sort.list(x, decreasing = TRUE)) > [1] 2 1 3 4 > Indeed, well spotted, that seems to be correct. > > Henric Winell > ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Open this post in threaded view
|

## Re: rank(, ties.method="last")

 In reply to this post by Marius Hofert-4 Marius Hofert-4------------------------------ > Den 2015-10-09 kl. 12:14, skrev Martin Maechler: > I think so: the code above doesn't seem to do the right thing.  Consider > the following example: > >  > x <- c(1, 1, 2, 3) >  > rank2(x, ties.method = "last") > [1] 1 2 4 3 > > That doesn't look right to me -- I had expected > >  > rev(sort.list(x, decreasing = TRUE)) > [1] 2 1 3 4 > Indeed, well spotted, that seems to be correct. > > Henric Winell > ------------------------------ In the particular example (of length 4), what is really wanted is the following. ind <- integer(4) ind[sort.list(x, decreasing=TRUE)] <- 4:1 ind The following gives the desired result: sort.list(rev(sort.list(x, decreasing=TRUE))) ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel