8 votes

Ajout de la répartition S4 à la base R S3 générique

J'essaie d'ajouter une méthode spatiale à merge qui doit être S4 (puisqu'il est envoyé sur les types de deux objets différents).

J'ai essayé d'utiliser un solution antérieure comme suit :

#' Merge a SpatialPolygonsDataFrame with a data.frame
#' @param SPDF A SpatialPolygonsDataFrame
#' @param df A data.frame
#' @param \dots Parameters to pass to merge.data.frame
#' 
#' @export
#' @docType methods
#' @rdname merge-methods
setGeneric("merge", function(SPDF, df, ...){
  cat("generic dispatch\n")
  standardGeneric("merge")
})
#' @rdname merge-methods
#' @aliases merge,SpatialPolygonsDataFrame,data.frame-method
setMethod("merge",c("SpatialPolygonsDataFrame","data.frame"), function(SPDF,df,...) {
  cat("method dispatch\n")
})

Ce qui fonctionne :

x <- 1
class(x) <- "SpatialPolygonsDataFrame"
y <- data.frame()
> merge(x,y)
generic dispatch
method dispatch

Vous allez devoir me faire confiance et me dire que si x est vraiment un SPDF au lieu d'un faux, il ne renvoie pas l'erreur de slot que vous obtenez si vous exécutez réellement ce code (ou ne le faites pas, et utilisez simplement le générique plus permissif ci-dessous qui ne renvoie pas l'erreur). Les SPDF sont difficiles à créer.

Le problème est qu'il semble avoir écrasé la répartition S3 :

> merge(y,y)
generic dispatch
Error in function (classes, fdef, mtable)  : 
  unable to find an inherited method for function "merge", for signature "data.frame", "data.frame"

Comment puis-je éviter cela ? J'ai essayé d'éliminer la définition de la fonction de setGeneric de sorte qu'il se lit simplement setGeneric("merge") mais ça ne marche pas non plus. Dois-je d'une manière ou d'une autre importer le merge S3 générique de base ?

8voto

Martin Morgan Points 19965

La mauvaise répartition se produit parce que le corps du générique n'est pas "standard" (je pense que le raisonnement est que, puisque vous avez fait autre chose qu'invoquer standardGeneric("merge") vous savez ce que vous faites, donc pas de défaut automatique ; peut-être que j'invente et que c'est vraiment un bug). Les solutions sont de définir un générique standard permettant la répartition par défaut

setGeneric("merge")

ou de fournir explicitement une répartition standard

setGeneric("merge", function(x, y, ...) standardGeneric("merge"))

ou spécifier explicitement une méthode par défaut

setGeneric("merge", function(x, y, ...){
  cat("generic dispatch\n")
  standardGeneric("merge")
}, useAsDefault=base::merge)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X