[英]R: how to find what S3 method will be called on an object?
我知道methods()
,它返回給定類的所有方法。 假設我有x
並且我想知道當我調用foo(x)
時會調用什么方法。 有沒有可以做到這一點的單線或包裹?
我能想到的最短的是:
sapply(class(x), function(y) try(getS3method('foo', y), silent = TRUE))
然后檢查結果的類......但是沒有內置的嗎?
更新
完整的一個班輪將是:
fm <- function (x, method) {
cls <- c(class(x), 'default')
results <- lapply(cls, function(y) try(getS3method(method, y), silent = TRUE))
Find(function (x) class(x) != 'try-error', results)
}
這將適用於大多數事情,但請注意,它可能會因某些復雜對象而失敗。 例如,根據?S3Methods
,在matrix(1:4, 2, 2)
上調用foo
會嘗試foo.matrix
,然后是foo.numeric
,然后是foo.default
; 而這段代碼只會尋找foo.matrix
和foo.default
。
findMethod
定義的findMethod
不是單行代碼,但它的主體只有 4 行代碼(如果我們要求將泛型作為字符串傳遞,它可以減少到 3 行代碼)。 它將返回一個字符串,表示該方法的名稱,該方法將由輸入泛型分派給定泛型及其參數。 (如果您想返回方法本身, findMethod
主體的最后一行替換為get(X(...))
。)在內部,它創建了一個泛型 X 和一個對應於輸入泛型的每個方法的 X 方法,例如每個 X 方法返回將運行的輸入泛型的方法的名稱。 X 泛型及其方法都是在findMethod
函數中創建的,因此當findMethod
退出時它們會消失。 為了得到結果,我們只需將輸入參數作為findMethod
函數體的最后一行運行 X。
findMethod <- function(generic, ...) {
ch <- deparse(substitute(generic))
f <- X <- function(x, ...) UseMethod("X")
for(m in methods(ch)) assign(sub(ch, "X", m, fixed = TRUE), "body<-"(f, value = m))
X(...)
}
現在測試一下。 (請注意,問題中的單行在其中幾個測試中失敗並出現錯誤,但findMethod
給出了預期的結果。)
findMethod(as.ts, iris)
## [1] "as.ts.default"
findMethod(print, iris)
## [1] "print.data.frame"
findMethod(print, Sys.time())
## [1] "print.POSIXct"
findMethod(print, 22)
## [1] "print.default"
# in this example it looks at 2nd component of class vector as no print.ordered exists
class(ordered(3))
## [1] "ordered" "factor"
findMethod(print, ordered(3))
## [1] "print.factor"
findMethod(`[`, BOD, 1:2, "Time")
## [1] "[.data.frame"
我用這個:
s3_method <- function(generic, class, env = parent.frame()) {
fn <- get(generic, envir = env)
ns <- asNamespace(topenv(fn))
tbl <- ns$.__S3MethodsTable__.
for (c in class) {
name <- paste0(generic, ".", c)
if (exists(name, envir = tbl, inherits = FALSE)) {
return(get(name, envir = tbl))
}
if (exists(name, envir = globalenv(), inherits = FALSE)) {
return(get(name, envir = globalenv()))
}
}
NULL
}
為簡單起見,這不會返回調用環境中由賦值定義的方法。 為了方便,在開發過程中檢查全局環境。 這些與 r-lib 包中使用的規則相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.