Skip to content

order(x,y, decreasing = c(FALSE, TRUE)) - how / elegantly?

3 messages · Martin Maechler, Brian Ripley

#
I've found the need to compute a version of  order(x,y)
where I want the sort order 
for *increasing* x  and *decresing* y ...

something we could imagine could be provided in the future as

  order(x,y, decreasing = c(FALSE, TRUE))

i.e., using a 'vectorized' decreasing argument.
{No, I'm not volunteering right now!}

I've found the following R-level solution and
like to quiz you for more elegant / faster solutions 
{but I am not really interested in replacing  
 order(x)  by  sort.list(x, method="quick") and similar things;
 one thing to consider *is* using an   'na.last = . ' correctly,
 and I haven't had the need for that and so not bothered to "do it"}

## Here's a script with my version and a small example 
## (if you want speed comparisons, use larger examples) :

orderXuYd <- function(x,y)
{
    ## Purpose: order(x,y): x up, y down
    ## ----------------------------------------------------------------------
    ## Arguments: x,y:  vectors of the same length
    ## ----------------------------------------------------------------------
    ## Author: Martin Maechler, Date: 21 Aug 2008

    ix <- order(x) 
    xx <- x[ix]
    iy <- tapply(y[ix], xx, order, decreasing = TRUE)
    ## Note: 'SIMPLIFY', 'USE.NAMES', 'use.names' are just for efficiency:
    unlist(mapply(`[`, split(ix,xx), iy, 
                  SIMPLIFY = FALSE, USE.NAMES = FALSE),
           use.names = FALSE)
}

x <- c(1, 1, 2, 0, 0, 2, 1, 2, 2, 0, 2)
y <- c(27, 21, 45, 11, 13, 58, 35, 74, 95, 16, 122)
ii <- orderXuYd(x,y)
## yes, this is it :
cbind(ii=ii, x=x[ii],y=y[ii])

------------------

Yes, the real reason this goes to R-devel is that it might be
neat to provide this (well, its generalization) via an enhanced
order() function.

Martin Maechler, ETH Zurich

PS: I will be basically offline all day tomorrow, so don't
    expect my reactions to your ideas quickly
#
Duh!!  

The simplest, probably fastest and most elegant solution of
course is

       order(x, -y)

......  if only I would have biked home earlier, today,...
	I'm sure I would have save much of my time....

Martin
MM> I've found the need to compute a version of order(x,y)
    MM> where I want the sort order for *increasing* x and
    MM> *decresing* y ...

    MM> something we could imagine could be provided in the
    MM> future as

    MM>   order(x,y, decreasing = c(FALSE, TRUE))

    MM> i.e., using a 'vectorized' decreasing argument.  {No,
    MM> I'm not volunteering right now!}

    MM> I've found the following R-level solution and like to
    MM> quiz you for more elegant / faster solutions {but I am
    MM> not really interested in replacing order(x) by
    MM> sort.list(x, method="quick") and similar things; one
    MM> thing to consider *is* using an 'na.last = . '
    MM> correctly, and I haven't had the need for that and so
    MM> not bothered to "do it"}

    MM> ## Here's a script with my version and a small example
    MM> ## (if you want speed comparisons, use larger examples)
    MM> :

    MM> orderXuYd <- function(x,y) { ## Purpose: order(x,y): x
    MM> up, y down ##
    MM> ----------------------------------------------------------------------
    MM> ## Arguments: x,y: vectors of the same length ##
    MM> ----------------------------------------------------------------------
    MM> ## Author: Martin Maechler, Date: 21 Aug 2008

    MM>     ix <- order(x) xx <- x[ix] iy <- tapply(y[ix], xx,
    MM> order, decreasing = TRUE) ## Note: 'SIMPLIFY',
    MM> 'USE.NAMES', 'use.names' are just for efficiency:
    MM> unlist(mapply(`[`, split(ix,xx), iy, SIMPLIFY = FALSE,
    MM> USE.NAMES = FALSE), use.names = FALSE) }

    MM> x <- c(1, 1, 2, 0, 0, 2, 1, 2, 2, 0, 2) y <- c(27, 21,
    MM> 45, 11, 13, 58, 35, 74, 95, 16, 122) ii <-
    MM> orderXuYd(x,y) ## yes, this is it : cbind(ii=ii,
    MM> x=x[ii],y=y[ii])

    MM> ------------------

    MM> Yes, the real reason this goes to R-devel is that it
    MM> might be neat to provide this (well, its generalization)
    MM> via an enhanced order() function.

    MM> Martin Maechler, ETH Zurich

    MM> PS: I will be basically offline all day tomorrow, so
    MM> don't expect my reactions to your ideas quickly

    MM> ______________________________________________
    MM> R-devel at r-project.org mailing list
    MM> https://stat.ethz.ch/mailman/listinfo/r-devel
#
On Thu, 21 Aug 2008, Martin Maechler wrote:

            
Only for numeric x.  As Martin knows, I am working on ideas for 'generic' 
order, and one is a xtfrm(z) function that creates an integer vector that 
sorts the same as z.  Then -xtrfm(z) would work.