2016-05-23 27 views
8

ho un vettore, dicono vec1, e un altro vettore chiamato vec2 come segue:tutte le possibili combinazioni di due vettori, mantenendo l'ordine in R

vec1 = c(4,1) 
# [1] 4 1 

vec2 = c(5,3,2) 
# [1] 5 3 2 

Quello che sto cercando è tutte le possibili combinazioni di vec1 e vec2 mentre viene mantenuto l'ordine degli elementi dei vettori. Cioè, la matrice risultante dovrebbe essere così:

> res 
     [,1] [,2] [,3] [,4] [,5] 
[1,] 4 1 5 3 2 
[2,] 4 5 1 3 2 
[3,] 4 5 3 1 2 
[4,] 4 5 3 2 1 
[5,] 5 4 1 3 2 
[6,] 5 4 3 1 2 
[7,] 5 4 3 2 1 
[8,] 5 3 4 1 2 
[9,] 5 3 4 2 1 
[10,] 5 3 2 4 1 

# res=structure(c(4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 1, 5, 5, 5, 4, 4, 4, 
# 3, 3, 3, 5, 1, 3, 3, 1, 3, 3, 4, 4, 2, 3, 3, 1, 2, 3, 1, 2, 1, 
# 2, 4, 2, 2, 2, 1, 2, 2, 1, 2, 1, 1), .Dim = c(10L, 5L)) 

Non è consentita la ripetizione di due vettori. Cioè, tutte le righe della matrice risultante hanno elementi unici.

In realtà sto cercando il modo più efficiente. Un modo per affrontare questo problema è generare tutte le possibili permutazioni di lunghezza n che cresce in modo fattoriale (n=5 qui) e quindi applicare il filtro. Ma richiede molto tempo con lo sviluppo di n.

Esiste un modo efficace per farlo?

+0

Quindi, è chiaro che non vuoi permutazioni, ma che cosa esattamente cosa si intende per "mantenere l'ordine"? Che tutti gli elementi di 'vec2' devono apparire nell'ordine indicizzato originale (e lo stesso per' vec1'), ma non c'è limite se un elemento di un input precede qualsiasi elemento dell'altro? Quindi, cosa succede se c'è un valore comune in entrambi i vettori? O è garantito che non accada? –

risposta

13

Prova questo:

nv1 <- length(vec1) 
nv2 <- length(vec2) 
n <- nv1 + nv2 

result <- combn(n,nv1,function(v) {z=integer(n);z[v]=vec1;z[-v]=vec2;z}) 

L'idea è di produrre tutte le combinazioni di indici in cui inserire gli elementi di vec1.

+0

Grazie mille! idea molto carina Solo una piccola modifica. 't (risultato)' deve essere restituito. – 989

2

Non che elegante come soluzione Marat Talipov, ma si può fare:

# get the ordering per vector 
cc <- c(order(vec1,decreasing = T), order(vec2, decreasing = T)+length(vec1)) 
cc 
[1] 1 2 3 4 5 

# permutation to get all "order-combinations" 
library(combinat) 
m <- do.call(rbind, permn(cc)) 

# remove unsorted per vector, only if both vectors are correct set TRUE for both: 
gr <- apply(m, 1, function(x){ 
      !is.unsorted(x[x < (length(vec1)+1)]) & !is.unsorted(x[x > (length(vec1))]) 
     }) 

# result, exchange the order index with the vector elements: 
t(apply(m[gr, ], 1, function(x, y) y[x], c(vec1, vec2))) 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 4 1 5 3 2 
[2,] 4 5 3 1 2 
[3,] 4 5 3 2 1 
[4,] 4 5 1 3 2 
[5,] 5 4 1 3 2 
[6,] 5 4 3 2 1 
[7,] 5 4 3 1 2 
[8,] 5 3 4 1 2 
[9,] 5 3 4 2 1 
[10,] 5 3 2 4 1