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.