dotsMethods
位於 methods
包(package)。 說明
“...” 參數R函數被特殊對待,因為它匹配零個、一個或多個實際參數(以及對象)。添加了一個機製R允許 “...” 作為通用函數的簽名。為此類函數定義的方法將在以下情況下被選擇和調用:全部匹配 “...” 的參數來自指定的類或該類的某個子類。
在簽名中使用"..."
從 2.8.0 版本開始R,可以根據特殊參數“...”調度(選擇和調用)S4方法。目前,“...” 不能與其他形式參數混合:泛型函數的簽名或者僅為“...”,或者不包含“...”。 (此限製可能會在未來版本中取消。)
給定一個合適的通用函數,可以通過調用 setMethod
以通常的方式指定方法。編寫方法定義時,必須期望與 “...” 對應的所有參數都來自方法簽名中指定的類,或者來自擴展該類的類(即該類的子類)。
通常,這些方法會將 “...” 傳遞給另一個函數,或者創建一個參數列表並對其進行迭代。請參閱下麵的示例。
當您的計算適合多個現有類時,一種方便的方法可能是通過調用 setClassUnion
來定義這些類的並集。請參閱下麵的示例。
"..."的方法選擇和調度
有關一般討論,請參閱Methods_Details。以下假設您已閱讀該文檔的“方法選擇和調度”部分。
“...” 上選擇的方法由調用 setMethod
中的單個類指定。如果“...”對應的所有實參都有這個類,則直接選擇對應的方法。
否則,從第一個 “...” 參數開始計算每個參數的類以及該類的超類。對於第一個參數,合格的方法是適用於任何類的方法。對於引入先前未考慮的類的每個後續參數,合格的方法進一步限製為與參數的類或超類匹配的方法。如果不存在其他符合條件的類,則迭代將中斷並選擇默認方法(如果有)。
在迭代結束時,一種或多種方法可能是合格的。如果超過一個,則選擇查找與實際參數距離最小的方法。對於每個參數,任何繼承的方法都對應於一個距離,可從類定義的 contains
槽中獲取。由於同一類可以出現多個參數,因此可能有多個與之相關的距離。將它們組合起來不可避免地是任意的:當前的計算使用最小距離。因此,例如,如果一個方法直接匹配一個參數,一個作為第一代超類,另一個作為第二代超類,則距離為 0、1 和 2。當前選擇計算將對此方法使用距離 0。特別是,此選擇標準傾向於使用與一個或多個參數類別完全匹配的方法。
與普通的方法選擇一樣,可能存在多個具有相同距離的方法。發出警告消息並選擇其中一種方法(第一個遇到的方法,在本例中是相當任意的)。
請注意,雖然計算檢查所有參數,但分派的基本成本隨著參數中不同類的數量而增加,當後者很大時,可能比參數數量小得多。
實施細節
在 “...” 上調度的方法是在 2.8.0 版本中引入的R。相應的選擇和調度的初始實現是在 R 函數中實現的,以便在研究新機製時保持靈活性。在此實現中,本地版本standardGeneric
被插入到通用函數的環境中。本地版本根據上述標準選擇一個方法,並從通用函數的環境中調用該方法。這與不涉及 “...” 時 C 實現所采取的操作略有不同。除了需要額外的計算時間之外,該方法是在真正的函數調用中計算的,而不是由 C 版本構建的特殊上下文(無法在 R 代碼中完全複製)。但是,在不同的計算結果的情況下到目前為止還沒有遇到過,而且看起來可能性很小。
通過將繼承的方法存儲在所有方法的表中來緩存除 “...” 以外的參數上分派的方法,在下一個選擇中可以在實際參數中使用相同的類組合找到該方法(但不用於繼承搜索) 。基於“...”的方法也被緩存,但沒有立即找到。如前所述,所選方法僅取決於 “...” 參數中出現的類集。這些類中的每一個都可以出現一次或多次,因此實際參數類的許多組合將產生相同的有效簽名。選擇計算首先計算並排序遇到的不同類。這給出了一個標簽,該標簽將緩存在所有方法的表中,從而避免在第一次出現後進一步搜索繼承的類。對showMethods
的調用將公開此類繼承的方法。
目的是當獲得足夠的經驗後,“...” 函數將被添加到標準 C 代碼中。同時,可能支持 “...” 與簽名中其他參數的組合。
例子
cc <- function(...)c(...)
setGeneric("cc")
setMethod("cc", "character", function(...)paste(...))
setClassUnion("Number", c("numeric", "complex"))
setMethod("cc", "Number", function(...) sum(...))
setClass("cdate", contains = "character", slots = c(date = "Date"))
setClass("vdate", contains = "vector", slots = c(date = "Date"))
cd1 <- new("cdate", "abcdef", date = Sys.Date())
cd2 <- new("vdate", "abcdef", date = Sys.Date())
stopifnot(identical(cc(letters, character(), cd1),
paste(letters, character(), cd1))) # the "character" method
stopifnot(identical(cc(letters, character(), cd2),
c(letters, character(), cd2)))
# the default, because "vdate" doesn't extend "character"
stopifnot(identical(cc(1:10, 1+1i), sum(1:10, 1+1i))) # the "Number" method
stopifnot(identical(cc(1:10, 1+1i, TRUE), c(1:10, 1+1i, TRUE))) # the default
stopifnot(identical(cc(), c())) # no arguments implies the default method
setGeneric("numMax", function(...)standardGeneric("numMax"))
setMethod("numMax", "numeric", function(...)max(...))
# won't work for complex data
setMethod("numMax", "Number", function(...) paste(...))
# should not be selected w/o complex args
stopifnot(identical(numMax(1:10, pi, 1+1i), paste(1:10, pi, 1+1i)))
stopifnot(identical(numMax(1:10, pi, 1), max(1:10, pi, 1)))
try(numMax(1:10, pi, TRUE)) # should be an error: no default method
## A generic version of paste(), dispatching on the "..." argument:
setGeneric("paste", signature = "...")
setMethod("paste", "Number", function(..., sep, collapse) c(...))
stopifnot(identical(paste(1:10, pi, 1), c(1:10, pi, 1)))
參考
Chambers, John M. (2008) Software for Data Analysis: Programming with R Springer. (For the R version.)
Chambers, John M. (1998) Programming with Data Springer (For the original S4 version.)
也可以看看
有關方法的一般討論,請參閱Methods_Details 和其中的鏈接。
相關用法
- R as 強製對象屬於某個類
- R language-class 表示未評估語言對象的類
- R className 類名包含對應的包
- R BasicClasses 基本數據類型對應的類
- R callGeneric 從方法調用當前通用函數
- R findClass 查找類定義
- R setOldClass 注冊舊式 (S3) 類和繼承
- R ReferenceClasses 具有按引用處理的字段的對象(OOP 樣式)
- R MethodsList 方法列表對象
- R setGroupGeneric 創建函數的組通用版本
- R StructureClasses 基本結構對應的類
- R showMethods 顯示指定函數或類的所有方法
- R getMethod 獲取或測試方法的定義
- R slot 正式類對象中的槽
- R S4groupGeneric S4組通用函數
- R methodUtilities 用於方法和 S-Plus 兼容性的實用函數
- R getClass 獲取類定義
- R evalSource 使用源文件中的函數定義,無需重新安裝包
- R is 對象是來自類嗎?
- R isSealedMethod 檢查密封方法或類
- R cbind2 按列或行組合兩個對象
- R GenericFunctions 管理通用函數的工具
- R S3Part 包含 S3 類的 S4 類
- R nonStructure-class 基本類型的非結構 S4 類
- R selectSuperClasses 類的超類(特定類型)
注:本文由純淨天空篩選整理自R-devel大神的英文原創作品 The Use of ... in Method Signatures。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。