pairwise make combination combinat all r combinations

make - pairwise combinations in r



VersiĆ³n no redundante de expand.grid (5)

¿Qué hay de usar outer ? Pero esta función particular los concatena en una cadena de caracteres.

outer( c("aa", "ab", "cc"), c("aa", "ab", "cc") , "paste" ) # [,1] [,2] [,3] #[1,] "aa aa" "aa ab" "aa cc" #[2,] "ab aa" "ab ab" "ab cc" #[3,] "cc aa" "cc ab" "cc cc"

También puede usar combn en los elementos únicos de los dos vectores si no quiere que los elementos se repitan (por ejemplo, aa aa )

vals <- c( c("aa", "ab", "cc"), c("aa", "ab", "cc") ) vals <- unique( vals ) combn( vals , 2 ) # [,1] [,2] [,3] #[1,] "aa" "aa" "ab" #[2,] "ab" "cc" "cc"

La función R expand.grid devuelve todas las combinaciones posibles entre los elementos de los parámetros proporcionados. p.ej

> expand.grid(c("aa", "ab", "cc"), c("aa", "ab", "cc")) Var1 Var2 1 aa aa 2 ab aa 3 cc aa 4 aa ab 5 ab ab 6 cc ab 7 aa cc 8 ab cc 9 cc cc

¿Conoce una forma eficiente de obtener directamente (por lo tanto, sin ninguna comparación de filas después de expand.grid ) solo las combinaciones ''únicas'' entre los vectores suministrados? La salida será

Var1 Var2 1 aa aa 2 ab aa 3 cc aa 5 ab ab 6 cc ab 9 cc cc

EDITAR la combinación de cada elemento consigo mismo podría eventualmente ser descartada de la respuesta. Realmente no lo necesito en mi programa, aunque (matemáticamente) aa aa sería una combinación única (regular) entre un elemento de Var1 y otro de var2 .

La solución debe producir pares de elementos de ambos vectores (es decir, uno de cada uno de los vectores de entrada, de modo que se pueda aplicar a más de 2 entradas)


En la base R, puedes usar esto:

expand.grid.unique <- function(x, y, include.equals=FALSE) { x <- unique(x) y <- unique(y) g <- function(i) { z <- setdiff(y, x[seq_len(i-include.equals)]) if(length(z)) cbind(x[i], z, deparse.level=0) } do.call(rbind, lapply(seq_along(x), g)) }

Resultados:

> x <- c("aa", "ab", "cc") > y <- c("aa", "ab", "cc") > expand.grid.unique(x, y) [,1] [,2] [1,] "aa" "ab" [2,] "aa" "cc" [3,] "ab" "cc" > expand.grid.unique(x, y, include.equals=TRUE) [,1] [,2] [1,] "aa" "aa" [2,] "aa" "ab" [3,] "aa" "cc" [4,] "ab" "ab" [5,] "ab" "cc" [6,] "cc" "cc"


Las respuestas anteriores carecían de una forma de obtener un resultado específico, a saber, mantener los pares propios pero eliminar aquellos con órdenes diferentes. El paquete gtools tiene dos funciones para estos fines, combinations y permutations . Según este sitio web :

  • Cuando el orden no importa, es una combinación.
  • Cuando el orden sí importa es una Permutación.

En ambos casos, tenemos que decidir si se permiten repeticiones o no, y, en consecuencia, ambas funciones tienen un argumento de repetición permitido, que produce 4 combinaciones (¡deliciosamente meta!). Vale la pena repasar cada uno de estos. Simplifiqué el vector a letras individuales para facilitar su comprensión.

Permutaciones con repetición.

La opción más amplia es permitir tanto las relaciones personales como las opciones ordenadas de manera diferente:

> permutations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c")) [,1] [,2] [1,] "a" "a" [2,] "a" "b" [3,] "a" "c" [4,] "b" "a" [5,] "b" "b" [6,] "b" "c" [7,] "c" "a" [8,] "c" "b" [9,] "c" "c"

lo que nos da 9 opciones. Este valor se puede encontrar en la fórmula simple n^r es decir, 3^2=9 . Este es el producto / unión cartesiano para usuarios familiarizados con SQL.

Hay dos formas de limitar esto: 1) eliminar las relaciones personales (no permitir repeticiones), o 2) eliminar las opciones ordenadas de manera diferente (es decir, combinaciones).

Combinaciones con repeticiones.

Si queremos eliminar las opciones ordenadas de forma diferente, utilizamos:

> combinations(n = 3, r = 2, repeats.allowed = T, v = c("a", "b", "c")) [,1] [,2] [1,] "a" "a" [2,] "a" "b" [3,] "a" "c" [4,] "b" "b" [5,] "b" "c" [6,] "c" "c"

Lo que nos da 6 opciones. ¡La fórmula para este valor es (r+n-1)!/(r!*(n-1)!) decir (2+3-1)!/(2!*(3-1)!)=4!/(2*2!)=24/4=6 .

Permutaciones sin repetición.

Si por el contrario queremos rechazar repeticiones, usamos:

> permutations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c")) [,1] [,2] [1,] "a" "b" [2,] "a" "c" [3,] "b" "a" [4,] "b" "c" [5,] "c" "a" [6,] "c" "b"

Lo que también nos da 6 opciones, pero diferentes! El número de opciones es el mismo que el anterior pero es una coincidencia. El valor se puede encontrar en la fórmula n!/(nr)! es decir (3*2*1)/(3-2)!=6/1!=6 .

Combinaciones sin repeticiones.

Lo más limitante es cuando no queremos auto-relaciones / repeticiones u opciones ordenadas de manera diferente, en cuyo caso usamos:

> combinations(n = 3, r = 2, repeats.allowed = F, v = c("a", "b", "c")) [,1] [,2] [1,] "a" "b" [2,] "a" "c" [3,] "b" "c"

lo que nos da solo 3 opciones. El número de opciones se puede calcular a partir de la fórmula bastante compleja n!/(r!(nr)!) decir, 3*2*1/(2*1*(3-2)!)=6/(2*1!)=6/2=3 .


Si los dos vectores son iguales, existe la función de combinations en el paquete gtools :

library(gtools) combinations(n = 3, r = 2, v = c("aa", "ab", "cc"), repeats.allowed = TRUE) # [,1] [,2] # [1,] "aa" "aa" # [2,] "aa" "ab" # [3,] "aa" "cc" # [4,] "ab" "ab" # [5,] "ab" "cc" # [6,] "cc" "cc"

Y sin "aa" "aa" , etc.

combinations(n = 3, r = 2, v = c("aa", "ab", "cc"), repeats.allowed = FALSE)


Tratar:

factors <- c("a", "b", "c") all.combos <- t(combn(factors,2)) [,1] [,2] [1,] "a" "b" [2,] "a" "c" [3,] "b" "c"

Esto no incluirá duplicados de cada factor (por ejemplo, "a" "a"), pero puede agregarlos fácilmente si es necesario.

dup.combos <- cbind(factors,factors) factors factors [1,] "a" "a" [2,] "b" "b" [3,] "c" "c" all.combos <- rbind(all.combos,dup.combos) factors factors [1,] "a" "b" [2,] "a" "c" [3,] "b" "c" [4,] "a" "a" [5,] "b" "b" [6,] "c" "c"