2016-03-12 14 views
5

Tôi đang đọc cuốn sách Nâng cao R của Hadley Wickham, cụ thể là hướng dẫn viên của OO (http://adv-r.had.co.nz/OO-essentials.html). Bài tập đầu tiên trong chương đó như sau:Tại sao hàm t trả về giá trị t.test cho các đối tượng có lớp được đặt thành "test"?

Đọc mã nguồn cho t() và t.test() và xác nhận rằng t.test() là một phương thức S3 chung và không phải là S3. Điều gì xảy ra nếu bạn tạo một đối tượng có kiểm tra lớp và gọi t() với nó?

Nếu tôi hiểu chương này một cách chính xác, chúng tôi có thể xác nhận rằng t() và t.test() là chung, vì chúng sử dụng hàm UseMethod() trong mã nguồn. phương thức (t) trả về t.data.frame, t.default và t.ts * như các phương thức của hàm t(). Tại sao sau đó, nếu cả hai đều là S3 generics và t không có phương thức t.test, thì mã sau có trả về test t không?

a <- structure(1:4, class = "test") 
t(a) 

Dự đoán của tôi sẽ là sử dụng phương pháp mặc định cho lớp "test" và t.default (a) chuyển vị trí theo logic mà tôi cho là đúng. Vậy t.test đến từ đâu?

Trả lời

6

Nếu bạn chạy t(a), trong đó a là đối tượng của bạn thuộc lớp test, thì UseMethod("t") được gọi. Điều này sẽ kiểm tra xem lớp học của đối số đầu tiên bạn cung cấp cho t() là gì. Lớp học là test và R bây giờ sẽ là tìm kiếm một hàm t.test(). Kể từ khi t.test() tồn tại, t.test(a) được chạy. Điều này được gọi là "phương thức công văn".

Chỉ khi t.test() không tồn tại, R sẽ sử dụng để gọi số t.default(). Bạn có thể thực sự thậm chí nhìn thấy điều này xảy ra, bằng cách tách các gói stats trước khi chạy t(a):

a <- structure(1:4, class = "test") 
detach("package:stats") 
t(a) 
##  [,1] [,2] [,3] [,4] 
## [1,] 1 2 3 4 
## attr(,"class") 
## [1] "test" 

Câu hỏi đặt ra hiện nay là, tại sao t.test không nằm trong danh sách, khi bạn chạy methods("t"). Khi bạn nhìn vào mã nguồn của methods(), bạn sẽ thấy rằng nó gọi là .S3methods(). Hàm này biên dịch tên của tất cả các phương thức của t. Tuy nhiên, tại một số điểm, nó loại bỏ các tên hàm được chứa trong S3MethodsStopList:

info <- info[grep(name, row.names(info)), ] 
info <- info[!row.names(info) %in% S3MethodsStopList, 
    ] 

(Nếu tôi chạy chỉnh sửa (.S3methods) trong RStudio, đây là những dòng 47 và 48).

S3MethodsStopList được định nghĩa trước đó (trên dòng 15):

S3MethodsStopList <- tools:::.make_S3_methods_stop_list(NULL) 

Chức năng tools:::.make_S3_methods_stop_list() có vẻ như không được ghi chép lại, nhưng nó chỉ có vẻ để trả về một danh sách mã hóa cứng của tên hàm chứa một dấu chấm, nhưng thực tế không phải phương pháp. t.test() là một trong số họ:

grep("^t\\.", tools:::.make_S3_methods_stop_list(NULL), value = TRUE) 
##     Hmisc6    calibrator     mosaic    mratios1 
##  "t.test.cluster"    "t.fun"    "t.test"  "t.test.ration" 
##    mratios2    mratios3     stats6 
## "t.test.ratio.default" "t.test.ratio.formula" 

Nói tóm lại, methods() không rõ ràng lọc ra các chức năng được biết không phải là phương pháp. Phương pháp điều phối, mặt khác, chỉ cần tìm một hàm có tên thích hợp.

+0

OK! Cảm ơn bạn đã giải thích kỹ lưỡng! – M4RT1NK4

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