Espero crear todas las posibles permutaciones de un vector que contenga dos valores diferentes, en los que controlo la proporción de cada uno de los valores.

Por ejemplo, si tengo un vector de longitud tres y quiero que todas las combinaciones posibles contengan un solo 1, mi resultado deseado es una lista que se ve así:

list.1 <- list(c(1,0,0), c(0,1,0), c(0,0,1))

Por el contrario, si quiero todas las combinaciones posibles que contengan tres 1, mi resultado deseado es una lista que se ve así:

list.3 <- list(c(1,1,1))

Para decirlo de otra manera, el patrón de los valores 1 y 0 importa, pero todos los 1 deben tratarse como idénticos a todos los demás 1.

Basado en la búsqueda aquí y en otros lugares, probé varios enfoques:

expand.grid(0:1, 0:1, 0:1)  # this includes all possible combinations of 1, 2, or 3 ones
permn(c(0,1,1))             # this does not treat the ones as identical (e.g. it produces (0,1,1) twice)
unique(permn(c(0,1,1)))     # this does the job!

Entonces, usar la función permn del paquete combinat parece prometedor. Sin embargo, cuando escalo esto a mi problema real (un vector de longitud 20, con 50% 1s y 50% 0s, me encuentro con problemas:

unique(permn(c(rep(1,10), rep(0, 10))))

# returns the error:
Error in vector("list", gamma(n + 1)) : 
  vector size specified is too large

Tengo entendido que esto está sucediendo porque, en la llamada a permn, hace una lista que contiene todas las permutaciones posibles, aunque muchas de ellas son idénticas, y esta lista es demasiado grande para que R la maneje.

¿Alguien tiene alguna sugerencia sobre cómo solucionar esto?

Lo siento si esto ha sido respondido anteriormente - ¡hay muchas, muchas preguntas SO que contienen un lenguaje similar pero problemas diferentes y no he podido encontrar una solución que satisfaga mis necesidades!

6
Sam Zipper 20 jul. 2016 a las 17:37

2 respuestas

La mejor respuesta

No debería ser un factor decisivo que expand.grid incluya todas las permutaciones. Simplemente agregue un subconjunto después de:

combinations <- function(size, choose) {

  d <- do.call("expand.grid", rep(list(0:1), size))
  d[rowSums(d) == choose,]

}

combinations(size=10, choose=3)
#    Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10
# 8     1    1    1    0    0    0    0    0    0     0
# 12    1    1    0    1    0    0    0    0    0     0
# 14    1    0    1    1    0    0    0    0    0     0
# 15    0    1    1    1    0    0    0    0    0     0
# 20    1    1    0    0    1    0    0    0    0     0
# 22    1    0    1    0    1    0    0    0    0     0
...
3
Pierre L 20 jul. 2016 a las 16:01

De hecho, el problema es que inicialmente está calculando todas las permutaciones factoriales (20) (~ 10 ^ 18), que no caben en su memoria. Lo que busca es una forma eficaz de calcular permutaciones de varios conjuntos. El paquete multicool puede hacer esto:

library(multicool)

res <- allPerm(initMC(c(rep(0,10),rep(1,10) )))

Este cálculo lleva unos dos minutos en mi computadora portátil, pero definitivamente es factible.

2
David Heckmann 20 jul. 2016 a las 15:44