2014-10-19 88 views
4

在R中,我試圖爲矢量的每個元素創建一個閉包,並讓它在運行時訪問該特定元素。如何爲R中向量中的每個元素創建一個閉包?

我有值的矢量:

the.vector <- c('a', 'b', 'c') 

如果我運行它迭代向量,運行一個簡單的函數返回的每個元件的功能,最終的結果將是list('a', 'b', 'c')。它是這樣的(輸出被簡化爲簡潔起見):

Test1 <- function() { 
    lapply(the.vector, function(element) { 
    element 
    }) 
} 

Test1() 
list('a', 'b', 'c') 

現在,如果我迭代向量,創建訪問每個元件的封閉件,然後用迭代該和運行每個閉合,該結果是list('c', 'c', 'c')(!)。它看起來像這樣:

Test2 <- function() { 
    closures <- lapply(the.vector, function(element) { 
    function() { 
     element 
    } 
    }) 
    lapply(closures, function(closure) { 
    closure() 
    }) 
} 

Test2() 
list('c', 'c', 'c') 

總結:我想內封閉引用每個元素,從而使Test2結果是一樣的Test1

我敢肯定,這是由於R解析變量名的方式,因爲它確實是詞法範圍;我可能會以動態範圍的方式進行討論。但是,這並不能解決我的問題,我不知道該怎麼做。

達到理想效果的最佳方法是什麼?

回答

6

問題是,在Test2應用循環中,您實際上並沒有使用變量element,所以它仍然是一個「承諾」,並且當您運行該函數時最終解決該承諾時,您將獲得最後一個已知值變量是「c」。解決此問題的最簡單方法是使用force()函數

Test2 <- function() { 
    closures <- lapply(the.vector, function(element) { 
    force(element) 
    function() { 
     element 
    } 
    }) 
    lapply(closures, function(closure) { 
    closure() 
    }) 
} 
+0

哇。棒極了!我很想了解更多。你知道任何參考,我可以找到更多的?非常感謝! – 2014-10-19 02:32:49

+0

有關承諾的討論有點[這裏](http://adv-r.had.co.nz/Computing-on-the-language.html),當然你會發現該指南的其餘部分也很有用。 – MrFlick 2014-10-19 03:23:29

相關問題