#r #combinatorics
#r #комбинаторика
Вопрос:
Я хочу поделиться функцией 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 столбцов).
Ответ №1:
Ну, там есть встроенная 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
Комментарии:
1. При такой небольшой проблеме, скорее всего, разница заключается в накладных расходах на проверку ошибок и настройку для общего случая с 3 или более строками выходных данных и возможным интересным приложением, которое
combn
проходит через это.
Ответ №2:
combn
В пакете utils
есть базовая функция R, которая, насколько я могу судить, дает идентичные (при транспонировании) результаты. Разница в том, что 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
Комментарии:
1. Большое спасибо, потому что я был озадачен этой функцией combn.
Ответ №3:
пакет combinat
. Отличный набор инструментов для комбинирования, перестановки и всего такого.
Ответ №4:
Спасибо за публикацию. Несколько настроек для повышения производительности.
a. Я использовал rep.int вместо или повторно, при вычислении индексов для first.
б. Я использовал
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)