我有一个长度为N的数值向量x,并且想要创建所有以下集合的内集合和的向量:x元素的任何可能组合,每个组合中最多M个元素。我把一个缓慢的迭代方法放在一起;我在这里寻找的是一种不使用任何循环的方式。
考虑我一直采用的方法,在下面的例子中,N = 5且M = 4
M <- 4
x <- 11:15
y <- as.matrix(expand.grid(rep(list(0:1), length(x))))
result <- y[rowSums(y) <= M, ] %*% x
然而,当N变大(对我来说超过22)时,expand.grid输出变得太大并且给出错误(用x&lt; - 11:55替换上面的x来观察这个)。理想情况下,会有一个expand.grid函数,它允许在构造完整矩阵之前对行进行限制,这(至少对于我想要的)将矩阵大小保持在内存限制内。
有没有办法实现这一点而不会导致大N的问题?
答案 0 :(得分:2)
你的问题与大量的组合有关。 您似乎正在做的是以x的长度序列列出0和1的所有不同组合。
在你的例子中,x长度为5,你有2 ^ 5 = 32种组合 当x的长度为22时,你有2 ^ 22 = 4194304个组合。
你不能使用二进制编码吗? 在你的情况下,这意味着 0代表00000 1代表00001 2代表00010 3代表00011 ...
它不会完全解决你的问题,但你应该能够比现在更进一步。
答案 1 :(得分:1)
试试这个:
c(0, unlist(lapply(1:M, function(k) colSums(combn(x, k)))))
它生成的结果与expand.grid方法相同,如下所示,显示测试数据。
M <- 4
x <- 11:15
# expand.grid approach
y <- as.matrix(expand.grid(rep(list(0:1), length(x))))
result <- y[rowSums(y) <= M, ] %*% x
# combn approach
result1 <- c(0, unlist(lapply(1:M, function(k) colSums(combn(x, k)))))
all(sort(result[,1]) == sort(result1))
# [1] TRUE
这应该很快(我的机器需要0.227577秒,N = 22,M = 4):
x <- 1:22 # N = 22
M <- 4
c(0, unlist(lapply(1:M, function(k) colSums(combn(x, k)))))
# [1] 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 3 4 5 6 7
您可能希望使用
选择总和的唯一值unique(c(0, unlist(lapply(1:M, function(k) colSums(combn(x, k))))))