2016-02-26 72 views
1

我有一些數據,看起來像這樣:所有R可能子組合

basin <- c("Volta","Seine","Limpopo") 
c1 <- c("BEN","BEL","SA") 
c2 <- c("BURK","FRA","MOZ") 
c3 <- c("IVC","LUX","ZIM") 
c4 <- c("GHA","NA","BOTS") 
c5 <- c("MALI","NA","NA") 
c6 <- c("TOGO","NA","NA") 
df <- data.frame(basin, c1, c2, c3, c4, c5, c6) 

    basin c1 c2 c3 c4 c5 c6 
1 Volta BEN BUR IVC GHA MALI TOGO 
2 Seine BEL FRA LUX NA NA NA 
3 Limpopo SA MOZ ZIM BOTS NA NA 

每個流域有k個國家。例如,在第一行中,我需要生成5個國家的所有組合,4個國家的所有組合,等等。第二行我需要生成2個國家和3個國家和2個國家的所有組合的所有組合。然後我想將這些子集添加爲數據中的新行。

我試圖用這個功能:

allSubs <- function(x, k) { 
    if(k > length(x)) stop('k > length(x)') 
    if(choose(length(x), k)==1){ 
    list(as.vector(combn(x, k))) 
    } else { 
    cbn <- combn(x, k) 
    lapply(seq(ncol(cbn)), function(i) cbn[,i]) 
    } 
}  

但是,我只能得到它的工作,如果我給它的數據是這樣的:

allSubs(c('BEN','BURK','IVC','GHA','MALI','TOGO'),4) 

但我真的需要它遍歷通過數據框中的行。我感謝任何幫助。

回答

0

這裏是一個解決方案與數據如下(輸入數據仍然是有點問題和我修改代碼來生成正確的數據):

basin <- c("Volta","Seine","Limpopo") 
c1 <- c("BEN","BEL","SA") 
c2 <- c("BURK","FRA","MOZ") 
c3 <- c("IVC","LUX","ZIM") 
c4 <- c("GHA",NA,"BOTS") 
c5 <- c("MALI",NA,NA) 
c6 <- c("TOGO",NA,NA) 
df <- data.frame(basin, c1, c2, c3, c4, c5, c6, stringsAsFactors = FALSE) 

    basin c1 c2 c3 c4 c5 c6 
1 Volta BEN BURK IVC GHA MALI TOGO 
2 Seine BEL FRA LUX <NA> <NA> <NA> 
3 Limpopo SA MOZ ZIM BOTS <NA> <NA> 

apply(df[, 2:7], 1, function(x) {l <- x[!is.na(x)]; sapply(seq(1:(length(l)-1)), function(y) combn(l, y))}) 

結果將是每個國家代碼的各種子組合每行。希望這可以幫助。當然,你可以將我用於調用apply調用的外部函數的'inline'函數分開。

+0

謝謝你的迴應。我調整了原始文章中的數據以包含NAs(並且還顯示了我是如何創建的)。我不擅長處理R中的數據,這是我的錯誤。我需要這種格式,因爲這只是數據的一小部分,而我試圖讓代碼工作。 – Beatrix

+0

我編輯了答案以適應修改後的數據。不知道這是你正在尋找的輸出,因爲你沒有指定預期的輸出。 – Gopala

+0

太棒了!兩個問題:我將如何調整它以不列出一個組合?我將它改爲'sapply(seq(2:(length(l)-1))',但它沒有做到我想的那樣。另外,我怎樣才能將組合輸出返回到數據框?任何數據框,可以命令盆地的組合輸出? – Beatrix

0

這裏是你想要的固定組合的數量,而不是「n」組合的數量。

expand.grid(c1, c2, c3, c4, c5, c6) 

我建議把c1,c2,c3 ..... cn放在列表中,用這個。

list <- mget(ls(pattern='^c\\d+')) 

這將創建一個列表,你的環境不受基於關閉對象以字母「C」開頭,標題您的數據集更具體,以避免攝入以「C」或任何啓動你指定它的其他對象通過。因此,只需將c替換爲所引用對象的名稱的開始。

expand.grid(list) 

    c1 c2 c3 c4 c5 c6 
1 BEN BURK IVC GHA MALI TOGO 
2 BEL BURK IVC GHA MALI TOGO 
3 SA BURK IVC GHA MALI TOGO 
4 BEN FRA IVC GHA MALI TOGO 
5 BEL FRA IVC GHA MALI TOGO 
6 SA FRA IVC GHA MALI TOGO 
7 BEN MOZ IVC GHA MALI TOGO 
8 BEL MOZ IVC GHA MALI TOGO 
9 SA MOZ IVC GHA MALI TOGO 
10 BEN BURK LUX GHA MALI TOGO 

............................... 

723 SA BURK ZIM BOTS <NA> <NA> 
724 BEN FRA ZIM BOTS <NA> <NA> 
725 BEL FRA ZIM BOTS <NA> <NA> 
726 SA FRA ZIM BOTS <NA> <NA> 
727 BEN MOZ ZIM BOTS <NA> <NA> 
728 BEL MOZ ZIM BOTS <NA> <NA> 
729 SA MOZ ZIM BOTS <NA> <NA> 

如果你想知道如何分配similiar一系列的名字,我建議用玩弄周圍的物體分配功能。

下面是一個例子。

for (i in 2:ncol(df)-1) { 
    assign(paste("Combo",i,sep=""), df[, i+1]) 
} 

如果您不喜歡硬編碼變量名稱,那麼只需要考慮一下。

有關1s,2s,3s,4s,5s,6s .... ns的所有可能組的列表,我將不得不考慮這一點。將盡快回復。

我正在考慮allPerms函數素食包和group_by包在dplyr中的一些組合應該做的伎倆,但我必須看到。

+0

啊,我看到的問題...將不得不實驗...我的壞 – InfiniteFlashChess