8

R 的 S3 OO 系统以泛型函数为中心,泛型函数调用方法取决于调用泛型函数的对象的类。关键是通用函数调用适当的方法,而不是在类中定义方法的其他 OO 编程语言。

例如,该mean函数是通用函数。

isGeneric("mean")
methods(mean)

这将打印

TRUE
[1] mean,ANY-method          mean.Date                mean.default             mean.difftime           
[5] mean.IDate*              mean,Matrix-method       mean.POSIXct             mean.POSIXlt            
[9] mean,sparseMatrix-method mean,sparseVector-method
see '?methods' for accessing help and source code

我正在探索 R 并找到了该as功能。我对 R 说函数不是通用的,但它仍然有方法这一事实感到困惑。

isGeneric("as")
methods(as)

TRUE
  [1] as.AAbin                                  as.AAbin.character                       
  [3] as.alignment                              as.allPerms                              
  [5] as.array                                  as.array.default                         
  [7] as.binary                                 as.bitsplits                             
  [9] as.bitsplits.prop.part                    as.call
  ...                                  

最后有一个警告说这as不是通用的。

 Warning message:
 In .S3methods(generic.function, class, parent.frame()) :
 function 'as' appears not to be S3 generic; found functions that look like S3 methods

有人可以解释一下这个as功能是什么以及如何连接as.listas.data.frame吗?R 说这as.list是一个泛型(我很想对 R 中的不一致感到有点生气,因为我希望成为泛型函数的对象as.list的方法)。请帮忙。listas

4

1 回答 1

11

as不是 S3 泛型,但请注意您得到了 TRUE。(我得到了一个错误。)这意味着您已经加载了一个定义as为 S4 泛型的包。*.defaultS3 泛型通过使用函数和UseMethod-function的类调度工作。我得到的 FALSE 意味着没有为要as查找的泛型定义方法。缺少泛型的一个有争议的原因as是,仅使用一个数据对象调用这样的函数不会指定“强制目标”。这意味着需要将目标构建到函数名称中。

在声明as为 Generic 之后(注意大写,暗示这适用于 S4 功能:

setGeneric("as")  # note that I didn't really even need to define any methods

get('as')
#--- output----
standardGeneric for "as" defined from package "methods"

function (object, Class, strict = TRUE, ext = possibleExtends(thisClass, 
    Class)) 
standardGeneric("as")
<environment: 0x7fb1ba501740>
Methods may be defined for arguments: object, Class, strict, ext
Use  showMethods("as")  for currently available ones.

如果我重新启动 R(并且不加载任何为“as”调用 setGeneric 的库),我会得到:

get('as')
#--- output ---
function (object, Class, strict = TRUE, ext = possibleExtends(thisClass, 
    Class)) 
{
    if (.identC(Class, "double")) 
        Class <- "numeric"
    thisClass <- .class1(object)
    if (.identC(thisClass, Class) || .identC(Class, "ANY")) 
        return(object)
    where <- .classEnv(thisClass, mustFind = FALSE)
    coerceFun <- getGeneric("coerce", where = where)
    coerceMethods <- .getMethodsTable(coerceFun, environment(coerceFun), 
        inherited = TRUE)
    asMethod <- .quickCoerceSelect(thisClass, Class, coerceFun, 
        coerceMethods, where)
    .... trimmed the rest of the code

但是你问“为什么”,当然,在讨论语言设计时总是一个危险的问题。我已经翻阅了 S 中的统计模型的最后一章,这是适用于 S3 调度的大多数帮助页面的引用参考,但没有发现任何关于强制或as函数的讨论。“S3 通用”有一个隐含的定义,需要使用UseMethod但没有提及为什么as被排除在该策略之外。我想到了两种可能性:它是为了防止在强制应用中出现任何类型的继承歧义,或者它是一种效率决策。

我可能应该补充一点,有一个 S4setAs函数,你可以找到所有 S4 强制函数showMethods("coerce")

于 2018-01-14T18:50:16.163 回答