2012-10-03 16 views
6

Estoy tratando de agregar un método espacial a merge que debe ser S4 (ya que se distribuye en los tipos de dos objetos diferentes).Agregando S4 envío a la base R S3 genérico

He intentado usar un earlier solution de la siguiente manera:

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

¿Qué hace el trabajo:

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

Vas a tener que confiar en mí que si x es realmente una SPDF en lugar de una falso, que no devuelve el error de ranura que obtiene si realmente ejecuta ese código (o no, y simplemente usa el genérico más permisivo a continuación que no devuelve el error). Los SPDF son un dolor para crear.

El problema es que parece haber sobrescrito S3 despacho:

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

¿Cómo puedo evitar eso? He intentado eliminar la definición de función de setGeneric para que simplemente lea setGeneric("merge") pero eso tampoco funciona. ¿Debo importar de alguna manera el merge S3 generic de base?

Respuesta

6

El envío erróneo se produce porque el cuerpo del genérico no es "estándar" (creo que la razón es que, ya que ha hecho algo distinto de invocar standardGeneric("merge"), ya sabe lo que está haciendo, por lo que no hay ajuste automático ; tal vez estoy inventando esto y realmente es un error). Las soluciones son establecer un permitiendo genérica estándar para el envío por defecto

setGeneric("merge") 

o para proporcionar explícitamente el envío estándar

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

o explícitamente especificar un método predeterminado

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

De ellos, sólo el tercero funciona para mi. El primero que tengo como ejemplo en mi pregunta. Pero el tercero funciona brillantemente. –

Cuestiones relacionadas