R expand.grid 有行限制
R expand.grid with row restrictions
我有一个长度为 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 替换为 x <- 11:55 以观察这一点)。理想情况下,会有一个 expand.grid 函数允许在构建完整矩阵之前对行进行限制,这(至少对于我想要的)将使矩阵大小保持在内存限制内。
有没有办法在不对大 N 造成问题的情况下实现这一点?
您的问题与组合的数量有关。
您似乎在做的是在长度为 x.
的序列中列出 0 和 1 的所有不同组合
在您的示例中,x 的长度为 5,您有 2^5=32 种组合
当 x 的长度为 22 时,您有 2^22=4194304 种组合。
您不能改用二进制编码吗?
在你的情况下,这意味着
0代表00000
1代表00001
2代表00010
3代表00011
...
它不会完全解决你的问题,但你应该能比现在更进一步。
试试这个:
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))))))
我有一个长度为 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 替换为 x <- 11:55 以观察这一点)。理想情况下,会有一个 expand.grid 函数允许在构建完整矩阵之前对行进行限制,这(至少对于我想要的)将使矩阵大小保持在内存限制内。
有没有办法在不对大 N 造成问题的情况下实现这一点?
您的问题与组合的数量有关。 您似乎在做的是在长度为 x.
的序列中列出 0 和 1 的所有不同组合在您的示例中,x 的长度为 5,您有 2^5=32 种组合 当 x 的长度为 22 时,您有 2^22=4194304 种组合。
您不能改用二进制编码吗? 在你的情况下,这意味着 0代表00000 1代表00001 2代表00010 3代表00011 ...
它不会完全解决你的问题,但你应该能比现在更进一步。
试试这个:
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))))))