2013-04-01 4 views
13

lapplyを使用して同様の関数のリストを作成しようとすると、リストのすべての関数が同じで、最終要素がどのようなものであるかがわかります。lapplyから匿名関数を返す - 何がうまくいかないのですか?

次のことを考えてみましょう:あなたは同じ結果を得るため、これらの機能を評価しようとすると

pow <- function(x,y) x^y 
pl <- lapply(1:3,function(y) function(x) pow(x,y)) 
pl 
[[1]] 
function (x) 
pow(x, y) 
<environment: 0x09ccd5f8> 

[[2]] 
function (x) 
pow(x, y) 
<environment: 0x09ccd6bc> 

[[3]] 
function (x) 
pow(x, y) 
<environment: 0x09ccd780> 

:ここで何が起こっているか

pl[[1]](2) 
[1] 8 
pl[[2]](2) 
[1] 8 
pl[[3]](2) 
[1] 8 

、そしてどのように私は(私が望む結果を得ることができますリスト内の正しい機能)?

+0

私はわからないが、あなたの目標は何ですか。たぶん 'pl < - function(x、y)lapply(y、function(y)pow(x、y)); pl(2,1:3) '? – Roland

+0

Ross Ihaka(RCore)のこれらのメモは役立つかもしれません(特にレイジー評価についての部分)www.stat.auckland.ac.nz/~ihaka/downloads/Waikato-WRUG.pdf –

+0

これはもはやR 3.2.0、以下の私の答えを見てください。 – jhin

答えて

20

Rは、値そのものではなく、promisesです。この約束は、渡されたときではなく、最初に評価された時に強制され、その時には質問の中でコードを使用するとインデックスが変更されます。

pl <- lapply(1:3, function(y) { force(y); function(x) pow(x,y) }) 
+0

ありがとう、この落とし穴がどのように機能するか知っているのは良いことです。私は将来このことを念頭に置いておく必要があります。 – James

4

これはもはやR 3.2.0のように真ではありません:forceに外側の無名関数が呼び出されると、それは明確に読者に作る時に約束を次のようにコードを書くことができます!

change logの対応する行を読み取ります。このような機能を適用し、それらが遅延評価との間の 望ましくない相互作用を除去するために適用する関数に)(今 力引数を減らすよう

高次機能可変キャプチャ を閉じます。

そして実際:

pow <- function(x,y) x^y 
pl <- lapply(1:3,function(y) function(x) pow(x,y)) 
pl[[1]](2) 
# [1] 2 
pl[[2]](2) 
# [1] 4 
pl[[3]](2) 
# [1] 8 
+0

それは良いニュースです。 – James