R 生成向量元素的所有可能组合的列表

R 生成向量元素的所有可能组合的列表,r,combinations,R,Combinations,我试图在长度为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) 您正在查找展开.grid expand.grid(0:1, 0:1, 0:1) 或者,从长远来看: n <- 14 l <- rep(

我试图在长度为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)

您正在查找
展开.grid

expand.grid(0:1, 0:1, 0:1)
或者,从长远来看:

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

expand.grid(l)

n您正在查找
展开.grid

expand.grid(0:1, 0:1, 0:1)
或者,从长远来看:

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

expand.grid(l)

n有16384种可能的排列。您可以使用
iterpc
包以迭代方式获取结果

library(iterpc)
I = iterpc(2, 14, label=c(0,1), order=T, replace=T)
getnext(I)
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
getnext(I)
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1
getnext(I)
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 1 0

如果您想要所有结果,仍然可以使用
getall(I)

有16384种可能的排列。您可以使用
iterpc
包以迭代方式获取结果

library(iterpc)
I = iterpc(2, 14, label=c(0,1), order=T, replace=T)
getnext(I)
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
getnext(I)
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 1
getnext(I)
# [1] 0 0 0 0 0 0 0 0 0 0 0 0 1 0

如果您想要所有结果,您仍然可以使用
getall(I)

作为@Justin方法的替代方法,您还可以使用“data.table”包中的
CJ
。在这里,我还使用了
replicate
创建了包含14个0和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

作为@Justin方法的替代方法,您还可以使用“data.table”包中的
CJ
。在这里,我还使用了
replicate
创建了包含14个0和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

由于处理的是0和1,所以用位来表示整数似乎很自然。使用一个稍有改动的函数(
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
}
如果您喜欢矩阵,
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 

由于处理的是0和1,所以用位来表示整数似乎很自然。使用一个稍有改动的函数(
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
}
如果您喜欢矩阵,
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 

tidyr
有两个类似于
expand.grid()
的选项

tidyr::crossing()
返回一个TIBLE,并且不将字符串转换为因子(尽管您可以执行
expand.grid(…,stringsafactors=F)

或者两个变量的所有可能组合,即使数据中的数据中没有具有这些特定值的观测值,如下所示:

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

这为每个组提供了项目id和项目名称的所有可能组合-它为组2项目id 1和项目名称a创建了一行。

tidyr
有两个类似于
expand.grid()
的选项

tidyr::crossing()
返回一个TIBLE,并且不将字符串转换为因子(尽管您可以执行
expand.grid(…,stringsafactors=F)

或者两个变量的所有可能组合,即使数据中的数据中没有具有这些特定值的观测值,如下所示:

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

这为每个组提供了项目id和项目名称的所有可能组合-它为第2组项目id 1和项目名称a创建了一行。

这与前面的答案不同。如果您需要14个值1和0的所有可能组合,这就像生成从0到(2^14)-1的所有可能数字,并保留它们的二进制表示

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

n这与前面的答案不同。如果您需要14个值1和0的所有可能组合,这就像生成从0到(2^14)-1的所有可能数字,并保留它们的二进制表示

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

n我在这里讨论一种通用方法来解决所有类似类型的问题,比如这个问题。首先,让我们看看解决方案是如何随着N个数的增加而发展的,以找出一般模式

首先,长度1的解决方案是

0
1
现在,对于长度2,溶液变为(第二列,由|分隔):

将其与长度为1的上一个解进行比较,很明显,要获得这个新解,我们只需将0和1附加到上一个解(第1列,0和1)

现在对于长度3,解决方案是(第3列):

同样,这个新的解决方案是通过将0和1附加到以前的每个解决方案(长度为2的第2列)来获得的

这种观察自然会导致递归解决方案。假设我们已经得到了长度为N-1的解
解(c(0,1),N-1)
,为了得到N的解,我们只需将0和1附加到解N-1的每一项
将每一项附加到列表中(解(c(0,1),len-1),c(0,1))
。请注意,这里更复杂的问题是如何自然分解为更简单的问题的

然后我们只需要将这个简单的英语翻译成R代码,几乎是字面意思:

# assume you have got solution for a shorter length len-1 -> solution(v, len-1) 
# the solution of length len will be the solution of shorter length appended with each element in v 
solution <- function(v, len) {
  if (len<=1) {
    as.list(v)
  } else {
    append_each_to_list(solution(v, len-1), v)
  } 
}

# function to append each element in vector v to list L and return a list
append_each_to_list <- function(L, v) {
  purrr::flatten(lapply(v, 
         function(n) lapply(L, function(l) c(l, n))
         ))
}

我在这里讨论一种通用的方法来解决所有类似类型的问题,比如这个问题。首先,让我们看看解决方案是如何随着N个数的增加而发展的,以找出一般模式

首先,长度1的解决方案是

0
1
现在,对于长度2,溶液变为(第二列,由|分隔):

将其与长度为1的上一个解进行比较,很明显,要获得这个新解,我们只需将0和1附加到上一个解(第1列,0和1)

现在对于长度3,解决方案是(第3列):

同样,这个新的解决方案是通过将0和1附加到以前的每个解决方案(长度为2的第2列)来获得的

这种观察自然会导致递归解决方案。假设我们已经得到了长度为N-1的解
解(c(0,1),N-1)
,为了得到N的解,我们只需将0和1附加到解N-1的每一项
将每一项附加到列表中(解(c(0,1),len-1),c(0,1))
。请注意,这里更复杂的问题是如何自然分解为更简单的问题的