Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort a list of nontrivial elements in R

Tags:

sorting

r

In R, I have a list of nontrivial objects (they aren't simple objects like scalars that R can be expected to be able to define an order for). I want to sort the list. Most languages allow the programmer to provide a function or similar that compares a pair of list elements that is passed to a sort function. How can I sort my list?

like image 799
Chris Avatar asked Sep 22 '11 13:09

Chris


People also ask

How do I sort a list in R?

Sorting or Ordering a list in R can be done by using lapply() function or using the order() function after converting to a vector using unlist().

How do I sort a list in ascending order in R?

To sort a data frame in R, use the order( ) function. By default, sorting is ASCENDING. Prepend the sorting variable by a minus sign to indicate DESCENDING order.

What is order function R?

Definition of order() R function: The order function returns the position of each element of its input in ascending or descending order. As you can see in Figure 1, the lowest value (i.e. -10) is located at position two and the highest value (i.e. 8) is located at position three within our example vector.


1 Answers

To make this is as simple I can, say your objects are lists with two elements, a name and a value. The value is a numeric; that's what we want to sort by. You can imagine having more elements and needing to do something more complex to sort.

The sort help page tells us that sort uses xtfrm; xtfrm in turn tells us it will use == and > methods for the class of x[i].

First I'll define an object that I want to sort:

xx <- lapply(c(3,5,7,2,4), function(i) list(name=LETTERS[i], value=i))
class(xx) <- "myobj"

Now, since xtfrm works on the x[i]'s, I need to define a [ function that returns the desired elements but still with the right class

`[.myobj` <- function(x, i) {
  class(x) <- "list"
  structure(x[i], class="myobj")
}

Now we need == and > functions for the myobj class; this potentially could be smarter by vectorizing these properly; but for the sort function, we know that we're only going to be passing in myobj's of length 1, so I'll just use the first element to define the relations.

`>.myobj` <- function(e1, e2) {
  e1[[1]]$value > e2[[1]]$value
}

`==.myobj` <- function(e1, e2) {
  e1[[1]]$value == e2[[1]]$value
}

Now sort just works.

sort(xx)

It might be considered more proper to write a full Ops function for your object; however, to just sort, this seems to be all you need. See p.89-90 in Venables/Ripley for more details about doing this using the S3 style. Also, if you can easily write an xtfrm function for your objects, that would be simpler and most likely faster.

like image 171
Aaron left Stack Overflow Avatar answered Sep 22 '22 20:09

Aaron left Stack Overflow