我使用iterpc创建了一个迭代器,然后将其包装在iterators::iter包中。
iter<-iterpc(nrow(data),4,ordered=TRUE,replace=TRUE)
it<-iter_wrapper(iter)然后,我使用foreach进行计算。
calcs<-foreach(i=it)%dopar%{
blah}我的问题是我不想使用迭代器中的每一个元素。我想随机选择迭代器的某些元素,比如1000个。(计算时间是个问题)如何选择迭代器的随机子集?
发布于 2016-04-05 01:20:06
我怀疑排列迭代器是按顺序工作的,所以无法随机采样。您可以做的是编写一个迭代器,该迭代器在父迭代器上重复调用nextElem以返回精简版本。这个例子通过一些“瘦”参数创建了一个迭代器的精简版本:
> thinit = function(iterator,thin){
iter(
function(){
for(i in 1:(thin-1)){
nextElem(iterator)
}
nextElem(iterator)}
)
}注意,我在循环中调用了thin-1次,所以最后一次调用是迭代器返回值。
因此,从一个简单的1:100迭代器开始:
> i1 <- iter(1:100)制作一个精简版本:
> i10 = thinit(i1, 10)然后对循环输出进行精简:
> foreach(i=i10) %dopar% {i}
[[1]]
[1] 10
[[2]]
[1] 20
[[3]]
[1] 30现在,您可以让包装器随机调用nextElem多次(只要它返回nextElem调用,它就会作为迭代器工作),以便从父迭代器中随机获取样本。你不可能从排列中准确地得到250个样本,但是如果你知道有2500个排列,你调用nextElem直到runif(1)>.9,你平均会得到250个……或者别的什么。如下所示:
> pthin = function(iterator, p){
iter(
function(){
while(runif(1)<p){
nextElem(iterator)
}
nextElem(iterator)
}
)
}
> i1 <- iter(1:100)
> ip10 = pthin(i1,.9)
> unlist(foreach(i=ip10) %dopar% {i})
[1] 1 9 18 19 22 28 35 38 53 55 63 67 81 84 86 89 95 98
> i1 <- iter(1:100)
> ip10 = pthin(i1,.9)
> unlist(foreach(i=ip10) %dopar% {i})
[1] 15 19 21 24 45 59 63 70 73 76 79 88 94 100
> i1 <- iter(1:100)
> ip10 = pthin(i1,.9)
> unlist(foreach(i=ip10) %dopar% {i})
[1] 10 50 62 76 79 81 97请注意,父迭代器被调用了大N次,但采样意味着{i}中的循环中的肉只被调用了很少的次数,我怀疑这是花费了大部分时间的地方。
如果您确实坚持从父迭代器中获取给定的N个样本,并且您知道迭代器中元素的数量,那么可以从该迭代器中计算N个样本,并使用如上所述的迭代器包装器,该包装器会一直在父迭代器上调用nextElem,直到它到达样本中的下一个索引,然后返回该值。它必须保持闭包中返回哪些样本的状态,就像我的示例一样。目前还不能完全做到这一点(需要更多的咖啡),所以这里有一个替代方法:
创建一个迭代器包装器,它返回一个迭代器,该迭代器生成原始迭代器的值以及从1到N的连续索引号。这类似于python zip函数。然后只在索引号在子集中的那些迭代上工作。应该知道原始迭代器的长度才能生成子集。示例:
这是我的zip迭代器包装器。它返回一个迭代器,用于生成列表元素,其中$index是连续的索引,$value是来自父迭代器的值:
> zipit = function(iz){
itn=1
iter(
function(){
itn<<-itn+1
list(index=itn-1,value=nextElem(iz))
}
)
}现在,根据需要创建一个置换迭代器。我们知道这个元素总共有10个元素,所以从10个元素中生成一个包含4个值的样本:
> I <- iterpc(5, 2)
> it <- iter_wrapper(I)
> subset = sample(10,4)现在,您的主循环有了一个测试,并且只处理(在本例中是值的简单和)子集中的那些迭代:
> foreach(i=zipit(it), .combine=c) %do% {if(i$index %in% subset)sum(i$value)}
[1] 4 7 8 9https://stackoverflow.com/questions/36408016
复制相似问题