2013-02-14 26 views
21

Tôi đọc this basic question về cách đổi tên đối tượng và câu trả lời của @Shane cho nó, chỉ cho tôi đánh giá lười biếng. Bây giờ tôi tự hỏi nếu assign được đánh giá lười biếng, quá. Cũng giống như ở đây:Đánh giá lười biếng trong R - được chỉ định bị ảnh hưởng?

assign("someNewName",someOldObject) 
rm(someOldObject) 

Lý do tại sao tôi tự hỏi về việc này là các trường hợp sử dụng như sau: Giả sử tôi có 10K + R đối tượng mỗi trong số đó có hai thuộc tính gọi là originalNameadditionalName. Bây giờ tôi muốn viết một hàm có hiệu quả có thể cho phép người dùng chuyển từ tên này sang tên khác mà không làm mất hai thuộc tính này. Gần giống như thế này ...

EDIT: dựa trên @ Hadley, tôi đã thay đổi mã của mình.

switchObjectName <- function(x) { 
    n1 <- attributes(x)$originalName 
    n2 <- attributes(x)$additionalName 
    objName <- deparse(substitute(x)) 
    if(objName == n1) { 
    delayedAssign(n2,x,assign.env=.GlobalEnv) 
    } else { 
    delayedAssign(n1,x,assign.env=.GlobalEnv) 
    } 
    rm(list=c(objName),envir=.GlobalEnv)  
} 

hoạt động tốt, nhưng tôi đã gặp một số rắc rối khi nhận được tuyên bố rm. Tôi đã thử rm(objName,envir=.GlobalEnv) nhưng không thể làm cho nó hoạt động mặc dù objName chắc chắn là một nhân vật gây ra nó là kết quả của deparse(substitute(x).

+12

Nếu tôi hiểu chính xác câu hỏi của bạn, hãy xem phần 'delayAssign', https://github.com/hadley/pryr/blob/master/R/assign-delayed.r và phần "Chuyển nhượng: tên liên kết với giá trị" trên https://github.com/hadley/devtools/wiki/environments – hadley

+0

cảm ơn một lần nữa. đặc biệt là con trỏ đến chương trong wiki của bạn đã giúp rất nhiều điều để hiểu những gì đang diễn ra. 'delayAssign' là gợi ý đúng. –

Trả lời

5

Ngôn ngữ R thường có ngữ nghĩa giá trị. Bài tập x <- y có nghĩa là xy sẽ là các bản sao độc lập của cùng một đối tượng (cập nhật trên yx sẽ độc lập). Việc triển khai ngây thơ của x <- y sẽ luôn phân bổ bộ nhớ cho x và sao chép hoàn toàn y vào đó. GNU-R thay vì sử dụng một cơ chế sao chép trên ghi, nó sẽ trì hoãn bản sao cho đến khi một cập nhật thực sự xảy ra, giúp tiết kiệm thời gian bộ nhớ/thực thi trong trường hợp nó không xảy ra. Người dùng R không cần phải biết về tối ưu hóa này, nó hoàn toàn minh bạch (ngoại trừ một số trường hợp hiếm gặp như lỗi ngoài bộ nhớ). Cơ chế này áp dụng cho bài tập được viết là x <- yassign("x", y) như nhau.

Đánh giá lười biếng là một phần của thiết kế ngôn ngữ và hiển thị với người dùng R/lập trình viên. Các biểu thức được chuyển thành các đối số cho một hàm, ví dụ: trong foo(ls()) biểu thức được thông qua là ls(), được đánh giá uể oải, chỉ khi và khi cần thiết bằng cách thực hiện hàm được gọi.

delayedAssign là chức năng cấp thấp, hiển thị cho người dùng R/lập trình viên, nhưng thực sự chỉ được sử dụng để tải gói chậm và không cần thiết trong chương trình người dùng. delayedAssign cho phép chỉ định một biểu thức để tính toán giá trị của một biến; việc tính toán sẽ xảy ra một cách lười biếng chỉ khi/khi biến được đọc lần đầu tiên.

Vì vậy, để trả lời câu hỏi, một nhiệm vụ trong R luôn là '' lười '' trong đó cơ chế sao chép-ghi-ghi được sử dụng. Việc tính toán phía bên phải của nhiệm vụ cũng có thể là lười biếng (sử dụng delayedAssign), nhưng điều đó không cần thiết/được sử dụng bởi các chương trình người dùng.

Tôi nghĩ cho '' đổi tên '' của các biến, không cần sử dụng delayedAssign (vì phía bên tay phải không được tính toán). Nó chỉ làm cho tình hình phức tạp hơn và có khả năng sẽ có hiệu suất cao hơn do việc giữ sổ sách delayedAssign phải làm. Tôi sẽ chỉ sử dụng phân công bình thường nếu tôi phải đổi tên biến.

Để rõ ràng về mã, tôi cũng sẽ cố gắng tránh việc xóa các biến khỏi môi trường và thậm chí chỉ định từ một hàm vào môi trường toàn cầu, ví dụ: Tôi sẽ chỉ tạo một danh sách mới và chèn các ràng buộc mới (các biến) vào nó.Sau khi đã đề cập đến cơ chế sao chép trên ghi, với việc thực hiện hiện tại trong GNU-R, bất kỳ giải pháp được mô tả nào cũng có khả năng gây ra việc sao chép bộ nhớ mà không cần thiết phải có các biến không được đổi tên. Không có cách nào để tránh điều này ở mức R.

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