長さ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)
助けていただければ幸いです!
おかげで、
あなたが探しています expand.grid
。
expand.grid(0:1, 0:1, 0:1)
または、長い場合:
n <- 14
l <- rep(list(0:1), n)
expand.grid(l)
@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の行が作成されます。
0と1を扱っているので、整数をビットで考えるのは自然なことのようです。この post (MyIntToBit
以下)から少し変更された関数を使用して、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
これは、以前の回答に対する異なるアプローチです。 1と0の14個の値のすべての可能な組み合わせが必要な場合、0から(2 ^ 14)-1までのすべての可能な数を生成し、それらのバイナリ表現を保持するようなものです。
n <- 14
lapply(0:(2^n-1), FUN=function(x) head(as.integer(intToBits(x)),n))