在R中生成长度为n的所有可能的二进制向量

时间:2018-02-25 20:23:22

标签: r vector binary

我希望在R中生成长度为n的所有可能的二进制向量。这样做的最佳方法(最好是计算效率和可读代码)是什么?

3 个答案:

答案 0 :(得分:5)

n = 3
expand.grid(replicate(n, 0:1, simplify = FALSE))
#  Var1 Var2 Var3
#1    0    0    0
#2    1    0    0
#3    0    1    0
#4    1    1    0
#5    0    0    1
#6    1    0    1
#7    0    1    1
#8    1    1    1

答案 1 :(得分:0)

受到this question的启发,生成所有可能包含小于 n 1的长度m的二进制向量,我已扩展此代码以生成所有可能的组合。但这并不漂亮。

> z <- 3
> z <- rep(0, n)
> do.call(rbind, lapply(0:n, function(i) t(apply(combn(1:n,i), 2, function(k) {z[k]=1;z}))))
     [,1] [,2] [,3]
[1,]    0    0    0
[2,]    1    0    0
[3,]    0    1    0
[4,]    0    0    1
[5,]    1    1    0
[6,]    1    0    1
[7,]    0    1    1
[8,]    1    1    1

它在做什么?一旦我们将其剥离,这个单线程的核心如下:

apply(combn(1:n,i), 2, function(k) {z[k]=1;z})

要理解这一点,让我们进一步退一步。函数combn(x,m)一次生成x m的所有可能组合。

> combn(1:n, 1)
     [,1] [,2] [,3]
[1,]    1    2    3
> combn(1:n, 2)
     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    2    3    3
> combn(1:n, 3)
     [,1]
[1,]    1
[2,]    2
[3,]    3

对于使用apply(MARGIN=2),我们一次将此函数的一列传递给我们的内部函数function(k) {z[k]=1;z},它只是用{{1}替换索引k处的所有值。 }}。因为它们最初都是1,所以这给了我们每个可能的二元向量。

其余的只是橱窗装饰。 0为我们提供了一个宽而短的矩阵;我们用combn转置它。 t返回一个列表;我们将列表的每个元素中的矩阵与lapply绑定在一起。

答案 2 :(得分:0)

你应该定义什么是“最好的方式”(最快的?最短的代码?等)。

一种方法是使用包R.utils和函数intToBin将十进制数转换为二进制数。参见示例。

require(R.utils)
n <- 5
strsplit(intToBin(0:(2 ^ n - 1)), split = "")