如何为R中定义的S4类定义函数`match`和`%in%`的行为?

时间:2016-02-13 03:26:17

标签: r s4

我创建了一个包含多个R类的包,它们将整数映射到组合数据中经常出现的各种结构,反之亦然。虽然类只封装了映射(结构数量增长得非常快,很容易达到数万亿)而不是实际存储结构,但将类的实例视为向量"包含&很方便。 #34;这些结构很好,实例就像向量一样。

例如,其中一个类是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[的定义,而%in%match的定义在同一个文件中并且与相同的设置,不是吗?

1 个答案:

答案 0 :(得分:1)

Random rand = new Random(); int n = rand.nextInt(mAnimations.length) + 1; YoYo.with(Techniques.(mAnimations[n])) .duration(1000) .playOn(textView); 不是通用的(match()),因此您希望将其设置为一个,可能比调度所有参数更明智。

isGeneric("match")

编写方法以遵循签名

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

请记住在您的包NAMESPACE中导出类和泛型

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

对于exportClasses("PPV") export("match") ,隐式泛型(通过定义不首先使用%in%的方法创建)是明智的,所以只需定义方法

setGeneric()

请记住也要导出隐式泛型(NAMESPACE中的setMethod("%in%", c("vector", "PPV"), function(x, table) { message("%in%") match(x, table, nomatch=0L) > 0 }) )。

有人可能希望,export("%in%")是根据base::%in%定义的,并且match()已经为您的类实现,因此没有必要为{{实现match() 1}}。事实并非如此,我认为因为%in%是以不首先寻找通用的方式在C中实现的。