[英]R Randomly select a combination
假设我有一个向量x
,其中包含10个数字。 我想选择N次M次子集并将其放入列表对象。 如何确保我选择的内容与列表中的所有元素都是唯一的? 注意顺序无关紧要。 因此c(1,0,3)
与c(3,0,1)
相同。
x = seq(1,10,1)
我可以使用combn(x,N)
来做到这一点,但是在我的x
包含10k或更多元素的情况下,使用combn并随机选择其中的任何一个都不可行。
或者说问题。 我想在不进行替换的情况下随机采样combn(x,N)
的输出。 是否可以不先生成调用combn
?
有任何想法吗?
我想在不进行替换的情况下随机采样combn(x,N)的输出。 是否可以不先生成调用combn?
我不这么认为,不是具有32位整数的当前状态(而bit64
甚至bit64
不错,也无法捕获所有内容)。
combn(10000,4)
:为了能够任意索引combn(10000,4)
返回的combn(10000,4)
,您可能首先要确定一些简单明了的东西,例如“是我四个数字中的第一个为'1'”。 明知第一j
组合产生的迭代将用1(例如,启动1,2,3,4
, 1,2,3,5
,......, 1,2,3,10000
),你认为“所有我需要做的是对照第一组1检查我想要的索引并进行迭代”(寻找2、3等)。 不幸的是,在10k和N=5
,前4.162501e+14
行以“ 1”开头。 (这恰好是choose(10000-1,5-1)
,这不是巧合。)然后,您必须一次又一次地执行此操作,并且计数会增加。
这远远超出了32位整数空间。 N=6
以8.320840e+17
作为第一组1 8.320840e+17
。
要在此空间上执行“随机访问”是相当疯狂的,甚至(我怀疑)本机64位计算也将很快耗尽空间。
我相信您最实用的方法是在他的评论中使用@alistaire的建议代码:
set.seed(42)
x <- seq(1, 10000)
N <- 4
M <- 10
out <- list()
while(length(out) < M) {
out <- c(out,
unique(replicate(M - length(out), sort(sample(x, N)), simplify = FALSE)))
}
str(out)
# List of 10
# $ : int [1:4] 2861 8302 9149 9370
# $ : int [1:4] 1347 5191 6418 7365
# $ : int [1:4] 4577 6570 7050 7189
# $ : int [1:4] 2555 4623 9347 9398
# $ : int [1:4] 1175 4750 5602 9783
# $ : int [1:4] 1387 9041 9464 9887
# $ : int [1:4] 825 3902 5142 9055
# $ : int [1:4] 4470 7375 8109 8360
# $ : int [1:4] 40 3882 6852 8327
# $ : int [1:4] 74 2077 6116 9065
或稍作调整(如果使用更大的N
, M
,速度可能会提高约30%):
set.seed(42)
N <- 8
M <- 100
out <- list()
while (length(out) < M) {
out2 <- split(apply(matrix(sample(lenx, size = M*N, replace = TRUE),
nrow = M, ncol = N),
1, sort),
rep(1:M, each = N))
out <- c(out, out2[ !duplicated(out2) ])
}
如果您知道M*N < length(x)
,那么可以改用replace=FALSE
,这样就可以确保只通过一次while
循环。
我编写了一个函数,提供了对组合的随机访问。 但是,我测试的次数越多,我越会发现它开始崩溃时,这样做会不会确保索引的完全唯一性,也不会保证发生这种情况时会犯错误 。 (因此,我没有发布它。如果有人真的很好奇,我可以脱机提供它。我对惰性的expand.grid
做了类似的expand.grid
,但是从数学expand.grid
这更简单/易于处理;甚至到那时我都没有用它进行测试设置得很大。由于您正在寻找组合而不是排列,因此我认为这不适合。)
底线:不幸的是,R可能不是这个地方。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.