【问题标题】:Sort a list of nontrivial elements in R对R中的非平凡元素列表进行排序
【发布时间】:2011-09-22 22:22:21
【问题描述】:

在 R 中,我有一个重要对象的列表(它们不是像标量这样的简单对象,可以期望 R 能够为其定义顺序)。我想对列表进行排序。大多数语言允许程序员提供一个函数或类似的函数来比较传递给排序函数的一对列表元素。如何对列表进行排序?

【问题讨论】:

标签: r sorting


【解决方案1】:

为了尽可能简单,假设您的对象是包含两个元素的列表,一个名称和一个值。该值是一个数字;这就是我们想要排序的。你可以想象有更多的元素并且需要做一些更复杂的排序。

sort 帮助页面告诉我们sort 使用xtfrmxtfrm 反过来告诉我们它将使用 ==> 方法用于 x[i] 类。

首先我将定义一个我想要排序的对象:

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

现在,由于 xtfrmx[i] 上工作,我需要定义一个 [ 函数,该函数返回所需的元素但仍具有正确的类

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

现在我们需要myobj 类的==&gt; 函数;通过适当地对它们进行矢量化,这可能会更智能;但是对于排序函数,我们知道我们只会传入长度为 1 的myobj,所以我将只使用第一个元素来定义关系。

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

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

现在sort 可以正常工作了。

sort(xx)

为您的对象编写完整的Ops 函数可能被认为更合适;然而,只是排序,这似乎是你所需要的。有关使用 S3 样式执行此操作的更多详细信息,请参见 Venables/Ripley 中的第 89-90 页。此外,如果您可以轻松地为您的对象编写 xtfrm 函数,那将更简单,而且很可能更快。

【讨论】:

  • 谢谢亚伦。很棒的答案。
  • 要构建一个比使用常规 R 位构建的不太通用的解决方案需要做很多工作:这是 order 的两种用途,首先是值:xx[order(as.character(sapply(xx, "[", "value")))],然后是名称:xx[order(as.character(sapply(xx, "[", "name")))],没有对类方法的任何引用。
  • @DWin 是绝对正确的;如果你能做一些更聪明的事情,你应该这样做!
【解决方案2】:

order 函数将允许您确定字符或数字参数的排序顺序,并打破与后续参数的联系。你需要更具体地了解你想要什么。生成一个“非平凡对象”的示例,并在某个 R 对象中指定您想要的顺序。列表可能是最非矢量的对象:

> slist <- list(cc=list(rr=1), bb=list(ee=2, yy=7), zz="ww")
> slist[order(names(slist))]  # alpha order on names()
$bb
$bb$ee
[1] 2
$bb$yy
[1] 7  
$cc
$cc$rr
[1] 1    
$zz
[1] "ww"

slist[c("zz", "bb", "cc")]   # an arbitrary ordering
$zz
[1] "ww"
$bb
$bb$ee
[1] 2
$bb$yy
[1] 7
$cc
$cc$rr
[1] 1

【讨论】:

    【解决方案3】:

    一种选择是为您的对象创建一个xtfrm 方法。 order 之类的函数采用多个列,这在某些情况下有效。 gtools 包中还有一些针对特定情况的专用函数,例如 mixedsort

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-28
      • 1970-01-01
      相关资源
      最近更新 更多