【问题标题】:function to return all S3 methods applicable to an object返回适用于对象的所有 S3 方法的函数
【发布时间】:2014-05-24 01:24:42
【问题描述】:

有没有人整理/找到一个好的方法来列出给定对象可用的所有S3方法?内置的methods() 函数将为指定的类或指定的泛型函数提供所有可用的方法,但不为对象提供。

我想到的例子是一个glm 对象,它属于(次要?)类"glm",但也继承自"lm"

g <- glm(y~x,data=data.frame(x=1:10,y=1:10))
class(g)
## [1] "glm" "lm"

“lm”类有 35 种方法,“glm”有 22 种方法。我对结合以下结果的答案感兴趣

lapply(class(g),function(x) methods(class=x))

以一种明智的方式,以便我可以立即看到(例如)add1 有一个特定于glm 的方法,但是alias 的方法是从lm 类继承的。

有人有巧妙的方法来做到这一点,还是已经存在?

PS Steve Walker 的S3-S4-reference class glossary 表明这对引用类自动起作用,我们必须使用对象来获取方法 (x$getRefClass()$methods())。

【问题讨论】:

  • 询问 S3 类的方法有点误导,因为在 S3 中,函数有方法,而不是类。

标签: r r-s3


【解决方案1】:

这是一个复制“标准”行为的尝试

classMethods <- function(cl) {
    if(!is.character(cl)) {
        cl<-class(cl)
    }
    ml<-lapply(cl, function(x) {
        sname <- gsub("([.[])", "\\\\\\1", paste0(".", x, "$"))
        m <- methods(class=x)
        data.frame(
            m=as.vector(m), 
            c=x, n=sub(sname, "", as.vector(m)),
            attr(m,"info"),
            stringsAsFactors=F
        )
    })
    df<-do.call(rbind, ml)
    df<-df[!duplicated(df$n),]
    structure(df$m, 
        info=data.frame(visible=df$visible, from=df$from), 
        class="MethodsFunction")
}

然后你可以尝试一下

g <- glm(y~x,data=data.frame(x=1:10,y=1:10))
classMethods(g)
#or classMethods(c("glm","lm"))

它会返回

 [1] add1.glm*           anova.glm           confint.glm*        cooks.distance.glm*
 [5] deviance.glm*       drop1.glm*          effects.glm*        extractAIC.glm*    
 [9] family.glm*         formula.glm*        influence.glm*      logLik.glm*        
[13] model.frame.glm     nobs.glm*           predict.glm         print.glm          
[17] residuals.glm       rstandard.glm       rstudent.glm        summary.glm        
[21] vcov.glm*           weights.glm*        alias.lm*           case.names.lm*     
[25] dfbeta.lm*          dfbetas.lm*         dummy.coef.lm*      hatvalues.lm       
[29] kappa.lm            labels.lm*          model.matrix.lm     plot.lm            
[33] proj.lm*            qr.lm*              simulate.lm*        variable.names.lm* 

   Non-visible functions are asterisked

它不像 Josh 那样优雅或简短,但我认为它很好地再现了默认行为。有趣的是,methods 函数本身大多只是所有已知函数名称的 grep。我从那里借了gsub 的东西。

【讨论】:

    【解决方案2】:

    这是一个函数,它至少可以告诉您对象最初会触发哪些 S3 方法:

    findMethodsS3 <- function(object) {
        x <- unlist(lapply(class(object),function(x) methods(class=x)))   
        sort(x[!duplicated(tools::file_path_sans_ext(x))])
    }
    
    findMethodsS3(g)
    #  [1] "add1.glm"           "alias.lm"           "anova.glm"         
    #  [4] "case.names.lm"      "confint.glm"        "cooks.distance.glm"
    #  [7] "deviance.glm"       "dfbeta.lm"          "dfbetas.lm"        
    # [10] "drop1.glm"          "dummy.coef.lm"      "effects.glm"       
    # [13] "extractAIC.glm"     "family.glm"         "formula.glm"       
    # [16] "hatvalues.lm"       "influence.glm"      "kappa.lm"          
    # [19] "labels.lm"          "logLik.glm"         "model.frame.glm"   
    # [22] "model.matrix.lm"    "nobs.glm"           "plot.lm"           
    # [25] "predict.glm"        "print.glm"          "proj.lm"           
    # [28] "qr.lm"              "residuals.glm"      "rstandard.glm"     
    # [31] "rstudent.glm"       "simulate.lm"        "summary.glm"       
    # [34] "variable.names.lm"  "vcov.glm"           "weights.glm"    
    

    【讨论】:

    • 这是我所知道的 R 函数中最容易记住的复杂名称。记住它是在 utils 还是 tools 是我通常会得到的...
    • 只有在类名没有“.”时才有效在里面,对吧?
    • 看起来应该可以工作:tools::file_path_sans_ext("a.b.c") is "a.b"
    • @MrFlick -- 是的,非常好。看起来唯一的解决方案是像你的函数那样显式地去掉已知的类名。
    • @BenBolker 我想的更像tools::file_path_sans_ext("print.data.frame")=="print.data"
    猜你喜欢
    • 2011-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 2012-04-23
    • 1970-01-01
    相关资源
    最近更新 更多