2013-08-13 16 views
7

Tôi đã đi qua some examples trong hướng dẫn của hadley để chức năng, và đã gặp một vấn đề bất ngờ.

Giả sử tôi có một danh sách các đối tượng mô hình,

x=1:3;y=3:1; bah <- list(lm(x~y),lm(y~x)) 

và muốn trích xuất một cái gì đó từ mỗi (như đề xuất trong câu hỏi hadley về một danh sách gọi là "thử nghiệm"). Tôi đã mong đợi một trong những hoạt động này:

lapply(bah,`$`,i='call') # or... 
lapply(bah,`$`,call) 

Tuy nhiên, các giá trị trả lại này là rỗng. Nó có vẻ như tôi không lạm dụng các $ chức năng, như những điều này làm việc:

`$`(bah[[1]],i='call') 
`$`(bah[[1]],call) 

Dù sao, tôi chỉ làm điều này như một bài tập và tò mò nơi sai lầm của tôi là. Tôi biết tôi có thể sử dụng một chức năng ẩn danh, nhưng nghĩ rằng phải có một cách để sử dụng cú pháp tương tự như không giải pháp ban đầu của tôi. Tôi đã xem qua các địa điểm $ được đề cập trong ?Extract, nhưng không thấy bất kỳ giải thích rõ ràng nào.

Tôi chỉ nhận ra rằng công trình này:

lapply(bah,`[[`,i='call') 

và điều này

lapply(bah,function(x)`$`(x,call)) 

Có lẽ đây chỉ là đi xuống đến một số lapply voodoo mà đòi hỏi chức năng ẩn danh mà không phải là cần thiết? Tôi cảm thấy như tôi đã nghe nói rằng một nơi nào đó trên SO trước.

+2

Không có voodoo. Hàm "$" không đánh giá các đối số của nó, trong khi "[[" làm. –

+3

@DWin - bạn có thể vui lòng giải thích, tôi không hiểu ý bạn là gì? – eddi

+0

@Dwin Có lẽ đây chỉ là trên đầu của tôi, nhưng tôi không rõ ràng về những gì đánh giá có nghĩa ở đây. Dường như để đánh giá args okay khi được gọi trực tiếp, như trong '\' $ \ '(bah [[1]], i = 'call')' ...? (argh: thoát backticks nội tuyến là gây phiền nhiễu) – Frank

Trả lời

4

này được ghi chép lại trong ?lapply, trong "Ghi chú" phần (tôi nhấn mạnh):

Vì lý do lịch sử, các cuộc gọi được tạo ra bởi lapply là unevaluated, và mã đã được viết (ví dụ bquote) mà dựa vào điều này. Điều này có nghĩa là cuộc gọi được ghi lại luôn có dạng FUN(X[[0L]], ...), với 0L được thay thế bằng chỉ số nguyên hiện tại. Đây không phải là thường là một vấn đề, nhưng có thể là nếu FUN sử dụng sys.call hoặc match.call hoặc nếu đó là chức năng nguyên thủy sử dụng cuộc gọi . Điều này có nghĩa là nó thường an toàn hơn để gọi các hàm nguyên thủy với trình bao bọc, ví dụ: lapply(ll, function(x) is.numeric(x)) là bắt buộc trong R 2.7.1 để đảm bảo rằng phương thức gửi cho is.numeric xảy ra chính xác.

+0

Tôi vẫn còn một chút nhầm lẫn - những gì kêu gọi '$' -function hiện này 'lapply (bah, \' $ \ ', 'gọi')' kết quả? Nó dường như không phải là '\' $ \ '(bah [[1L]], 'gọi')' là cách tôi đọc được ghi chú đó (nếu bạn thay thế '...' bằng ''call'' và' FUN 'với' \ '$ \' '). – eddi

+4

'\' $ \ '(bah [[1L]], ...)' – Peyton

+0

@Peyton ahhh, tôi hiểu, cảm ơn! – eddi