I have a custom class object (list of tuples). I have defined <.myclass
>.myclass
and ==.myclass
on it as well.
我有一个自定义类对象(元组列表)。我已经定义的<。myclass >。myclass和= =。我的课上也有。
Now I have a
现在我有一个
a <- obj1 # of myclass
b <- obj2 # of myclass
c <- obj3 # of myclass
L <- list(list(a,12,1),list(b,215,23),list(c,21,9))
I want to sort L, on index 1. i.e. I have b < c < a
then, I want sorted L in this form list(list(b,215,23),list(c,21,9),list(a,12,1))
我想对L排序,在索引1上。例如,我有b < c < a那么,我想要在这个表单列表中排序L (list(b,215,23),list(c,21,9),list(a,12,1)
How do I achieve this?
我如何做到这一点?
In my searches, I found how to sort on particular index, and using that I wrote the following function
在我的搜索中,我找到了如何对特定索引进行排序,并使用它编写了以下函数
magic_sort <- function(lst, sortind, dec = T) {
return(lst[order(sapply(lst,'[[',sortind), decreasing = dec)])
}
But when I give index 1 to it, to sort on obj1, it fails with
但是当我给它一个索引1,对obj1排序时,它会失败
> magic_sort(L,1)
Error in order(sapply(lst, "[[", sortind), decreasing = dec) :
unimplemented type 'list' in 'orderVector1'
Is there any fix for this? In general, can I have functions like sort, minimum and so on, based on custom definition of comparison operators?
有什么解决办法吗?一般来说,我能基于比较运算符的自定义定义定义拥有排序、最小等函数吗?
Edit: Following perhaps will help understand the structure better: http://pastebin.com/0M7JRLTu
编辑:以下内容可能有助于更好地理解结构:http://pastebin.com/0M7JRLTu
Edit 2:
编辑2:
library("sets")
a <- list()
class(a) <- "dfsc"
a[[1]] <- tuple(1L, 2L, "C", "a", "B")
b <- list()
class(b) <- "dfsc"
b[[1]] <- tuple(1L, 2L, "A", "b", "B")
c <- list()
class(c) <- "dfsc"
c[[1]] <- tuple(1L, 2L, "A", "a", "B")
L <- list()
L[[1]] <- list(a, 12, 132)
L[[2]] <- list(b, 21, 21)
L[[3]] <- list(c, 32, 123)
`<.dfsc` <- function(c1, c2) {
return(lt_list(toList(c1),toList(c2)))
}
`==.dfsc` <- function(c1, c2) {
return(toString(c1) == toString(c2))
}
`>.dfsc` <- function(c1, c2) {
return(!((c1 < c2) || (c1 == c2)))
}
lt_list <- function(l1, l2) {
n1 <- length(l1)
n2 <- length(l2)
j = 1
while(j <= n1 && j <= n2) {
if (l1[[j]] != l2[[j]]) {
return (l1[[j]] < l2[[j]])
}
j = j + 1
}
return(n1 < n2)
}
toString.dfsc <- function(x) {
code_string <- ""
#for(ii in x[[1]]) {
for(ii in x) {
code_string <- paste(code_string,"(",ii[[1]],",",ii[[2]],",",ii[[3]],",",ii[[4]],",",ii[[5]],")", sep = "")
}
return(code_string)
}
Now I want the L
desired to be list(list(c,_,_),list(b,_,_),list(a,_,_))
现在我想要L所需的列表(列表(c、_、_),列表(b,_,_),列表(_,_))
2 个解决方案
#1
2
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":
Aaron给出的这个答案演示了在一个类对象上应用自定义排序所需的东西。正如Roland所指出的,实际上,您需要对“L”进行排序,因此,这就是关注自定义排序的地方。为了提供对“L”元素的索引进行排序的灵活性,一种方法是在“L”上存储一个额外的attr:
Turn "L" to an appropriate object:
将“L”转到合适的对象:
class(L) = "myclass"
attr(L, "sort_ind") = 1L
Ops
methods need to be defined (extract the relevant element of your data):
需要定义Ops方法(提取数据的相关元素):
"<.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:
上述方法是必须定义的(可能除了“<”),因为对排序/排序的调用最终会调用需要.gt的rank,以便相应地对每个元素进行子集划分并进行比较。最后,酱料的get/set函数:
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]]
)
(我假设toList函数应该是toList = function(x) x[[1L]]))
#2
0
I wanted to make use of internal and supposedly more efficient sort, but doesn't seem like this sort has facility to take custom comparison operator. So I ended up using implementation of quicksort to sort lists of lists at arbitrary index, assuming comparison exists between the elements at that index.
我想要使用内部的并且被认为是更有效的排序,但是看起来这种排序并没有使用自定义比较运算符的功能。因此,我最终使用了快速排序的实现来对任意索引中的列表进行排序,假设该索引中的元素之间存在比较。
part_qsort <- function(l, idx, low, high) {
lst <- l
pivot <- lst[[high]][[idx]]
i <- low - 1
for(j in low:(high-1)) {
if ((lst[[j]][[idx]] < pivot) || (lst[[j]][[idx]] == pivot)) {
i <- i + 1
swap(lst[[i]],lst[[j]])
}
}
swap(lst[[(i+1)]],lst[[high]])
eval.parent(substitute(l <- lst))
return(i+1)
}
# recursive calls to quicksort
qsort <- function(l,idx,low,high) {
if (low < high) {
lst <- l
pi <- part_qsort(lst,idx,low,high)
qsort(lst, idx, low, pi-1)
qsort(lst, idx, pi+1, high)
eval.parent(substitute(l <- lst))
}
}
Another thing to look into can be library("rlist")
which seems to have a bunch of functions implemented on lists.
另一件要研究的事情是库(“rlist”),它似乎有一堆在列表上实现的函数。
#1
2
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":
Aaron给出的这个答案演示了在一个类对象上应用自定义排序所需的东西。正如Roland所指出的,实际上,您需要对“L”进行排序,因此,这就是关注自定义排序的地方。为了提供对“L”元素的索引进行排序的灵活性,一种方法是在“L”上存储一个额外的attr:
Turn "L" to an appropriate object:
将“L”转到合适的对象:
class(L) = "myclass"
attr(L, "sort_ind") = 1L
Ops
methods need to be defined (extract the relevant element of your data):
需要定义Ops方法(提取数据的相关元素):
"<.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:
上述方法是必须定义的(可能除了“<”),因为对排序/排序的调用最终会调用需要.gt的rank,以便相应地对每个元素进行子集划分并进行比较。最后,酱料的get/set函数:
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]]
)
(我假设toList函数应该是toList = function(x) x[[1L]]))
#2
0
I wanted to make use of internal and supposedly more efficient sort, but doesn't seem like this sort has facility to take custom comparison operator. So I ended up using implementation of quicksort to sort lists of lists at arbitrary index, assuming comparison exists between the elements at that index.
我想要使用内部的并且被认为是更有效的排序,但是看起来这种排序并没有使用自定义比较运算符的功能。因此,我最终使用了快速排序的实现来对任意索引中的列表进行排序,假设该索引中的元素之间存在比较。
part_qsort <- function(l, idx, low, high) {
lst <- l
pivot <- lst[[high]][[idx]]
i <- low - 1
for(j in low:(high-1)) {
if ((lst[[j]][[idx]] < pivot) || (lst[[j]][[idx]] == pivot)) {
i <- i + 1
swap(lst[[i]],lst[[j]])
}
}
swap(lst[[(i+1)]],lst[[high]])
eval.parent(substitute(l <- lst))
return(i+1)
}
# recursive calls to quicksort
qsort <- function(l,idx,low,high) {
if (low < high) {
lst <- l
pi <- part_qsort(lst,idx,low,high)
qsort(lst, idx, low, pi-1)
qsort(lst, idx, pi+1, high)
eval.parent(substitute(l <- lst))
}
}
Another thing to look into can be library("rlist")
which seems to have a bunch of functions implemented on lists.
另一件要研究的事情是库(“rlist”),它似乎有一堆在列表上实现的函数。