# Combinatoria simple en R

I wish to share an R function for finding all possible unique undirected combinations between elements of a single vector:

``````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)
}
``````

and ask if there is a simpler way of doing this? (I need the result to be in a 2-column matrix).

preguntado el 08 de noviembre de 11 a las 13:11

## 4 Respuestas

Well, there's a built-in `combn` función:

``````t(combn(vec1,2))
``````

Yours looks faster, though, perhaps because `combn` is trying to solve a more general problem (??):

``````> 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
``````

respondido 08 nov., 11:17

With a problem this small the overhead of error checking and setup for the general case of 3 or higher rows of output and possible FUN application that `combn` wades through is most probably the difference. - IRTFM

There is a base R function `combn` en paquete `utils` which, as far as I can tell, gives identical (if transposed) results. The difference is that `combn` is more flexible in the sense that it will also calculate combinations of length other than 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
``````

Using the base 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
``````

Calculate combinations of length 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
``````

respondido 08 nov., 11:17

Thanks a lot because I was perplexed by this combn function. - Fedja Blagojevic

paquete `combinat`. Great bunch of tools for combination, permutation, and all that.

respondido 08 nov., 11:19

Thanks for posting. A few tweaks for performance.

a. I used rep.int instead or rep, when figuring out the indices for first.

b. I used

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

en lugar de

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

c. I used

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

en lugar de

``````matrix(cbind(first, second), ncol = 2)
``````

Respondido el 23 de junio de 15 a las 13:06

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.