在所有排列中混合2个不同的向量

时间:2016-06-16 10:47:22

标签: r

我需要在所有不同的排列中组合两个不同大小的向量。例如:

a <- c(A,B,C)
b <- c(1,2,3,4,5,6)

我需要&#34;混合&#34;他们分成两个向量:

m <- c(1,2,C)
n <- c(A,B,3,4,5,6)

我需要很多这些组合,没有重复。 (所有值的类型将相同)

2 个答案:

答案 0 :(得分:0)

获得单个排列: 如果顺序无关紧要并且假设m的长度为3:

> m  <- sample(union(a,b),3,replace=FALSE)
> n  <- setdiff(union(a,b),m)
> m
[1] "1" "6" "2"
> n
[1] "A" "B" "C" "3" "4" "5"

你也可以随机化m矢量长度来获得

> m  <- sample (union(a,b),sample(1:length(union(a,b)),1),replace=FALSE)
> n  <- setdiff(union(a,b),m)
> m
[1] "1" "C" "B"
> n
[1] "A" "2" "3" "4" "5" "6"

如果顺序很重要并假设自然顺序是{1,2,3,4,5,6,a,b,c}

> n  <-  sort(setdiff(union(a,b),m))
> m  <-  sort(sample (union(a,b),3,replace=FALSE))
> n  <-  sort(setdiff(union(a,b),m))
> m
[1] "3" "B" "C"
> n
[1] "1" "2" "4" "5" "6" "A"

对于所有可能的排列,您需要确定向量长度(当长度(m)= 1时,有9个排列,长度(m)= 2,有36个等等)

答案 1 :(得分:0)

在我看来,你想要置换组合向量。要做到这一点,首先我们需要一个函数来生成排列。这是基础R中的递归实现:

permr <- function(v,r=length(v)) if (r==0L) NULL else do.call(rbind,lapply(seq_along(v),function(i) cbind(v[i],permr(v[-i],r-1L))));

演示:

permr(1:3); ## defaults to full-size subset, i.e. r=n=3
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    1    3    2
## [3,]    2    1    3
## [4,]    2    3    1
## [5,]    3    1    2
## [6,]    3    2    1
permr(1:4,3L); ## permute r=3 of n=4
##       [,1] [,2] [,3]
##  [1,]    1    2    3
##  [2,]    1    2    4
##  [3,]    1    3    2
##  [4,]    1    3    4
##  [5,]    1    4    2
##  [6,]    1    4    3
##  [7,]    2    1    3
##  [8,]    2    1    4
##  [9,]    2    3    1
## [10,]    2    3    4
## [11,]    2    4    1
## [12,]    2    4    3
## [13,]    3    1    2
## [14,]    3    1    4
## [15,]    3    2    1
## [16,]    3    2    4
## [17,]    3    4    1
## [18,]    3    4    2
## [19,]    4    1    2
## [20,]    4    1    3
## [21,]    4    2    1
## [22,]    4    2    3
## [23,]    4    3    1
## [24,]    4    3    2

现在我们可以为任何r

生成组合向量的置换矩阵
a <- c('A','B','C');
b <- 1:6;
permr(c(a,b),3L); ## r=3
##        [,1] [,2] [,3]
##   [1,] "A"  "B"  "C"
##   [2,] "A"  "B"  "1"
##   [3,] "A"  "B"  "2"
##   [4,] "A"  "B"  "3"
##   [5,] "A"  "B"  "4"
##
## ... snip ...
##
## [500,] "6"  "5"  "C"
## [501,] "6"  "5"  "1"
## [502,] "6"  "5"  "2"
## [503,] "6"  "5"  "3"
## [504,] "6"  "5"  "4"

如果您希望获得所有可能的子集大小,我们可以使用lapply()来收集列表中的排列矩阵。虽然现在我们已经在计算工作方面取得了进展:

