2016-07-20 81 views
4

我希望創建包含兩個不同值的向量的所有可能的排列,其中我控制每個值的比例。R-找到值的唯一排列

例如,如果我有長度爲三的向量,我想含有單個1中的所有可能的組合,我期望的輸出是一個看起來像這樣列表:

list.1 <- list(c(1,0,0), c(0,1,0), c(0,0,1)) 

相反,如果我希望所有包含三個1秒種可能的組合,我所希望的輸出是一個看起來像這個名單:

list.3 <- list(c(1,1,1)) 

換一種方式,不管10值的模式,但所有1 S的關係是湯治療d與所有其他1 s相同。

基於搜索這裏和其他地方,我已經試過幾種方法:

expand.grid(0:1, 0:1, 0:1) # this includes all possible combinations of 1, 2, or 3 ones 
permn(c(0,1,1))    # this does not treat the ones as identical (e.g. it produces (0,1,1) twice) 
unique(permn(c(0,1,1)))  # this does the job! 

因此,使用該功能permncombinat很有前途的包。然而,當我擴大這件事對我的實際問題(長度20的載體,用50個%1和50個%0,我碰到的問題:

unique(permn(c(rep(1,10), rep(0, 10)))) 

# returns the error: 
Error in vector("list", gamma(n + 1)) : 
    vector size specified is too large 

我的理解是,這是因爲發生在來電permn,它使包含所有可能的排列,儘管其中許多是相同的,並且這個名單是太大的R處理列表。

沒有人有怎樣來解決這個身邊?

建議

對不起,如果這已被回答以前 - 有許多,許多SO問題包含類似的語言,但不同的p roblems和我沒有能夠找到滿足我的需求的解決方案!

+2

[這](http://stackoverflow.com/a/28368933/3184024)應該幫助 – wici

回答

1

它不應該是一個破壞者,expand.grid包括所有排列。只需添加後的一個子集:

combinations <- function(size, choose) { 

    d <- do.call("expand.grid", rep(list(0:1), size)) 
    d[rowSums(d) == choose,] 

} 

combinations(size=10, choose=3) 
# Var1 Var2 Var3 Var4 Var5 Var6 Var7 Var8 Var9 Var10 
# 8  1 1 1 0 0 0 0 0 0  0 
# 12 1 1 0 1 0 0 0 0 0  0 
# 14 1 0 1 1 0 0 0 0 0  0 
# 15 0 1 1 1 0 0 0 0 0  0 
# 20 1 1 0 0 1 0 0 0 0  0 
# 22 1 0 1 0 1 0 0 0 0  0 
... 
1

問題的確是,你最初計算所有階乘(20)(〜10^18)排列,這將不適合你的記憶。 您正在尋找的是一種計算多重集合排列的有效方法。該multicool包可以做到這一點:

library(multicool) 

res <- allPerm(initMC(c(rep(0,10),rep(1,10)))) 

這種計算髮生在我的筆記本電腦大約兩分鐘,但肯定是可行的。

+0

這不會產生所需的輸出。你可以發佈'head(res)'嗎? –

+0

這個解決方案似乎適用於我;兩者都生產了184,756個與rowsums == 10的組合。但是,我選擇Pierre的解決方案在<1秒內運行(而不是在我的計算機上約90秒)。 –