2014-08-29 14 views
40

Về cơ bản, khi có nhiều đối số trong setMethod hoặc (setGeneric), nó hoạt động rất chậm.R treo khi có quá nhiều đối số trong setMethod (hoặc setGeneric)

Dưới đây là một ví dụ cơ bản:

setClassUnion(name = "mNumeric", members = c("missing", "numeric")) 
setClass(Class = "classA", representation = representation(ID = "character")) 

setGeneric("foo", function(r, i, ..., m = 1, D = 1, U = 999, K = 0.005, 
          E1 = -5, E2 = 5, E3 = 1, E4 = 1, E5 = 1, E6 = 1, 
          A1 = -5, A2 = 5, A3 = 1, A4 = 1, A5 = 1, A6 = 1) 
        {standardGeneric ("foo")}) 

setMethod(f = "foo", 
    signature = c(r = "ANY", i = "classA", m = "mNumeric", D = "mNumeric", 
       U = "mNumeric", K = "mNumeric", E1 = "mNumeric", E2 = "mNumeric", 
       E3 = "mNumeric", E4 = "mNumeric", E5 = "mNumeric", E6 = "mNumeric", 
       A1 = "mNumeric", A2 = "mNumeric", A3 = "mNumeric", A4 = "mNumeric", 
       A5 = "mNumeric", A6 = "mNumeric"), 
    function(r, i, ..., m, D, U, K, E1, E2, E3, E4, E5, E6, A1, A2, A3, A4, A5, A6) 
    {print("Function can made it here..")}) 

#Program hangs after the following code. (at least five minutes) 
foo(r = 1, i = new("classA", ID = "ID1")) 

tôi quan sát rằng đây không liên quan đến lớp. Bạn có thể đặt một lớp học numeric vào r và nó sẽ làm như vậy. Nếu tôi cắt số đối số thì nó sẽ hoạt động.

Tôi nghi ngờ rằng nó cố gắng "to find an inherited method for function ‘foo’ for signature ‘"numeric", "classA", "missing", ..." và điều này khiến R bị treo. HERE là một cuộc thảo luận tốt về chủ đề này.

Bởi vì nếu tôi chạy cùng một mã với các thông số ít hoạt động:

setGeneric("foo", function(r, i, ..., m = 1, D = 1, U = 999, K = 0.005, 
          E1 = -5, E2 = 5, E3 = 1, E4 = 1) 
      {standardGeneric ("foo")}) 

setMethod(f = "foo", 
    signature = c(r = "ANY", i = "classA", m = "mNumeric", D = "mNumeric", 
       U = "mNumeric", K = "mNumeric", E1 = "mNumeric", E2 = "mNumeric", 
       E3 = "mNumeric", E4 = "mNumeric"), 
    function(r, i, ..., m, D, U, K, E1, E2, E3, E4) 
    {print("Function can made it here..")}) 

foo(r = 1, i = new("classA", ID = "ID1")) 

Tại sao điều này xảy ra? Bất cứ ý tưởng sẽ được đánh giá cao.

+4

Tôi đã thử nghiệm mà không có biến E - không phải 5 phút, nhưng vẫn dài đáng kể. Tôi quan sát thấy rằng chỉ lần đầu tiên khi foo được gọi là phải mất quá lâu. Lần thứ hai foo rất nhanh. Tôi đã cố gắng thay thế 'print' bằng' stop' và truy tìm nó bằng 'options (error = traceback)' để xem tất cả các bước gọi - nhưng mọi thứ có vẻ ổn, chỉ 3 cuộc gọi. Điều này thực sự lạ ... –

+2

@PatrickRoocks Cảm ơn bạn đã xác nhận. Tôi tin rằng phương pháp tra cứu mất rất nhiều thời gian (như được giải thích [ở đây] (http://stackoverflow.com/a/16386422/2275286)). Như bạn đã nói nó là lạ, người ta không thể viết bất kỳ chức năng S4 có hơn 5-6 đầu vào (và lặp lại trong một môi trường mới mỗi lần) nếu đây là trường hợp. – HBat

+0

Bạn có thể đặt mã một cách rõ ràng trong câu hỏi của mình để có thể so sánh các câu trả lời tiềm năng/xung quanh công việc trên cơ sở giảm thời gian gác máy không? Ví dụ bằng cách thay đổi dòng cuối cùng của bạn thành 'system.time (foo (r = 1, i = new (" classA ", ID =" ID1 "))'. –

Trả lời

1

Tôi gặp sự cố tương tự. S4 dường như tất cả các kết hợp chữ ký có thể có. Điều này làm chậm quá trình thu thập thông tin. Giải pháp là có càng ít yếu tố trong chữ ký càng tốt.

Bạn có thể tìm chi tiết tại đây https://stat.ethz.ch/pipermail/r-devel/2015-May/071092.html

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