2012-09-09 47 views
6

我有以下嵌套循環:遍歷向量的笛卡爾積

for (x in xs) { 
    for (y in ys) { 
     # Do something with x and y 
    } 
} 

其中我想拉平,所以我想建立兩個向量xsys的笛卡爾乘積並遍歷結果。在Python中,這將是微不足道的:

for xy in product(xs, ys): 
    # x, y = xy[0], xy[1] 

但在R,我發現最簡單的等同相當嚴峻:

xys <- expand.grid(xs, ys) 
for (i in 1 : nrow(xys)) { 
    xy <- as.vector(xys[i, ]) 
    # x <- xy[1], y <- xy[2] 
} 

當然必須有一個更好的辦法,不是嗎? (爲了澄清,我不想遍歷索引 ...我認爲必須有一種方法可以直接迭代產品中的元組。)

回答

8

您可以使用apply函數將函數應用於數據框的每一行。只需用您的實際功能替換"your function"即可。

# example data 
xs <- rnorm(10) 
ys <- rnorm(10)  

apply(expand.grid(xs, ys), 1, FUN = function(x) {"your function"}) 

這是一個非常基本的例子。在這裏,這兩個值的連續總和計算:

apply(expand.grid(xs, ys), 1, FUN = function(x) {x[1] + x[2]}) 

下面是一個使用命名參數(xsys)的變體,而不是指數(x[1]x[2]):

myfun <- function(xs, ys) xs + ys 
arguments <- expand.grid(xs = rnorm(10), ys = rnorm(10)) 
apply(arguments, 1, function(x)do.call(myfun, as.list(x))) 
+0

@Konrad Rudolph:我放棄了我的答案。它沒有錯。我不確定它是否完全是您尋找的解決方案。 @flodel正確地說明了在混合輸入類型中使用'apply'的問題。在這種情況下,您可以使用'as.numeric'將字符串轉換爲數字值。但只要您只使用數字矢量,就沒有問題。 –

10

R有與Python不同的範例,不要期望它具有生成器或元組 - 我們有向量和索引。

這種方式,映射在笛卡爾積函數只需調用

outer(xs,ys,function(x,y) ...) 

,如果你想undim結果。

編輯:在殼體xsys是東西比基矢量更復雜,一個選擇是使用指數,即

outer(seq(a=xs),seq(a=ys),function(xi,yi) ... xs[[xi]]/ys[xi,]/etc. ...) 

,或者使用地圖上的位的手工製作的產品的功能mapply

mapply(function(x,y) ...,xs,rep(ys,each=length(xs))) 
+0

我不關心不同的範例。我很擔心我的代碼中索引變量的普遍性。據我瞭解R,大多數/所有這些應該是不必要的。你的示例代碼看起來像我搜索它的行爲是錯誤的:'outer(1:2,3:4,function(x,y){print(sprintf('%d,%d', x,y))}' - 這會打印一個數組*和*結果矩陣 - 所以我不知道如何重寫我的循環在這裏工作......(我不知道你的意思是「undim」 ) –

+0

Uuh,前面的評論是愚蠢的,矩陣只是'outer'的返回值,不過,我仍然不確定如何調整它以替代我的嵌套循環,因爲'x'和'y'是向量,而不是標量。不幸的是,我確實需要標量。 –

+0

@KonradRudolph好的,擴展。 – mbq