web-dev-qa-db-ja.com

ベクトルの要素の可能なすべての組み合わせのリストを生成する

長さ14のベクトルで0と1のすべての可能な組み合わせを生成しようとしています。その出力をベクトルのリスト、またはさらに良いのはデータフレームとして取得する簡単な方法はありますか?

私が探しているものをより良く示すために、長さ3のベクトルのみが必要であると仮定しましょう。次のものを生成できるようにしたいと思います。

 (1,1,1), (0,0,0), (1,1,0), (1,0,0), (1,0,1), (0,1,0), (0,1,1), (0,0,0)

助けていただければ幸いです!

おかげで、

42
Mayou

あなたが探しています expand.grid

expand.grid(0:1, 0:1, 0:1)

または、長い場合:

n <- 14
l <- rep(list(0:1), n)

expand.grid(l)
74
Justin

@Justinのアプローチの代替として、「data.table」パッケージのCJを使用することもできます。ここでは、replicateを使用して14個のゼロと1のリストを作成しました。

library(data.table)
do.call(CJ, replicate(14, 0:1, FALSE))
#        V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 V11 V12 V13 V14
#     1:  0  0  0  0  0  0  0  0  0   0   0   0   0   0
#     2:  0  0  0  0  0  0  0  0  0   0   0   0   0   1
#     3:  0  0  0  0  0  0  0  0  0   0   0   0   1   0
#     4:  0  0  0  0  0  0  0  0  0   0   0   0   1   1
#     5:  0  0  0  0  0  0  0  0  0   0   0   1   0   0
#    ---                                               
# 16380:  1  1  1  1  1  1  1  1  1   1   1   0   1   1
# 16381:  1  1  1  1  1  1  1  1  1   1   1   1   0   0
# 16382:  1  1  1  1  1  1  1  1  1   1   1   1   0   1
# 16383:  1  1  1  1  1  1  1  1  1   1   1   1   1   0
# 16384:  1  1  1  1  1  1  1  1  1   1   1   1   1   1

tidyrには、expand.grid()と同様のオプションがいくつかあります。

tidyr::crossing()はティブルを返し、文字列をファクターに変換しません(expand.grid(..., stringsAsFactors = F)を実行できますが)。

_library(tidyr)

crossing(var1 = 0:1, var2 = 0:1, var3 = 0:1)
# A tibble: 8 x 3
   var1  var2  var3
  <int> <int> <int>
1     0     0     0
2     0     0     1
3     0     1     0
4     0     1     1
5     1     0     0
6     1     0     1
7     1     1     0
8     1     1     1
_

tidyr::expand()は、次のように、データに表示される値のみの両方の組み合わせを提供できます。

_expand(mtcars, nesting(vs, cyl))
# A tibble: 5 x 2
     vs   cyl
  <dbl> <dbl>
1     0     4
2     0     6
3     0     8
4     1     4
5     1     6
_

または、次のように、データ内のデータに特定の値が含まれる観測値がない場合でも、2つの変数のすべての可能な組み合わせ:

_expand(mtcars, vs, col)
# A tibble: 6 x 2
     vs   cyl
  <dbl> <dbl>
1     0     4
2     0     6
3     0     8
4     1     4
5     1     6
6     1     8
_

(vs == 1&cyl == 8である元のデータには観測がなかったことがわかります)

tidyr::complete()expand.grid()と同様に使用できます。これはドキュメントの例です:

_df <- dplyr::tibble(
  group = c(1:2, 1),
  item_id = c(1:2, 2),
  item_name = c("a", "b", "b"),
  value1 = 1:3,
  value2 = 4:6
)
df %>% complete(group, nesting(item_id, item_name))

# A tibble: 4 x 5
  group item_id item_name value1 value2
  <dbl>   <dbl> <chr>      <int>  <int>
1     1       1 a              1      4
2     1       2 b              3      6
3     2       1 a             NA     NA
4     2       2 b              2      5
_

これにより、各グループのitem_idとitem_nameの可能なすべての組み合わせが得られます。グループ2 item_id 1およびitem_name aの行が作成されます。

5
sbha

0と1を扱っているので、整数をビットで考えるのは自然なことのようです。この postMyIntToBit以下)から少し変更された関数を使用して、apply関数の選択とともに、目的の結果を得ることができます。

MyIntToBit <- function(x, Dig) {
    i <- 0L
    string <- numeric(Dig)
    while (x > 0) {
        string[Dig - i] <- x %% 2L
        x <- x %/% 2L
        i <- i + 1L
    }
    string
}

リストが必要な場合は、lapplyを次のように使用します。

lapply(0:(2^14 - 1), function(x) MyIntToBit(x,14))

マトリックスを好む場合、sapplyがトリックを行います:

sapply(0:(2^14 - 1), function(x) MyIntToBit(x,14))

以下に出力例を示します。

> lapply(0:(2^3 - 1), function(x) MyIntToBit(x,3))
[[1]]
[1] 0 0 0

[[2]]
[1] 0 0 1

[[3]]
[1] 0 1 0

[[4]]
[1] 0 1 1

[[5]]
[1] 1 0 0

[[6]]
[1] 1 0 1

[[7]]
[1] 1 1 0

[[8]]
[1] 1 1 1


> sapply(0:(2^3 - 1), function(x) MyIntToBit(x,3))
      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,]    0    0    0    0    1    1    1    1
[2,]    0    0    1    1    0    0    1    1
[3,]    0    1    0    1    0    1    0    1 
3
Joseph Wood

これは、以前の回答に対する異なるアプローチです。 1と0の14個の値のすべての可能な組み合わせが必要な場合、0から(2 ^ 14)-1までのすべての可能な数を生成し、それらのバイナリ表現を保持するようなものです。

n <- 14
lapply(0:(2^n-1), FUN=function(x) head(as.integer(intToBits(x)),n))
1