两个向量的所有可能组合,同时保持R中的顺序

时间:2016-05-23 14:36:57

标签: r vector

我有一个矢量,比如vec1,另一个名为vec2的矢量如下:

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

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

我正在寻找的是vec1vec2的所有可能组合,而向量的顺序是&#39}。元素被保留。也就是说,结果矩阵应该是这样的:

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

两个载体不允许重复。也就是说,结果矩阵的所有行都有唯一的元素。

我实际上正在寻找最有效的方式。解决此问题的一种方法是生成长度为n的所有可能的排列,这些排列是按要求增长的(此处为n=5),然后应用过滤。但随着n的增长,它耗费时间。

有没有一种有效的方法呢?

2 个答案:

答案 0 :(得分:13)

试试这个:

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

我们的想法是生成所有索引组合,以便放置vec1的元素。

答案 1 :(得分:2)

不像Marat Talipov解决方案那么优雅,但你可以做到:

# 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