将S4调度添加到基本R S3泛型

时间:2012-10-03 13:49:22

标签: r s4

我正在尝试向merge添加一个需要为S4的空间方法(因为它会调度两个不同对象的类型)。

我尝试使用earlier solution,如下所示:

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

哪种方法有效:

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

你将不得不相信我,如果x实际上是一个SPDF而不是伪造的,它不会返回你实际运行该代码时得到的插槽错误(或者没有,并且只需使用下面更宽松的通用,它不会返回错误)。 SPDF很难创造。

问题是它似乎覆盖了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"

我该如何避免?我尝试从setGeneric中删除函数定义,以便它只读取setGeneric("merge"),但这也不起作用。我是否需要以某种方式从merge导入base S3通用?

1 个答案:

答案 0 :(得分:8)

错误发送是因为泛型的主体不是“标准”(我认为理由是,因为你做了除调用standardGeneric("merge")以外的其他事情,你知道你在做什么没有自动默认;也许我正在做这个,这真的是一个错误)。解决方案是设置标准通用,允许默认调度

setGeneric("merge")

或明确提供标准派遣

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

或明确指定默认方法

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