0

我想定义一个返回标量返回值的 S4 方法。这里我的意思是标量值,与向量相反。

setGeneric("getScalar", function(value,  ...) 
  standardGeneric("getScalar")
)
setMethod("getScalar", 
          signature(value = "ANY"),
          def = function(value, ...) getScalar(value,...), ## call external function
          valueClass = "atomic" ### atomic is false, what should I do ?
)

我不能通过它的输出覆盖该方法,我的意思是我不能定义许多具有相同签名和不同返回 valueClass 的函数:numeric , integer , character ,.. 那么我该怎么做呢?

编辑以提供更多上下文:

我认为原子在这里令人困惑。我的意思是标量数值或布尔值或字符,长度为 1。为了提供更多上下文,我的包中将包含 3 个函数:

dbGetQuery   :return a list/data.frame : i.e some table rows
dbGetScalar  :return a scalar value  : i.e count(*),table_name,..
dbGetNoQuery :return nothing          : update/insert actions

它是对 DBI 接口的扩展。

编辑2

我们可以假设标量是一个长度为 1 的向量。但是我不能用 S4 来表达这个条件。在 c# 或 c 中,我会写

double[]       // vector
double        // scalar

也许我应该更改我的函数的名称。

4

1 回答 1

2

一种可能性是在方法分派后检查返回类型的值

setGeneric("getScalar", function(x, ...) {
    value <- standardGeneric("getScalar")
    if (!is.atomic(value) || length(value) != 1L)
        stop("not a scalar atomic vector")
    value
})

setMethod(getScalar, "ANY", function(x, ...) x)

另一种可能性是定义一个“标量”类,对强制约束的基类进行有效性检查

.Scalar <- setClass("Scalar", contains="ANY", validity=function(object) {
    if (length(object) != 1L)
        "non-scalar object"
    else TRUE
}, prototype=NA)

或使用基于虚拟类的小层次结构更强烈地控制标量类型

setClass("Scalar", validity=function(object) {
    if (length(object) != 1L)
        "non-scalar object"
    else TRUE
})

.ScalarInteger <- setClass("ScalarInteger",
    contains=c("Scalar", "integer"),
    prototype=prototype(NA_integer_))

这是BioconductorBiobase包中采用的方法,带有mkScalar构造函数。

于 2013-11-07T23:36:34.027 回答