我已经用这种方式定义了一个名为 FilterCommandIndices 的S4类:
setClass('FilterCommandIndices',
representation(rows='logical', cols='logical')
)
它只包含两个插槽,指示给定行或列是否包含在集合中的逻辑向量。然后我想重载下标运算符,使其与前一个类一起使用。我最初的实现是这样的:
setMethod('[', c(x='ANY', i='FilterCommandIndices', j='missing'),
function(x, i, j, ..., drop=TRUE) {
if (nrow(x) != length(getRows(i)) || ncol(x) != length(getCols(i))) {
stop('Incorrect number of dimensions')
} else {
return(x[getRows(i), getCols(i)])
}
})
在上面的代码中, getRows ()和 getCols ()是 FilterCommandIndices 类的相应简单访问器:
setGeneric('getRows', function(object) standardGeneric('getRows'))
setMethod('getRows', 'FilterCommandIndices',
function(object) {
return(object@rows)
})
setGeneric('getCols', function(object) standardGeneric('getCols'))
setMethod('getCols', 'FilterCommandIndices',
function(object) {
return(object@cols)
})
我认为通过使用 ANY 签名,我可以使这个简单的类和运算符组合在基类中工作,就像一个简单的矩阵。虽然它似乎适用于一个示例类......
d> bar1
An object of class "FilterCommandIndices"
Slot "rows":
[1] FALSE TRUE TRUE TRUE TRUE
Slot "cols":
[1] TRUE TRUE TRUE TRUE TRUE
d> mockMethylSet
MethylSet (storageMode: lockedEnvironment)
assayData: 5 features, 5 samples
element names: Meth, Unmeth
phenoData: none
Annotation
Preprocessing
Method: unknown
minfi version: unknown
Manifest version: unknown
d> mockMethylSet[bar1]
MethylSet (storageMode: lockedEnvironment)
assayData: 4 features, 5 samples
element names: Meth, Unmeth
phenoData: none
Annotation
Preprocessing
Method: unknown
minfi version: unknown
Manifest version: unknown
...但不在基础矩阵类中:
d> zeroDetectionP
S1 S2 S3 S4 S5
F1 0 0 0 0 0
F2 0 0 0 0 0
F3 0 0 0 0 0
F4 0 0 0 0 0
F5 0 0 0 0 0
d> zeroDetectionP[bar1]
Error en zeroDetectionP[bar1] : invalid subscript type 'S4'
在 setMethod 文档中,它表示您可以使用签名中的基类定义方法,这使我认为我可以使用 ANY实现类似于以前方法的内容签名并且只有当下标对象未实现 nrow (), ncol ()或运算符' ['。
非常感谢任何帮助或提示。
更新:设置特定的签名方法(如@hadley建议的那样)
如果我为矩阵基类设置一个具有特定签名的方法......
d> getMethod('[', c(x='matrix', i='FilterCommandIndices', j='missing'))
Method Definition:
function (x, i, j, ..., drop = TRUE)
{
return(x) # Dummy method
}
...然后再次尝试下标矩阵......
d> zeroDetectionP[bar1]
Error en zeroDetectionP[bar1] : invalid subscript type 'S4'
......错误仍然存在。
更新:最小可重复的示例
我试图写一个最小的场景,我可以重现前一个场景。我认为,这是一个给出相同错误的简单方案。正如@hadley建议的那样,可能是由于下标是原始的。
library(methods)
setClass('Indices', representation(rows='logical', cols='logical'))
setMethod('[', c(x='ANY', i='Indices', j='missing'),
function(x, i, j, ..., drop=FALSE) {
return(x[i@rows, i@cols])
})
setClass('M', representation(m='matrix'))
setMethod('[', c(x='M', i='logical', j='logical'),
function(x, i, j, ..., drop=FALSE) {
return(x@m[i, j])
})
anIndicesObject <- new('Indices', rows=c(TRUE, TRUE, FALSE), cols=c(FALSE, TRUE, FALSE))
aMatrix <- matrix(1:9, nrow=3)
aMobject <- new('M', m=aMatrix)
aMobject # Prints the M object
aMobject[c(TRUE, TRUE, FALSE), c(TRUE, TRUE, TRUE)] # Susbcript by logical vector
aMobject[anIndicesObject] # Subscript by Indices class
aMatrix[anIndicesObject] # Subscript a matrix by Indices --> ERROR
答案 0 :(得分:2)
更可重复的例子:
library(methods)
setClass("Indices", representation(rows = "logical", cols = "logical"))
x <- new("Indices", rows=c(TRUE, TRUE, FALSE), cols=c(FALSE, TRUE, FALSE))
m <- matrix(1:9, nrow=3)
m[x]
# Method doesn't appear to be found for signature x = "ANY"
show_s4 <- function(x, i, j, ..., drop=FALSE) "S4"
setMethod("[", signature(x = "ANY", i = "Indices", j = "missing"), show_s4)
m[x]
# Or even with explicit "matrix" in signature
setMethod("[", signature(x = "matrix", i = "Indices"), show_s4)
m[x]
# Error in m[x] : invalid subscript type "S4"
# Describing all arguments also fails
getGeneric("[")
setMethod(
"[",
signature(x = "matrix", i = "Indices", j = "missing", drop = "missing"),
show_s4
)
m[x]
我认为关键是?Methods
中的这句话:
如果是S3通用功能,则不会单独看到S4方法 被直接调用。但是,原始函数和运算符 是例外:如果和,内部C代码将查找S4方法 仅当对象是S4对象时。
由于矩阵不是S4类,因此您无法使用内部通用方法(如[
)