14

を使用して同様の関数のリストを作成しようとすると、リスト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

ここで何が起こっているのか、どうすれば希望する結果 (リスト内の正しい関数) を得ることができますか?

4

2 に答える 2

20

Rは、値自体ではなくpromiseを渡します。promise は、渡されたときではなく、最初に評価されたときに強制されます。問題のコードを使用すると、その時までにインデックスが変更されます。外側の無名関数が呼び出されたときに promiseを強制し、それを読者に明確にするために、コードを次のように書くことができます。

pl <- lapply(1:3, function(y) { force(y); function(x) pow(x,y) } )
于 2013-04-01T11:26:32.960 に答える
8

これは、R 3.2.0 以降では当てはまりません!

変更ログの対応する行は次のとおりです。

apply 関数や Reduce() などの高階関数は、クロージャでの遅延評価と変数キャプチャの間の望ましくない相互作用を排除するために、適用する関数に引数を強制するようになりました。

本当に:

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
于 2015-04-22T02:45:14.343 に答える