2013-07-31 28 views
4

我具有相等长度的两个对象(一个是通过解析JSON产生的列表,并且另一个是多维阵列的切片),例如:是否可以在foreach中使用zip迭代器(即“压缩”两个迭代器)?

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

我需要能够做如下:

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]] 
} 

是否有任何标准的方式来做到这一点(如在Python/C + +与增压Zip迭代器)?

回答

4

有一个在itertools包的izip功能,做你的描述:

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

但我更喜欢指定多个循环变量foreach

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

这两种解决方案迭代值从迭代器并行。如果你想要一个列表中的两个参数,那么izip更方便。

+0

太棒了!我认为它是关于通过压缩(压缩)文件进行迭代的...我只是创建了自己的izip迭代器,甚至将它命名为'izipiter'以避免与'izip'的名称冲突...现在我感觉非常愚蠢。至少我学到了一些关于迭代器构造的知识。谢谢! –

+0

@AdamRyczkowski我将它命名为Python itertools包中的izip函数。事实上,大部分迭代器和foreach软件包都是从Python复制的。例如,foreach尝试复制Python列表解析。 –

1

这可能不是正是你需要的,但希望它至少可能让你在正确的轨道上:

library(foreach) 

X = 1:10 
Y = 11:20 

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

是的,这是奇怪,但它正确地对这些数据。如果你传入一个数据帧,foreach遍历列而不是行(这并不令人惊讶,因为lapply做同样的事情)。因此,将数据帧转置为遍历行,但对象是列向量,所以我们需要对行进行索引,而不是像我们预期的那样对列进行索引。

+0

谢谢。它当然有诀窍。这不是很简单,也没有文件记录的技巧,是吗? –

+0

很高兴我能帮到你。您也可以尝试使用其他数据结构(如矩阵)来尝试使用此策略,以防将数据转换为df,从而减慢操作速度。正如你所看到的,我只在10条配对记录上试过了这个,但我假设你使用foreach和迭代器后可能有更多的数据。 –

0

在史蒂夫韦斯顿的回答之后,没有什么可以补充的;我会发布我自己的zip迭代器的工作版本,所以学习如何与R中的迭代器一起生活的人会受益。该迭代器被命名为izipiter,以避免与现有的迭代器izip发生名称冲突。

library(foreach)  
izipiter<- function(iters) 
{ 
    nextEl<-function() 
    { 
     tryCatch(
     { 
     foreach(it=iters,.combine=list) %do% 
      nextElem(it) 
     }, error=function(e) {stop("StopIteration")}) 
    } 
    obj<-list(nextElem=nextEl) 
    class(obj) <- c('izipiter','abstractiter','iter') 
    obj 
} 

这是如何使用它:

it1=iter(c(3,5,15)) 
it2=iter(list(x="a",y="b",z=c("one","two","three"))) 

myit=izipiter(iters=list(it1,it2)) 

foreach(it=myit) %do% 
    print(it)