2016-02-13 81 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中以一种不首先查找泛型的方式实现。

相关问题