I have a custom class object (list of tuples).
I have defined <.myclass
>.myclass
and ==.myclass
on it as well.
Now I have a
This answer from Aaron demonstrates, exactly, what is needed to apply a customized sort
on a class
ed object. As Roland notes, you -actually- need to sort
"L" and, thus, that is where the focus on custom sort
should be. To provide flexibility specifying on which index of "L" 's elements to sort
, a way would be to store an extra attr
on "L":
Turn "L" to an appropriate object:
class(L) = "myclass"
attr(L, "sort_ind") = 1L
Ops
methods need to be defined (extract the relevant element of your data):
"<.myclass" = function(x, y)
{
i = attr(x, "sort_ind") ## also check if 'x' and 'y' have the same 'attr(, "sort_ind")'
x[[1]][[i]] < y[[1]][[i]]
}
"==.myclass" = function(x, y)
{
i = attr(x, "sort_ind")
x[[1]][[i]] == y[[1]][[i]]
}
">.myclass" = function(x, y)
{
i = attr(x, "sort_ind")
x[[1]][[i]] > y[[1]][[i]]
}
And a subset method:
"[.myclass" = function(x, i)
{
y = .subset(x, i)
attributes(y) = attributes(x)
return(y)
}
The above methods are necessary (perhaps, except "<"
) to be defined since a call to sort
/order
will end up calling rank
which needs .gt
in order to subset accordingly each element and compare.
Finally, a get/set function for sauce:
sort_ind = function(x) attr(x, "sort_ind")
"sort_ind<-" = function(x, value)
{
attr(x, "sort_ind") = value
return(x)
}
And:
order(L)
#[1] 3 2 1
sort_ind(L) = 3
order(L)
#[1] 2 3 1
A method for sort
can be, also, created to wrap all the above:
sort.myclass = function(x, sort_ind = attr(x, "sort_ind"), ...)
{
sort_ind(x) = sort_ind
NextMethod()
}
sort(L)
sort(L, sort_ind = 1)
(I assumed that your toList
function would look like something toList = function(x) x[[1L]]
)