簡體   English   中英

用於S4方法的R match.call()

[英]R match.call() for S4 methods

我正在為S4類編寫一個方法,我想調用該方法,就好像它是一個函數並使用match.call()。

這是我正在做的最簡單的例子:

setClass(
  Class = "AClass",
  representation = representation(
    name = "character"
  )
)

setGeneric("meth1", function(object, ...) {
  standardGeneric("meth1")
})

setMethod(
  f = "meth1",
  signature = "AClass",
  definition = function(object, method, ..., warnings = TRUE) {
    # ...
    print(match.call())

    return(NA)
})

根據這個定義,我看到:

> meth1(new("AClass"), method = "MClust")
.local(object = object, method = "MClust")
[1] NA
> meth1(new("AClass"), method = Mclust)
.local(object = object, method = ..1)
[1] NA

問題是:

  1. 為什么在為參數'method'賦值時,從match.call()得到的這個參數的內容是..1 insetad fo "Mclust"

  2. 為什么'function'的名字來自match.call().local而不是meth1

  3. 如何從函數中的變量method獲得"Mclust"

有一些問題與如何match.call工程時,有...的函數調用參與和多層。 這與match.call搜索詞法堆棧以找到...替換而不是動態堆棧有關。 我寫了一個包來試圖糾正這些問題:

devtools::install_github("brodieg/matchcall")  # <-- the package in question
library(matchcall)
setMethod(
  f = "meth1",
  signature = "AClass",
  definition = function(object, method, ..., warnings = TRUE) {
    # ...
    print(match.call())
    print(match_call())
    print(match_call(2))
    return(NA)
  })
meth1(new("AClass"), method = Mclust)

生產:

.local(object = object, method = ..1)               # match.call
.local(object = object, method = Mclust)            # match_call(), my package
meth1(object = new("AClass"), method = Mclust)      # match_call(2), my package offset
[1] NA

因此,回答問題2,你得到.local的原因是因為有一系列調用最終會導致你定義的函數的評估,並且S4存儲的函數為.local

問題1的答案很復雜,但您可以查看我的包中附帶的插圖中的詳細信息。 請注意,在C代碼內部...參數具有名稱..1..2等( 來自R Internals

回想一下,函數的求值框最初包含匹配調用中的name = value對,因此對於...也是如此。 ......的值是一個(特殊的)pairlist,其元素由特殊符號..1,..2,...引用,它們設置了DDVAL位:當遇到其中一個時,它被查找(通過ddfindVar) )在評估框架中的...符號的值。

問題3,我不明白。 您是否希望能夠將未加引號的變量作為參數“方法”放入,然后將其解釋為字符?

請注意,該軟件包目前僅在github上,但您可以使用sys.calls來滿足您的需求。 例如,如果我們在您的方法中運行print(sys.calls()) ,我們得到:

[[1]]
meth1(new("AClass"), method = Mclust)

[[2]]
meth1(new("AClass"), method = Mclust)

[[3]]
.local(object, ...)

您可以直接使用它,但只有在調用中完全指定參數名稱時才能正常工作(即如果某人執行了meth1(x, "blah") ,則不會得到method=一部分sys.calls 。如果你有多個參數或部分指定的參數(例如meth=X )那么你將需要做更多的工作來匹配東西(這正是match_call所做的)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM