Простая комбинаторика в 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 столбцов).
4 ответов
Ну, есть встроенный 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
существует базовая функция R combn
в пакете utils
, который, насколько я могу судить, дает идентичные (если перенести) результаты. Разница в том, что 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
Спасибо за размещение. Несколько настроек для производительности.
a. Я использовал репутацию.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)