2016-06-01 5 views
0

Supposons que je souhaite définir la fonction rankMatrix du package Matrix pour mes propres objets de classe S4. Faire cela dans une session R en cours d'exécution semble être simple:La méthode correcte pour définir une fonction générique et la surcharger avec différents arguments dans un package

library(devtools); library(roxygen2); library(Matrix) 

######################################################## 
################ code used in the package ############## 

#' testclass 
#' 
#' @import Matrix 
#' @import methods 
#' @export 
setClass("MatrixReloaded", slots = list(sl = "Matrix", sr = "Matrix")) 

#' constructor of MatrixReloaded 
#' @export 
MatrixReloaded <- function(x, y) new("MatrixReloaded", sl = x, sr = y) 

# make rankMatrix generic 
setGeneric("rankMatrix", Matrix::rankMatrix) 

# and define new method for class MatrixReloaded 
setMethod("rankMatrix", signature(x = "MatrixReloaded"), 
      function(x, tol) 
      rankMatrix(x = [email protected], tol = tol) + 
      rankMatrix(x = [email protected], tol = tol) 
     ) 

######################################################## 
######################################################## 

# Create a MatrixReloaded object 
(newobj <- MatrixReloaded(Diagonal(1), Matrix(1:10, ncol=2))) 

#### and compare results 

# sum the ranks individually -- works as rankMatrix 
# can handle objects of class Matrix per default 
rankMatrix([email protected]) + rankMatrix([email protected]) 
rankMatrix(newobj) # call rankMatrix on the actual MatrixReloaded object 

Cela semble bien fonctionner ... En particulier, methods("rankMatrix") cède

rankMatrix,ANY-method rankMatrix,MatrixReloaded-method 

Le problème réel

Si je Construire un paquet contenant la classe, le constructeur ainsi que les lignes concernant rankMatrix puis démarrer une nouvelle session R, installer ainsi que charger le package, methods("rankMatrix") donne le même résultat, cependant rankMatrix(newobj) échoue en raison du fait que la fonction n'est pas appelée pour la classe correcte.

  • Qu'est-ce que j'ai fait de mal?
  • Les arguments doivent-ils correspondre exactement à ceux de la fonction générique par défaut?
  • Si oui, existe-t-il un moyen d'ignorer les arguments de la fonction par défaut (par exemple sval dans rankMatrix car je ne veux pas que R exécute le svd sur l'objet MatrixReloaded)?
+0

Je ne pense pas que 'newobj @ sl' aura la structure appropriée pour être de classe MatrixReloaded. Il ne s'agira que d'une matrice et rankMatrix n'a pas de méthode pour un élément avec cette signature. –

+0

@ 42-: Merci pour votre commentaire. L'avant-dernière ligne est juste une vérification, si la fonction 'rankMatrix' sur l'objet' MatrixReloaded' 'newobj' dans la dernière ligne fait la bonne chose - à savoir la somme des rangs des deux matrices simples. Et 'rankMatrix' (dans le cadre du paquetage' Matrix') est écrit d'une manière, qu'il peut aussi être utilisé avec des objets 'Matrix', bien qu'il n'y ait pas de méthode explicite pour cette classe. – DavidR

Répondre

0

La solution à mon premier problème est assez simple: j'ai oublié de @export la nouvelle méthode générique, comme par exemple. déclaré here