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?
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().
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With