如何使用迭代器包创建“演练”迭代器?在每个nextElem返回固定移动窗口的情况下,如何创建迭代器?
例如,假设我们有一个10x10矩阵。每个迭代器元素应该是一组行。第一个元素是行1:5,第二个元素是2:6,3:7,4:8....etc
如何将x转换为演练迭代器:
x <- matrix(1:100, 10)编辑:为了清楚起见,我想在并行foreach循环中使用生成的迭代器。
foreach(i = iter(x), .combine=rbind) %dopar% myFun(i)发布于 2014-12-31 21:47:15
您可以使用一个迭代器来返回您所描述的重叠子矩阵,但这将占用比所需的内存多得多的内存。最好使用一个迭代器来返回这些子矩阵的索引。有一种方法可以做到:
iwalk <- function(n, m) {
if (m > n)
stop('m > n')
it <- icount(n - m + 1)
nextEl <- function() {
i <- nextElem(it)
c(i, i + m - 1)
}
obj <- list(nextElem=nextEl)
class(obj) <- c('abstractiter', 'iter')
obj
}这个函数使用来自iterators包的iterators函数,这样我就不必担心诸如抛出"StopIteration“异常之类的细节。这是我在“书写自定义迭代器”中描述的一种技术。
如果您使用的是doMC并行后端,您可以使用这个迭代器,如下所示:
library(doMC)
nworkers <- 3
registerDoMC(nworkers)
x <- matrix(1:100, 10)
m <- 5
r1 <- foreach(ix=iwalk(nrow(x), m)) %dopar% {
x[ix[1]:ix[2],, drop=FALSE]
}这与doMC很好地结合在一起,因为每个工作人员都继承矩阵x。但是,如果将doParallel与集群对象或doMPI后端一起使用,最好避免将整个矩阵x导出给每个工作人员。在这种情况下,我将创建一个迭代器函数,将x的重叠子矩阵发送给每个工作人员,然后使用iwalk对这些子矩阵进行迭代:
ioverlap <- function(x, m, chunks) {
if (m > nrow(x))
stop('m > nrow(x)')
i <- 1
it <- idiv(nrow(x) - m + 1, chunks=chunks)
nextEl <- function() {
ntasks <- nextElem(it)
ifirst <- i
ilast <- i + ntasks + m - 2
i <<- i + ntasks
x[ifirst:ilast,, drop=FALSE]
}
obj <- list(nextElem=nextEl)
class(obj) <- c('abstractiter', 'iter')
obj
}
library(doParallel)
nworkers <- 3
cl <- makePSOCKcluster(nworkers)
registerDoParallel(cl)
x <- matrix(1:100, 10)
m <- 5
r2 <- foreach(y=ioverlap(x, m, nworkers), .combine='c',
.packages=c('foreach', 'iterators')) %dopar% {
foreach(iy=iwalk(nrow(y), m)) %do% {
y[iy[1]:iy[2],, drop=FALSE]
}
}在本例中,我在工作人员而不是主服务器上使用iwalk,这就是为什么iterators包必须由每个工作人员加载的原因。
https://stackoverflow.com/questions/27712863
复制相似问题