Hinzufügen von S4-Dispatch zum Basis-R-S3-Generikum
Frage
Ich versuche, eine räumliche Methode hinzuzufügen merge
Dies muss S4 sein (da es die Typen von zwei verschiedenen Objekten verarbeitet).
Ich habe versucht, eine zu verwenden frühere Lösung wie folgt:
#' 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")
})
Was funktioniert:
x <- 1
class(x) <- "SpatialPolygonsDataFrame"
y <- data.frame()
> merge(x,y)
generic dispatch
method dispatch
Sie müssen mir vertrauen, dass x, wenn es sich wirklich um ein SPDF und nicht um ein gefälschtes handelt, nicht den Slot-Fehler zurückgibt, den Sie erhalten, wenn Sie diesen Code tatsächlich ausführen (oder nicht, und einfach verwenden). Freizügigeres Generikum unten, das den Fehler nicht zurückgibt.SPDFs sind mühsam zu erstellen.
Das Problem ist, dass der S3-Versand anscheinend überschrieben wurde:
> 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"
Wie vermeide ich das?Ich habe versucht, die Funktionsdefinition aus zu entfernen setGeneric
damit es einfach liest setGeneric("merge")
aber das funktioniert auch nicht.Muss ich das irgendwie importieren? merge
S3 generisch von base
?
Lösung
Der Fehlversand tritt auf, weil der Hauptteil des Generikums nicht „Standard“ ist (ich denke, der Grund dafür ist, dass Sie etwas anderes getan haben als „invoke“) standardGeneric("merge")
, Sie wissen, was Sie tun, also keine automatische Standardeinstellung;vielleicht erfinde ich das nur und es ist wirklich ein Fehler).Lösungen bestehen darin, einen generischen Standard festzulegen, der den Standardversand ermöglicht
setGeneric("merge")
oder ausdrücklich einen Standardversand anzubieten
setGeneric("merge", function(x, y, ...) standardGeneric("merge"))
oder geben Sie explizit eine Standardmethode an
setGeneric("merge", function(x, y, ...){
cat("generic dispatch\n")
standardGeneric("merge")
}, useAsDefault=base::merge)