在R中生成一个列表的所有不同的排列

我试图创build列表的排列列表,例如, perms(list("a", "b", "c"))返回

 list(list("a", "b", "c"), list("a", "c", "b"), list("b", "a", "c"), list("b", "c", "a"), list("c", "a", "b"), list("c", "b", "a")) 

我不知道如何进行,任何帮助将不胜感激。

combinat::permn将完成这项工作:

 > library(combinat) > permn(letters[1:3]) [[1]] [1] "a" "b" "c" [[2]] [1] "a" "c" "b" [[3]] [1] "c" "a" "b" [[4]] [1] "c" "b" "a" [[5]] [1] "b" "c" "a" [[6]] [1] "b" "a" "c" 

请注意,如果元素很大,则计算量很大。

一段时间后,我不得不在基地R做这个没有加载任何包。

 permutations <- function(n){ if(n==1){ return(matrix(1)) } else { sp <- permutations(n-1) p <- nrow(sp) A <- matrix(nrow=n*p,ncol=n) for(i in 1:n){ A[(i-1)*p+1:p,] <- cbind(i,sp+(sp>=i)) } return(A) } } 

用法:

 > matrix(letters[permutations(3)],ncol=3) [,1] [,2] [,3] [1,] "a" "b" "c" [2,] "a" "c" "b" [3,] "b" "a" "c" [4,] "b" "c" "a" [5,] "c" "a" "b" [6,] "c" "b" "a" 

你可以从gtools包中尝试permutations() ,但是与permn()不同,它不会输出一个列表:

 > library(gtools) > permutations(3, 3, letters[1:3]) [,1] [,2] [,3] [1,] "a" "b" "c" [2,] "a" "c" "b" [3,] "b" "a" "c" [4,] "b" "c" "a" [5,] "c" "a" "b" [6,] "c" "b" "a" 

基地R也可以提供答案:

 all <- expand.grid(p1 = letters[1:3], p2 = letters[1:3], p3 = letters[1:3], stringsAsFactors = FALSE) perms <- all[apply(all, 1, function(x) {length(unique(x)) == 3}),] 
 # Another recursive implementation # for those who like to roll their own, no package required permutations <- function( x, prefix = c() ) { if(length(x) == 0 ) return(prefix) do.call(rbind, sapply(1:length(x), FUN = function(idx) permutations( x[-idx], c( prefix, x[idx])), simplify = FALSE)) } permutations(letters[1:3]) # [,1] [,2] [,3] #[1,] "a" "b" "c" #[2,] "a" "c" "b" #[3,] "b" "a" "c" #[4,] "b" "c" "a" #[5,] "c" "a" "b" #[6,] "c" "b" "a" 

尝试:

 > a = letters[1:3] > eg = expand.grid(a,a,a) > eg[!(eg$Var1==eg$Var2 | eg$Var2==eg$Var3 | eg$Var1==eg$Var3),] Var1 Var2 Var3 6 cba 8 bca 12 cab 16 acb 20 bac 22 abc 

正如@Adrian在评论中所build议的那样,最后一行可以replace为:

 eg[apply(eg, 1, anyDuplicated) == 0, ] 

基础R中的解决scheme,不依赖于其他软件包:

 > getPerms <- function(x) { if (length(x) == 1) { return(x) } else { res <- matrix(nrow = 0, ncol = length(x)) for (i in seq_along(x)) { res <- rbind(res, cbind(x[i], Recall(x[-i]))) } return(res) } } > getPerms(letters[1:3]) [,1] [,2] [,3] [1,] "a" "b" "c" [2,] "a" "c" "b" [3,] "b" "a" "c" [4,] "b" "c" "a" [5,] "c" "a" "b" [6,] "c" "b" "a" 

我希望这有帮助。

一个有趣的解决scheme“概率”使用样本基R:

 elements <- c("a", "b", "c") k <- length(elements) res=unique(t(sapply(1:200, function(x) sample(elements, k)))) # below, check you have all the permutations you need (if not, try again) nrow(res) == factorial(k) res 

基本上你会打电话给很多随机样本,希望能把它们全部拿出来,而且你是独一无二的。