2015-05-14 9 views
5

È possibile restituire un oggetto invisibile quando si utilizza la funzione di indicizzazione S3 "[" su una classe personalizzata? Ad esempio, nel codice qui sotto, c'è un modo per fare in modo che l'ultima riga di codice non stampi nulla?Ritorna dalla funzione di indicizzazione S3 "[" invisibile

mat <- function(x) { 
    structure(x, class="mat") 
} 

"[.mat" <- function(x, i, j) { 
    invisible(unclass(x)[i,j]) 
} 

m1 <- mat(matrix(1:10, ncol=2)) 
m1[1:2,] 

    [,1] [,2] 
[1,] 1 6 
[2,] 2 7 
+0

Non so nulla di fare lezioni, ma il tuo sembra malformato. 'str (m1)' funziona bene prima di definire '" [.mat "' ma dà un errore in seguito. – Frank

risposta

3

Il problema è che il valore restituito da [.mat non è di classe mat dal momento che si sta utilizzando unclass, in modo che utilizza il metodo di stampa di default per qualsiasi classe che ha. Per risolvere questo problema, assicurati che l'oggetto restituito sia ancora un mat e definisci un metodo di stampa per gli oggetti mat.

mat <- function(x) { 
    class(x) <- "mat" 
    x 
} 

`[.mat` <- function(x, i, j) { 
    y <- mat(unclass(x)[i, j]) 
    invisible(y) 
} 

print.mat <- function(x, ...) { 
    invisible(x) 
} 

test <- mat(matrix(1:10, ncol = 2)) 

test[1, 1] 
# Nothing is printed 
+0

Ancora stampe per me su R-3.2.0 su Ubuntu 64-bit. –

+0

Non riesco a riprodurre il comportamento che descrivi (R3.1.2), ottengo ancora l'output con il tuo codice. Inoltre, non sono sicuro di essere d'accordo con la tua logica. – BrodieG

+0

Non funziona neanche per me. Ma dopo aver aggiunto '" print.mat "<- function (x, ...) {}' al codice di @Alex A.. – cryo111

6

Si verificano problemi con il meccanismo di visibilità causato da funzioni primitive. Considerare:

> length.x <- function(x) invisible(23) 
> length(structure(1:10, class="x")) 
[1] 23 
> mean.x <- function(x) invisible(23) 
> mean(structure(1:10, class="x")) 
> # no output 

length è un primitivo, ma non è mean. Da R Internals:

Se il valore restituito di un'espressione R primo livello viene stampato è controllato dalla R_Visible variabile booleana globale. Questo è impostato (su true o false) in ingresso a tutte le funzioni primitive e interne basate sulla colonna eval della tabella nel file src/main/names.c: l'impostazione appropriata può essere estratta dalla macro PRIMPRINT.

e

funzioni interne e primitive costringono l'impostazione documentata di R_Visible al ritorno, a meno che il codice C è consentito cambiare (le eccezioni di cui sopra sono indicati con PRIMPRINT avente valore 2).

così sembrerebbe che non si può forzare rendimenti invisibili dei generici primitivi come [, length, ecc, e si deve ricorrere a soluzioni alternative, come quella suggerita da Alex.

+0

Grazie per questa spiegazione dettagliata – Abiel

+0

è fantastico ks per fornire queste informazioni. –