Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have zip iterator (i.e. "zip" two iterators together) in foreach?

I have two objects of equal length (one is a list produced by parsing JSON, and another is a slice of multi-dimensional of an array), e.g.:

library(rjson)
library(foreach)
iter1<-iter( fromJSON(file=jsonfilename)$someJSONarray )
iter2<-iter( myarr, by="row" )

I need to be able to do the following:

out=foreach(x=zipiter(iter1,iter2),combine=list) %do%
{
    #Do stuff with elements from both iterators accessed by e.g. x[[1]] and x[[2]]
}

Is there any standard way of doing it (like in Python/C++ with boost Zip iterator)?

like image 922
Adam Ryczkowski Avatar asked Jul 31 '13 20:07

Adam Ryczkowski


2 Answers

There is an izip function in the itertools package that does what you describe:

library(itertools)
out <- foreach(x=izip(iter1, iter2)) %do% {
    # x[[1]] contains a value from iter1
    # x[[2]] contains a value from iter2
}

But I prefer to specify multiple loop variables to foreach:

out <- foreach(x=iter1, y=iter2) %do% {
    # x contains a value from iter1
    # y contains a value from iter2
}

Both solutions iterate over values from the iterators in parallel. If you want the two arguments in a list, then izip is more convenient.

like image 108
Steve Weston Avatar answered Oct 15 '22 01:10

Steve Weston


This might not be exactly what you need, but hopefully it might at least get you on the right track:

library(foreach)

X = 1:10
Y = 11:20

out = foreach(x=t(data.frame(X, Y))) %do% {x[1,]*x[2,]}

Yes, this is weird, but it properly pairs up the data. If you pass in a dataframe, foreach iterates over the columns instead of the rows (this isn't entirely surprising since lapply does the same thing). So transposing the dataframe results in iteration over the rows, but then the x object is a column vector, so we need to index the rows instead of the columns like we'd expect.

like image 29
David Marx Avatar answered Oct 14 '22 23:10

David Marx