没有for循环的R二进制详尽列表
R binary exhaustive list without for loop
我正在尝试找出列表中一定数量的 1 和 0 的每一种可能组合,没有任何重叠。我希望列表包含一系列矩阵。
我想出了下面的代码,它实现了这个目标,例如,如果你想在 2x2 矩阵中有 2 个值 1 和 2 个值 0:
z<-0
for(i in 1:(4-1)){
for(j in (i+1):(4)){
x<-rep(0,4)
x[c(i,j)]<-1
x<-matrix(x,nrow=2,byrow=TRUE)
z<-z+1
k[[z]]<-x
}}
很好,但我希望能够创建包含更多 0 和 1 的列表。
我知道如何做到这一点的唯一方法是嵌套越来越多的 for 循环
例如,为了在 3x3 矩阵的 9 个空格中打印 3 个 1 的每个非重复组合:
for(i in 1:(9-2)){
for(j in (i+1):(9-1)){
for(k in (j+1):9){
x<-rep(0,9)
x[c(i,j,k)]<-1
x<-matrix(x,nrow=3,byrow=TRUE)
print(x)
}}}
我觉得必须有一个更优雅、更快捷的解决方案(尤其是在处理大量数字时)。即使一个简单的解决方案只能给我向量,也很容易让它们成为一个矩阵列表。我想在列表中枚举可变数量的 1 和 0,以便我可以使用它们进行进一步的操作。
感谢您的帮助!
这是执行此操作的函数。第一个参数是矩阵边的大小,第二个参数是想要的个数:
makematrix <- function(n, k){
z <- as.data.frame(t(expand.grid(rep(list(c(0,1)), n * n))))
z <- z[ ,colSums(z) == k]
lapply(z, function(x){matrix(x, nrow = n)})
}
首先,我们使用 expand.grid
将数据框中的所有 0 和 1 组合起来,用具有正确数量的 1 的子集进行子集化,然后我们使用 [=13] 将它们重新排列成一个矩阵列表=].
makematrix(2, 2)
$V4
[,1] [,2]
[1,] 1 0
[2,] 1 0
$V6
[,1] [,2]
[1,] 1 1
[2,] 0 0
$V7
[,1] [,2]
[1,] 0 1
[2,] 1 0
$V10
[,1] [,2]
[1,] 1 0
[2,] 0 1
$V11
[,1] [,2]
[1,] 0 0
[2,] 1 1
$V13
[,1] [,2]
[1,] 0 1
[2,] 0 1
您也可以直接使用库 combinat
,其中 permn
函数给出直接列表:
library(combinat)
unique(permn(c(1,1,0,0),function(x) matrix(x,nrow=sqrt(length(x)))))
#[[1]]
# [,1] [,2]
#[1,] 1 0
#[2,] 1 0
#[[2]]
# [,1] [,2]
#[1,] 1 1
#[2,] 0 0
#[[3]]
# [,1] [,2]
#[1,] 0 1
#[2,] 1 0
#[[4]]
# [,1] [,2]
#[1,] 0 0
#[2,] 1 1
#[[5]]
# [,1] [,2]
#[1,] 1 0
#[2,] 0 1
#[[6]]
# [,1] [,2]
#[1,] 0 1
#[2,] 0 1
我正在尝试找出列表中一定数量的 1 和 0 的每一种可能组合,没有任何重叠。我希望列表包含一系列矩阵。
我想出了下面的代码,它实现了这个目标,例如,如果你想在 2x2 矩阵中有 2 个值 1 和 2 个值 0:
z<-0
for(i in 1:(4-1)){
for(j in (i+1):(4)){
x<-rep(0,4)
x[c(i,j)]<-1
x<-matrix(x,nrow=2,byrow=TRUE)
z<-z+1
k[[z]]<-x
}}
很好,但我希望能够创建包含更多 0 和 1 的列表。
我知道如何做到这一点的唯一方法是嵌套越来越多的 for 循环
例如,为了在 3x3 矩阵的 9 个空格中打印 3 个 1 的每个非重复组合:
for(i in 1:(9-2)){
for(j in (i+1):(9-1)){
for(k in (j+1):9){
x<-rep(0,9)
x[c(i,j,k)]<-1
x<-matrix(x,nrow=3,byrow=TRUE)
print(x)
}}}
我觉得必须有一个更优雅、更快捷的解决方案(尤其是在处理大量数字时)。即使一个简单的解决方案只能给我向量,也很容易让它们成为一个矩阵列表。我想在列表中枚举可变数量的 1 和 0,以便我可以使用它们进行进一步的操作。
感谢您的帮助!
这是执行此操作的函数。第一个参数是矩阵边的大小,第二个参数是想要的个数:
makematrix <- function(n, k){
z <- as.data.frame(t(expand.grid(rep(list(c(0,1)), n * n))))
z <- z[ ,colSums(z) == k]
lapply(z, function(x){matrix(x, nrow = n)})
}
首先,我们使用 expand.grid
将数据框中的所有 0 和 1 组合起来,用具有正确数量的 1 的子集进行子集化,然后我们使用 [=13] 将它们重新排列成一个矩阵列表=].
makematrix(2, 2)
$V4
[,1] [,2]
[1,] 1 0
[2,] 1 0
$V6
[,1] [,2]
[1,] 1 1
[2,] 0 0
$V7
[,1] [,2]
[1,] 0 1
[2,] 1 0
$V10
[,1] [,2]
[1,] 1 0
[2,] 0 1
$V11
[,1] [,2]
[1,] 0 0
[2,] 1 1
$V13
[,1] [,2]
[1,] 0 1
[2,] 0 1
您也可以直接使用库 combinat
,其中 permn
函数给出直接列表:
library(combinat)
unique(permn(c(1,1,0,0),function(x) matrix(x,nrow=sqrt(length(x)))))
#[[1]]
# [,1] [,2]
#[1,] 1 0
#[2,] 1 0
#[[2]]
# [,1] [,2]
#[1,] 1 1
#[2,] 0 0
#[[3]]
# [,1] [,2]
#[1,] 0 1
#[2,] 1 0
#[[4]]
# [,1] [,2]
#[1,] 0 0
#[2,] 1 1
#[[5]]
# [,1] [,2]
#[1,] 1 0
#[2,] 0 1
#[[6]]
# [,1] [,2]
#[1,] 0 1
#[2,] 0 1