Добавление диспетчеризации S4 к базовой базе R S3 generic

Я пытаюсь добавить пространственный метод к merge, который должен быть S4 (поскольку он отправляет типы двух разных объектов).

Я попытался использовать более раннее решение следующим образом:

#' 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 S3 из base?


r s4
person Ari B. Friedman    schedule 03.10.2012    source источник


Ответы (1)


Неправильная отправка происходит из-за того, что тело дженерика не является «стандартным» (я думаю, причина в том, что, поскольку вы сделали что-то кроме вызова 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)
person Martin Morgan    schedule 03.10.2012
comment
Из них у меня работает только третья. Первый я действительно получил в качестве примера в моем вопросе. Зато третья работает блестяще. - person Ari B. Friedman; 03.10.2012