2012-10-03 5 views
6

Ich versuche, merge eine räumliche Methode hinzuzufügen, die S4 sein muss (da es die Typen von zwei verschiedenen Objekten auslöst).Hinzufügen von S4-Versand zu Basis R S3 generisch

Ich habe versucht, eine earlier solution wie folgt verwendet:

#' 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") 
}) 

Welche funktionierts:

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

Du gehst mir zu haben zu vertrauen, dass, wenn x anstelle einer wirklich SPDF- ist gefälscht, dass es nicht den Slot-Fehler zurückgibt, den Sie erhalten, wenn Sie tatsächlich diesen Code ausführen (oder nicht, und verwenden Sie einfach den allgemeineren generischen darunter, der den Fehler nicht zurückgibt). SPDFs sind mühsam zu erstellen.

Das Problem ist, dass es S3 Versand überschrieben zu haben scheint:

> 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 von setGeneric zu beseitigen, so dass es einfach setGeneric("merge") liest, aber das funktioniert auch nicht. Muss ich die merge S3 generische von base irgendwie importieren?

Antwort

6

Die Mis-Dispatch tritt auf, weil der Körper der generischen nicht "Standard" ist (Ich denke, die Begründung ist, dass, da Sie etwas anderes als standardGeneric("merge") aufrufen, wissen Sie, was Sie tun, also keine automatische Standard Vielleicht erstelle ich das und es ist wirklich ein Fehler. Lösungen sind ein Standard-generic so dass für den Standard-Versand bietet

setGeneric("merge") 

oder explizit Standardversand

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

oder explizit eine Standardmethode

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

Von denen, angeben zu setzen, nur die dritten funktioniert bei mir. Den ersten habe ich eigentlich als Beispiel in meiner Frage bekommen. Aber der dritte funktioniert hervorragend. –

Verwandte Themen