2012-10-03 7 views
6

Sto cercando di aggiungere un metodo spaziale a merge che deve essere S4 (poiché invia i tipi di due oggetti diversi).Aggiunta di S4 alla base R S3 generica

Ho provato con un earlier solution come segue:

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

che funziona:

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

Stai andando ad avere fiducia in me che se x è davvero una SPDF invece di un simulato uno, che non restituisce l'errore di slot che si ottiene se si esegue effettivamente quel codice (o non, e basta utilizzare il più generico permissivo di seguito che non restituisce l'errore). Gli SPDF sono un dolore da creare.

Il problema è che sembra aver sovrascritto S3 la spedizione:

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

Come posso evitare questo? Ho provato ad eliminare la definizione della funzione da setGeneric in modo che legge semplicemente setGeneric("merge") ma non funziona neanche. Devo in qualche modo importare lo merge S3 generico da base?

risposta

6

L'invio errato si verifica perché il corpo del generico non è "standard" (penso che la logica sia quella, dal momento che hai fatto qualcosa di diverso da invocare standardGeneric("merge"), sai cosa stai facendo in modo che non sia impostato automaticamente ; forse lo sto inventando ed è davvero un bug). Le soluzioni sono per impostare una norma generica che consente l'invio di default

setGeneric("merge") 

o per fornire in modo esplicito la spedizione standard di

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

o esplicitamente specificare un metodo predefinito

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

Di questi, solo la terza per me va bene. Il primo che ho effettivamente avuto come esempio nella mia domanda. Ma il terzo funziona brillantemente. –