2012-08-23 30 views
9

Cách tốt nhất để xác định một chức năng mục đích chung nào cần thực hiện cho cả hai lớp S3 và S4? Tôi đã sử dụng một cái gì đó như thế này:Kết hợp các phương pháp S4 và S3 trong một hàm duy nhất

setGeneric("myfun", function(x, ...){ 
    standardGeneric("myfun"); 
}); 

setMethod("myfun", "ANY", function(x, ...) { 
    if(!isS4(x)) { 
     return(UseMethod("myfun")); 
    } 
    stop("No implementation found for class: ", class(x)); 
}); 

này thành công:

myfun.bar <- function(x, ...){ 
    return("Object of class bar successfully dispatched."); 
} 
object <- structure(123, class=c("foo", "bar")); 
myfun(object) 

Có một động thái cách "tự nhiên" để thực hiện điều này? Tôi biết chúng ta có thể định nghĩa các phương thức S4 cho các lớp S3 bằng cách sử dụng setOldClass, tuy nhiên theo cách này chúng ta mất phương thức S3 gửi đi trong trường hợp một đối tượng có nhiều lớp. Ví dụ. (Trong một phiên sạch):

setGeneric("myfun", function(x, ...){ 
    standardGeneric("myfun"); 
}); 

setOldClass("bar") 
setMethod("myfun", "bar", function(x, ...){ 
    return("Object of class bar successfully dispatched."); 
}); 

object <- structure(123, class=c("foo", "bar")); 
myfun(object) 

này sai vì lớp thứ hai của object, trong trường hợp này bar, được bỏ qua. Chúng tôi có thể sửa lỗi này bằng cách xác định thừa kế S4 chính thức giữa foobar, nhưng đối với ứng dụng của tôi, tôi muốn có myfun.bar để làm việc ra khỏi hộp trên đối tượng S3 với lớp bar.

Dù bằng cách nào, mọi thứ đang trở nên lộn xộn, và tôi đoán đây là một vấn đề phổ biến, vì vậy có lẽ cách tốt hơn để làm điều này?

+0

Xem thêm http://stackoverflow.com/questions/12709933/adding-s4-dispatch-to-base-r-s3-generic cho trường hợp đặc biệt thêm công văn S4 vào chung S3 trong cơ sở R. –

Trả lời

13

Phần "Phương pháp cho S3 chức năng chung" của? Phương pháp đề xuất một S3 chung, một phương pháp S3 phong cách cho lớp S4, và phương pháp S4 chính nó.

setClass("A")     # define a class 

f3 <- function(x, ...)   # S3 generic, for S3 dispatch  
    UseMethod("f3") 
setGeneric("f3")     # S4 generic, for S4 dispatch, default is S3 generic 
f3.A <- function(x, ...) {}  # S3 method for S4 class 
setMethod("f3", "A", f3.A)  # S4 method for S4 class 

Cần chung S3 để gửi các lớp S3.

SetGeneric() đặt f3 (tức là, S3 chung) làm mặc định và f3, BẤT K-phương pháp thực sự là chung chung của S3. Vì 'BẤT K' 'ở (sắp xếp) gốc của phân cấp lớp, bất kỳ đối tượng nào (ví dụ, các đối tượng S3) mà phương thức S4 không tồn tại kết thúc tại tổng quát S3.

Định nghĩa của S3 chung cho lớp S4 được mô tả trên trang trợ giúp? Tôi nghĩ, xấp xỉ, S3 không biết về phương pháp S4, vì vậy nếu ta gọi chung S3 (ví dụ, bởi vì một trong không gian tên gói nơi gói biết về S3 f3 nhưng không phải là S4 f3) chung f3 sẽ không tìm thấy phương pháp S4. Tôi chỉ là người đưa tin.

+0

Vì vậy, điều đó có nghĩa là các phương pháp S4 được tìm kiếm đầu tiên trên cơ sở chữ ký của chúng và không khớp, các phương thức S3 sau đó được gửi đi? –

+0

@DWin có đúng là –

+0

Bạn có thể giải thích tại sao dòng đầu tiên và dòng cuối cùng là cần thiết không? – Jeroen

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