Сортировать список нетривиальных элементов в R - PullRequest
10 голосов
/ 22 сентября 2011

В R у меня есть список нетривиальных объектов (это не простые объекты, такие как скаляры, для которых R, как можно ожидать, сможет определять порядок).Я хочу отсортировать список.Большинство языков позволяют программисту предоставлять функцию или аналог, который сравнивает пару элементов списка, которые передаются в функцию сортировки.Как мне отсортировать мой список?

Ответы [ 3 ]

14 голосов
/ 22 сентября 2011

Чтобы сделать это как можно проще, скажем, ваши объекты - это списки с двумя элементами: именем и значением. Значение является числовым; это то, что мы хотим отсортировать. Вы можете представить, что у вас больше элементов и вам нужно что-то более сложное для сортировки.

Страница справки sort сообщает, что sort использует xtfrm; xtfrm, в свою очередь, говорит нам, что будет использовать методы == и > для класса x[i].

Сначала я определю объект, который хочу отсортировать:

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

Теперь, поскольку xtfrm работает с x[i], мне нужно определить функцию [, которая возвращает нужные элементы, но все еще с правильным классом

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

Теперь нам нужны функции == и > для класса myobj; потенциально это может быть умнее, если их правильно векторизовать; но для функции сортировки мы знаем, что мы будем передавать только myobj длины 1, поэтому я просто буду использовать первый элемент для определения отношений.

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

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

Теперь sort просто работает.

sort(xx)

Считается более правильным написать полную Ops функцию для вашего объекта; однако, чтобы разобраться, это все, что вам нужно. См. Стр.89-90 в Venables / Ripley для более подробной информации о том, как сделать это, используя стиль S3. Кроме того, если вы легко можете написать для своих объектов функцию xtfrm, это будет проще и, скорее всего, быстрее.

4 голосов
/ 22 сентября 2011

Функция 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
1 голос
/ 22 сентября 2011

Один из вариантов - создать метод xtfrm для ваших объектов.Такие функции, как order, принимают несколько столбцов, что в некоторых случаях работает.В пакете gtools есть также специальные функции для особых случаев, например mixedsort.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...