Come definire gli operatori di sottoinsiemi per una class S4?

Non riesco a trovare il modo corretto per definire [ , $ e [[ operatori sottoinsiemi per una class S4.

Qualcuno può fornirmi un esempio di base della definizione di questi tre per una class S4?

Scopri il generico in modo da sapere a cosa miriamo

 > getGeneric("[") standardGeneric for "[" defined from package "base" function (x, i, j, ..., drop = TRUE) standardGeneric("[", .Primitive("["))   Methods may be defined for arguments: x, i, j, drop Use showMethods("[") for currently available ones. 

Definisci una class semplice

 setClass("A", representation=representation(slt="numeric")) 

e implementare un metodo

 setMethod("[", c("A", "integer", "missing", "ANY"), ## we won't support subsetting on j; dispatching on 'drop' doesn't ## make sense (to me), so in rebellion we'll quietly ignore it. function(x, i, j, ..., drop=TRUE) { ## less clever: update slot, return instance ## [email protected] = [email protected][i] ## x ## clever: by default initialize is a copy constructor, too initialize(x, [email protected][i]) }) 

In azione:

 > a = new("A", slt=1:5) > a[3:1] An object of class "A" Slot "slt": [1] 3 2 1 

Esistono diverse strategie per supportare le firme (implicitamente), ad esempio è probabile che vogliate anche supportare valori di indice logico e di caratteri, possibilmente per entrambi i e j. Il più diretto è un pattern di “facciata” in cui ogni metodo esegue una coercizione preliminare a un tipo comune di indice di sottoinsieme, ad esempio integer per consentire il riordino e la ripetizione di voci di indice e quindi utilizza callGeneric per richiamare un singolo metodo questo fa il lavoro di sottomettere la class.

Non ci sono differenze concettuali per [[ , diverso dal voler rispettare la semantica di restituire il contenuto piuttosto che un’altra istanza dell’object come implicita da [ . Per $ abbiamo

 > getGeneric("$") standardGeneric for "$" defined from package "base" function (x, name) standardGeneric("$", .Primitive("$"))   Methods may be defined for arguments: x Use showMethods("$") for currently available ones. 

e

 setMethod("$", "A", function(x, name) { ## 'name' is a character(1) slot(x, name) }) 

con

 > a$slt [1] 1 2 3 4 5 

Vorrei fare come @Martin_Morgan ha suggerito per gli operatori che hai citato. Vorrei aggiungere un paio di punti però:

1) Sarei attento a definire un operatore $ per accedere ad uno slot S4 (a meno che non intendi accedere a una colonna da un frame di dati che è memorizzato in uno slot specifico?). Il suggerimento generale è di scrivere funzioni accessorie come getMySlot() e setMySlot() per ottenere le informazioni necessarie. È ansible utilizzare l’operatore @ per accedere ai dati da tali slot, anche se ottenere e impostare sono i migliori come interfaccia utente. L’utilizzo di $ potrebbe confondere l’utente, che probabilmente si aspetterebbe un data.frame. Vedi questo tutorial S4 di Christophe Genolini per una discussione approfondita di questi problemi. Se questo non è il modo in cui hai intenzione di usare $ , trascura il mio suggerimento (ma il tutorial è ancora un’ottima risorsa!).

2) Se stai definendo [ e [[ per ereditare da un’altra class, come vettore, dovrai anche definire el() (equivalente a [][[1L]] , o il primo elemento da un sottoinsieme [] ) e length() . Attualmente sto scrivendo una class per ereditare da numerici, e i metodi numerici cercheranno automaticamente di usare queste funzioni dalla tua class. Se la lezione è per un uso più limitato o personale, questo potrebbe non essere un problema.

Mi scuso, avrei lasciato questo come commento, ma sono nuovo di SO e non ho ancora il rappresentante!