我希望在R中生成长度为n
的所有可能的二进制向量。这样做的最佳方法(最好是计算效率和可读代码)是什么?
答案 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 = "")