2014-08-29 36 views
40

Zasadniczo, gdy istnieje wiele argumentów w setMethod lub (setGeneric), działa bardzo wolno.R zawiesza się, gdy istnieje zbyt wiele argumentów w metodzie setMethod (lub setGeneric)

Oto prosty przykład:

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")) 

mogę stwierdzić, że to nie jest związana z klasą. Możesz umieścić klasę numeric w r i zrobi to samo. Jeśli zmniejszę liczbę argumentów, zadziała.

Podejrzewam, że próbuje "to find an inherited method for function ‘foo’ for signature ‘"numeric", "classA", "missing", ...", a to powoduje, że R zawiesza się. HERE to dobra dyskusja na ten temat.

Bo jeśli biegnę sam kod z mniej parametrów to działa:

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")) 

Dlaczego tak się dzieje? Wszelkie pomysły zostaną docenione.

+4

testowałem bez e-zmiennych - nie 5 minut, ale nadal niezwykle długo. Zauważyłem, że tylko pierwszy raz, gdy jest wywoływany foo, trwa tak długo. Po raz drugi foo jest naprawdę szybki. Próbowałem zastąpić 'print' przez' stop' i śledzić go za pomocą 'options (error = traceback)', aby zobaczyć wszystkie kroki połączenia - ale wszystko wydaje się w porządku, tylko 3 połączenia. To jest naprawdę dziwne ... –

+2

@PatrickRoocks Dziękujemy za potwierdzenie. Wierzę, że metoda wyszukiwania zajmuje tak dużo czasu (jak wyjaśniono [tutaj] (http://stackoverflow.com/a/16386422/2275286)). Jak powiedziałeś, jest to dziwne, nie można napisać żadnej funkcji S4, która ma więcej niż 5-6 wejść (i iteruje w nowym środowisku za każdym razem), jeśli tak jest. – HBat

+0

Czy możesz w prosty sposób skorygować kod w pytaniu, aby potencjalne odpowiedzi/obejść można porównać na podstawie skrócenia czasu zawieszenia? Na przykład zmieniając ostatnią linię na 'system.time (foo (r = 1, i = new (" classA ", ID =" ID1 "))'. –

Odpowiedz