2014-08-29 2 views
40

En fait, quand il y a beaucoup d'arguments en setMethod ou (setGeneric), il fonctionne très lentement.R se bloque quand il y a trop d'arguments dans setMethod (ou setGeneric)

Voici un exemple de base:

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

Je constate que cela ne soit pas liée à la classe. Vous pouvez mettre une classe numeric en r et elle fera de même. Si je coupe le nombre d'arguments cela fonctionnera.

Je suspecte qu'il essaie "to find an inherited method for function ‘foo’ for signature ‘"numeric", "classA", "missing", ..." et cela provoque R à suspendre. HERE est une bonne discussion sur ce sujet.

Parce que si je lance même code avec moins de paramètres il fonctionne:

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

Pourquoi cela se produit? Toutes les idées sont les bienvenues.

+4

J'éprouvé sans l'E-variables - pas 5 minutes, mais encore remarquablement longue. J'ai observé que seulement la première fois que l'on appelle foo prend tellement de temps. La deuxième fois, foo est vraiment rapide. J'ai essayé de remplacer 'print' par' stop' et l'ai tracé par 'options (error = traceback)' pour voir toutes les étapes d'appel - mais tout semble bien, juste 3 appels. Donc, c'est vraiment bizarre ... –

+2

@PatrickRoocks Merci de confirmer. Je crois que la méthode de recherche prend tellement de temps (comme expliqué [ici] (http://stackoverflow.com/a/16386422/2275286)). Comme vous l'avez dit c'est bizarre, on ne peut écrire aucune fonction S4 qui a plus de 5-6 entrées (et itère dans un nouvel environnement à chaque fois) si c'est le cas. – HBat

+0

Pouvez-vous indiquer explicitement le code dans votre question afin que les réponses/solutions de rechange potentielles puissent être comparées sur la base de la réduction du temps de raccrochage? Par exemple en changeant votre dernière ligne à 'system.time (foo (r = 1, i = nouveau (" classA ", ID =" ID1 "))'. –

Répondre

Questions connexes