2014-05-22 96 views
2

我在R中工作,想將矢量傳遞給函數。向量給出了一系列for循環的最大值。如果矢量是(3,4,6,5),那麼應該運行下面的代碼。所以for循環的數量取決於傳遞給函數的向量的長度。然後針對每種可能性,計數器被輸入到另一個函數fn。爲下面的可能的fn提供了一個例子。R中的循環變量數

S=0 
fn = function(x){sum(x^2)} 

for (i in 0:3){ 
    for (j in 0:4){ 
     for (k in 0:6){ 
     for (l in 0:5){ 
      S=S+fn(c(i,j,k,l)) 
     } 
    } 
    } 
} 

我認爲遞歸是去這裏的路,但我沒有任何運氣想出來的,而且大部分的遞歸的例子,我已經看到了似乎是在一個非常高或非常低的水平。

任何想法解決這個問題的最佳方法是?

回答

6

無需使用循環

f <- function(vec, fn){ 
    vecs <- mapply(seq, 0, vec) 
    tmp <- do.call(expand.grid, vecs) 
    tmp <- apply(tmp, 1, fn) 
    sum(tmp) 
} 

fn = function(x){sum(x^2)} 
f(c(3, 4, 6, 5), fn = fn) 
+0

@ user20650如果你想要,你可以做到這一點。它不符合OP的規範,但需要更多的工作。它也只是將函數應用於整個展開的網格,而不是按行。在這種情況下,它給出了相同的答案,但是如果要以不同的方式處理列,則可能無法解決問題。 – Dason

+0

歡呼,幾乎只要我張貼刪除:) – user20650

+0

謝謝,這是非常有益的。我應該提到 - 矢量可能相當長,矢量中的值可能相當大。這是一個相對快速的解決方案還是可以改進? – user3666707

1

我喜歡@達誠的版本使用expand.grid,但這裏是針對當這種做法可能無法正常工作,或一般的啓示遞歸版本:

recfun <- function(a,b) { 
    S <- 0 
    if(length(b)) { 
     for(i in seq(0,b[1])) { 
      S <- S + Recall(c(a,i), b[-1]) 
     } 
    } else { 
     return(fn(a)) 
    } 
    S 
} 

recfun(numeric(0), c(3,4,6,5)) 

對於實際應用,您可能想要將其包含在另一個需要感興趣的向量的函數中,並將其作爲b傳遞給函數b,其空向量爲a