2013-04-01 37 views
13

Khi cố gắng tạo danh sách các hàm tương tự bằng cách sử dụng lapply, tôi thấy rằng tất cả các hàm trong danh sách đều giống nhau và bằng với yếu tố cuối cùng.Trả về các chức năng ẩn danh từ một cách lapply - điều gì đang xảy ra?

xem xét như sau:

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> 

Khi bạn cố gắng để đánh giá các chức năng này bạn sẽ có được kết quả giống hệt nhau:

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

gì đang xảy ra ở đây, và làm thế nào tôi có thể nhận được kết quả tôi mong muốn (các chức năng chính xác trong danh sách)?

+0

Tôi không chắc chắn, những gì mục tiêu của bạn là. Có thể 'pl <- function (x, y) lapply (y, hàm (y) pow (x, y)); pl (2,1: 3) '? – Roland

+0

Những ghi chú của Ross Ihaka (RCore) có thể hữu ích (đặc biệt là phần về Đánh giá Lười biếng) www.stat.auckland.ac.nz/~ihaka/downloads/Waikato-WRUG.pdf –

+0

Lưu ý rằng điều này không còn đúng với R 3.2.0, xem câu trả lời của tôi dưới đây. – jhin

Trả lời

20

R vượt qua promises, không phải bản thân các giá trị. Lời hứa bị ép buộc khi nó được đánh giá lần đầu tiên, không phải khi nó được thông qua, và vào thời điểm đó chỉ số đã thay đổi nếu một người sử dụng mã trong câu hỏi. Mã này có thể được viết như sau để force lời hứa lúc anonymous function bên ngoài được gọi và để làm cho nó rõ ràng đối với người đọc:

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

Cảm ơn, rất tốt để biết cách thức hoạt động của pitfall này. Tôi sẽ phải ghi nhớ điều này trong tương lai. – James

4

này không còn đúng như của R 3.2.0!

Dòng tương ứng trong change log đọc:

chức năng bậc cao như áp dụng các chức năng và giảm() bây giờ đối số lực lượng chức năng mà họ áp dụng để loại bỏ tương tác không mong muốn giữa đánh giá lười biếng và biến chụp trong bao đóng.

Và quả thực:

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

Đó là tin tốt. – James

Các vấn đề liên quan