「喰う・書く・逃げる」に棲む処

 動物に関するデータ分析者のブログです

区別可能な要素の組み合わせを生成するRプログラム

"A", "B", "C", "D"

上記のような4つの要素を組み合わせてグループ化(最小1グループ~最大4グループ)すると

1: A = B = C = D (1グループ)

2: A = B = C ≠ D (2グループ)

(3~14は省略)

15: A ≠ B ≠ C ≠ D (4グループ)

の15通り作れます。


これをRで自動で作ってくれるプログラムを書いてみました。

# プログラム
combi_groups=function(vector){
  if(length(vector)<4){
    lapply(1:length(vector),function(x){
      if(x==1){
        paste(combn(vector,1),collapse = " ≠ ")
      }else{
        combns=combn(vector,x)
        sapply(1:ncol(combns),function(y){
          not_equal=vector[!is.element(vector,combns[,y])]
          paste(c(paste(combns[,y],collapse = " = "),not_equal),collapse = " ≠ ")
        })  
      }
    })  
  }else if(length(vector)==4){
    lapply(1:(length(vector)+1),function(x){
      if(x==1){
        paste(combn(vector,1),collapse = " ≠ ")
      }else if(x==2){
        combns=combn(vector,x)
        if(length(vector)%%2==0){
          combns=combns[,1:(ncol(combns)/2)]
        }
        sapply(1:ncol(combns),function(y){
          not_equal=paste(vector[!is.element(vector,combns[,y])],collapse = " = ")
          paste(c(paste(combns[,y],collapse = " = "),not_equal),collapse = " ≠ ")
        })
      }else{
        combns=combn(vector,x-1)
        sapply(1:ncol(combns),function(y){
          not_equal=vector[!is.element(vector,combns[,y])]
          paste(c(paste(combns[,y],collapse = " = "),not_equal),collapse = " ≠ ")
        })  
      }
    })
  }else{
    stop(print("Error: This function cannot calculate with an over five-length vector"))
  }
}


これを実行すると

> combi_groups(c("A","B","C","D"))

[[1]]
[1] "A ≠ B ≠ C ≠ D"

[[2]]
[1] "A = B ≠ C = D" "A = C ≠ B = D" "A = D ≠ B = C"

[[3]]
[1] "A = B ≠ C ≠ D" "A = C ≠ B ≠ D" "A = D ≠ B ≠ C" "B = C ≠ A ≠ D" "B = D ≠ A ≠ C" "C = D ≠ A ≠ B"

[[4]]
[1] "A = B = C ≠ D" "A = B = D ≠ C" "A = C = D ≠ B" "B = C = D ≠ A"

[[5]]
[1] "A = B = C = D"

となります。


要素1個から要素3個にも対応しています。

5要素以上は複雑になるので対応していません。

#要素1個
> combi_groups(c("A"))
[[1]]
[1] "A"

#要素2個
> combi_groups(c("A","B"))
[[1]]
[1] "A ≠ B"

[[2]]
[1] "A = B"

#要素3個
> combi_groups(c("A","B","C"))
[[1]]
[1] "A ≠ B ≠ C"

[[2]]
[1] "A = B ≠ C" "A = C ≠ B" "B = C ≠ A"

[[3]]
[1] "A = B = C"

時間があったら、5要素以上に対応するものに改良するかも