v <- c(a,b); system.time({ res <- lapply(seq_along(v),function(r) permr(v,r)); });
##    user  system elapsed
##  11.813   0.000  11.824
sapply(res,nrow);
## [1]      9     72    504   3024  15120  60480 181440 362880 362880
lapply(res,head);
## [[1]]
##      [,1]
## [1,] "A"
## [2,] "B"
## [3,] "C"
## [4,] "1"
## [5,] "2"
## [6,] "3"
##
## [[2]]
##      [,1] [,2]
## [1,] "A"  "B"
## [2,] "A"  "C"
## [3,] "A"  "1"
## [4,] "A"  "2"
## [5,] "A"  "3"
## [6,] "A"  "4"
##
## [[3]]
##      [,1] [,2] [,3]
## [1,] "A"  "B"  "C"
## [2,] "A"  "B"  "1"
## [3,] "A"  "B"  "2"
## [4,] "A"  "B"  "3"
## [5,] "A"  "B"  "4"
## [6,] "A"  "B"  "5"
##
## [[4]]
##      [,1] [,2] [,3] [,4]
## [1,] "A"  "B"  "C"  "1"
## [2,] "A"  "B"  "C"  "2"
## [3,] "A"  "B"  "C"  "3"
## [4,] "A"  "B"  "C"  "4"
## [5,] "A"  "B"  "C"  "5"
## [6,] "A"  "B"  "C"  "6"
##
## [[5]]
##      [,1] [,2] [,3] [,4] [,5]
## [1,] "A"  "B"  "C"  "1"  "2"
## [2,] "A"  "B"  "C"  "1"  "3"
## [3,] "A"  "B"  "C"  "1"  "4"
## [4,] "A"  "B"  "C"  "1"  "5"
## [5,] "A"  "B"  "C"  "1"  "6"
## [6,] "A"  "B"  "C"  "2"  "1"
##
## [[6]]
##      [,1] [,2] [,3] [,4] [,5] [,6]
## [1,] "A"  "B"  "C"  "1"  "2"  "3"
## [2,] "A"  "B"  "C"  "1"  "2"  "4"
## [3,] "A"  "B"  "C"  "1"  "2"  "5"
## [4,] "A"  "B"  "C"  "1"  "2"  "6"
## [5,] "A"  "B"  "C"  "1"  "3"  "2"
## [6,] "A"  "B"  "C"  "1"  "3"  "4"
##
## [[7]]
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
## [1,] "A"  "B"  "C"  "1"  "2"  "3"  "4"
## [2,] "A"  "B"  "C"  "1"  "2"  "3"  "5"
## [3,] "A"  "B"  "C"  "1"  "2"  "3"  "6"
## [4,] "A"  "B"  "C"  "1"  "2"  "4"  "3"
## [5,] "A"  "B"  "C"  "1"  "2"  "4"  "5"
## [6,] "A"  "B"  "C"  "1"  "2"  "4"  "6"
##
## [[8]]
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
## [1,] "A"  "B"  "C"  "1"  "2"  "3"  "4"  "5"
## [2,] "A"  "B"  "C"  "1"  "2"  "3"  "4"  "6"
## [3,] "A"  "B"  "C"  "1"  "2"  "3"  "5"  "4"
## [4,] "A"  "B"  "C"  "1"  "2"  "3"  "5"  "6"
## [5,] "A"  "B"  "C"  "1"  "2"  "3"  "6"  "4"
## [6,] "A"  "B"  "C"  "1"  "2"  "3"  "6"  "5"
##
## [[9]]
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
## [1,] "A"  "B"  "C"  "1"  "2"  "3"  "4"  "5"  "6"
## [2,] "A"  "B"  "C"  "1"  "2"  "3"  "4"  "6"  "5"
## [3,] "A"  "B"  "C"  "1"  "2"  "3"  "5"  "4"  "6"
## [4,] "A"  "B"  "C"  "1"  "2"  "3"  "5"  "6"  "4"
## [5,] "A"  "B"  "C"  "1"  "2"  "3"  "6"  "4"  "5"
## [6,] "A"  "B"  "C"  "1"  "2"  "3"  "6"  "5"  "4"
##

如果您有兴趣,我们可以按如下方式找到您的示例排列:

which(apply(res[[3L]],1L,function(v) all(v==c(1,2,'C'))));
## [1] 192
res[[3L]][192L,];
## [1] "1" "2" "C"
which(apply(res[[6L]],1L,function(v) all(v==c('A','B',3:6))));
## [1] 436
res[[6L]][436L,];
## [1] "A" "B" "3" "4" "5" "6"