2016-02-13 40 views
0

我創建了一個包含多個R類的包,它將整數映射到經常出現在組合中的各種結構,反之亦然。雖然這些類僅封裝了映射(結構的數量增長非常快,容易達到萬億分之一),而不是實際存儲結構,但將類的實例視爲「包含」結構的向量是方便的,並且它將是很好的情況下行爲像矢量。如何爲R中定義的S4類定義函數`match`和`%in%`的行爲?

例如,類之一是PPV(用於置換僞向量),設置爲:

setClass(
    Class = "PPV", 
    representation(k = "numeric", items = "vector") 
) 

爲了使其行爲有點像載體,我已經加入定義爲length[

setMethod(
    f = "length", 
    signature = "PPV", 
    definition = function(x) # blah blah blah 
) 

setMethod(
    f = "[", 
    signature = "PPV", 
    definition = function(x, i, j, drop) { 
    # blah blah blah 
    } 
) 

到目前爲止,這麼好。這使我對實例和訪問結構使用length通過索引的情況下,「載」:

> # (ppv is a constructor) 
> # Create a pseudo-vector of 3-permutations of the first 5 letters. 
> ps <- ppv(3, letters[1:5]) 
> # Like vectors, access we can access structures "contained" by index. 
> for (i in 1:5) cat(ps[i],"\n") 
a b c 
a c b 
c a b 
c b a 
b c a 
> # Like vectors, function length is meaningful. 
> length(ps) 
[1] 60 

我也有從結構到指數定義爲存在測試映射,似乎這將是最這些映射分別通過match%in%函數來實現。這是我到目前爲止有:

setMethod(
    f = "%in%", 
    signature = c("vector", "PPV"), 
    definition = function(x, table) 
    # blah blah blah 
) 

setMethod(
    f = "match", 
    signature = c("vector", "PPV"), 
    definition = function(x, table) { 
    # blah blah blah 
    } 
) 

的問題是,當我安裝並加載庫,這些似乎並沒有被定義爲:

> some.permutation <- c("a", "c", "e") 
> some.permutation %in% ps 
Error in match(x, table, nomatch = 0L) : 
    'match' requires vector arguments 
> match(some.permutation, ps) 
Error in match(some.permutation, ps) : 'match' requires vector arguments 

然而,當我明確地執行包含在文件中的代碼,它的工作原理:

> some.permutation %in% ps 
[1] TRUE 
> match(some.permutation, ps) 
[1] 25 
> ps[25] 
[1] "a" "c" "e" 

爲什麼當包被加載,但對於那些有正在執行的length[定義和match,在同一個文件中並且具有相同的設置,是不是?

回答

1

match()不是一個通用的(isGeneric("match")),所以你想使它成爲一個,也許比分配所有參數更合理。

setGeneric("match", signature=c("x", "table")) 

編寫方法遵循簽名

setMethod("match", c("vector", "PPV"), 
    function(x, table, nomatch = NA_integer_, incomparables = NULL) 
{ 
    "match,vector,PPV-method" 
}) 

請記住,在你的包命名空間中導出類和泛型

exportClasses("PPV") 
export("match") 

對於%in%,隱含的通用(通過定義創建方法沒有先使用setGeneric())是明智的,所以只需定義方法

setMethod("%in%", c("vector", "PPV"), function(x, table) { 
    message("%in%") 
    match(x, table, nomatch=0L) > 0 
}) 

還記得導出隱式泛型(在NAMESPACE中爲export("%in%"))。

人們可能希望自base::%in%match()來定義,並match()已經爲你的類被實現,它也沒有必要實施%in%的方法。事實並非如此,我認爲是因爲match()在C中以一種不首先查找泛型的方式實現。

相關問題