2014-03-13 68 views
1

我已經定義稱爲S4類FilterCommandIndices這種方式:爲基矩陣類標操作符[R 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([email protected]) 
     }) 

setGeneric('getCols', function(object) standardGeneric('getCols')) 

setMethod('getCols', 'FilterCommandIndices', 
     function(object) { 
     return([email protected]) 
     }) 

我認爲通過使用ANY簽名,我可以使這個簡單的類和操作符組合在基類中工作,就像簡單的ma trix。雖然它似乎在一個示例類工作...

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()或運算符'['。

任何幫助或提示將不勝感激。

UPDATE:設置特定的簽名方法(如@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' 

......錯誤仍然存​​在。

UPDATE:最小的可重複的例子

我試圖寫一個最小的情況下,我可以重現以前的方案。我認爲,這是一個簡單的情況,它給出了同樣的錯誤。正如@哈德利所說,這可能是由於下標是一個原始的。

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[[email protected], [email protected]]) 
     }) 

setClass('M', representation(m='matrix')) 

setMethod('[', c(x='M', i='logical', j='logical'), 
     function(x, i, j, ..., drop=FALSE) { 
     return([email protected][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 
+1

嘗試顯式'使用setMethod( '[',C(X = '矩陣',我='FilterCommandIndices',j ='missing')'? – hadley

+0

我已經編輯了這個問題來添加額外的信息 – Fernandez

+0

嗯,可能是因爲'['是原始的,但你更可能得到幫助,如果你產生一個_minimal_ reproducible的例子,可以很容易地複製和粘貼到R. – hadley

回答

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

的S4單獨方法不會,如果S3泛型函數 可以看出直接調用。但是,原始函數和運算符 是例外:內部C代碼將查找S4方法if和 只有當對象是S4對象時。

由於矩陣不是S4類,你不能在它在內部通用方法分派(如[

+0

太棒了! 很多!現在它是有道理的,至少我可以從這句話中得到的所有意義?方法。感謝您的時間。 – Fernandez