Простая комбинаторика в R - PullRequest
8 голосов
/ 08 ноября 2011

Я хочу поделиться функцией R для нахождения всех возможных уникальных неориентированных комбинаций между элементами одного вектора:

combi <- function(vec1)
{
  si <- length(vec1)
  first <- rep(vec1, (si-1):0)
  secR <- rev(vec1)
  second <- secR[sequence(1:(si-1))]
  second <- rev(second)
  combi <- matrix(cbind(first, second), ncol = 2)
  return(combi)
}

и спросите, есть ли более простой способ сделать это? (Мне нужно, чтобы результат был в матрице из 2 столбцов).

Ответы [ 4 ]

10 голосов
/ 08 ноября 2011

Ну, есть встроенная функция combn:

t(combn(vec1,2))

Ваш выглядит быстрее, возможно, потому, что combn пытается решить более общую проблему (??):

> library(rbenchmark)
> v <- 1:20
> benchmark(combi(v),t(combn(v,2)))
            test replications elapsed relative user.self sys.self
1       combi(v)          100   0.005      1.0     0.004    0.000   
2 t(combn(v, 2))          100   0.044      8.8     0.040    0.004   
4 голосов
/ 08 ноября 2011

В пакете utils есть базовая функция R combn, которая, насколько я могу судить, дает идентичные (если транспонировать) результаты.Разница в том, что combn является более гибким в том смысле, что он также будет рассчитывать комбинации длины, отличные от 2.

combi(1:5)
      [,1] [,2]
 [1,]    1    2
 [2,]    1    3
 [3,]    1    4
 [4,]    1    5
 [5,]    2    3
 [6,]    2    4
 [7,]    2    5
 [8,]    3    4
 [9,]    3    5
[10,]    4    5

Используя базовую R combn:

combn(1:5, 2)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    1    1    2    2    2    3    3     4
[2,]    2    3    4    5    3    4    5    4    5     5

Рассчитать комбинации длины 3:

combn(1:5, 3)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    1    1    1    1    2    2    2     3
[2,]    2    2    2    3    3    4    3    3    4     4
[3,]    3    4    5    4    5    5    4    5    5     5
2 голосов
/ 08 ноября 2011

пакет combinat. Отличный набор инструментов для комбинации, перестановки и всего такого.

1 голос
/ 23 июня 2015

Спасибо за публикацию.Несколько настроек производительности.

a.Я использовал rep.int вместо или rep, когда вычислял индексы для первого.

b.Я использовал

second <- secR[rev(sequence(1:(si-1)))]

вместо

second <- secR[sequence(1:(si-1))]
second <- rev(second)

c.Я использовал

matrix(c(first, second), ncol = 2)

вместо

matrix(cbind(first, second), ncol = 2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...