Come scrivere una funzione c () per la personalizzazione di classe S3 in R
Domanda
Sto scrivendo una classe S3 in R che è solo un intero con alcuni attributi collegati ad esso. Se X1 e X2 sono oggetti di questa classe (lo chiamano "myclass"), poi vorrei c (x1, x2) per restituire un vettore di MyClass oggetti con la definizione della classe originale e gli attributi intatti. Tuttavia, il comportamento documentato di c () è quello di rimuovere gli attributi, così sembrerebbe che ho bisogno di scrivere il mio metodo proprio c.myclass (). La mia domanda è: come posso fare questo?
Un esempio del problema:
myclass <- function(x, n) structure(x, class="myclass", n=n)
x1 <- myclass(1, 5)
x2 <- myclass(2, 6)
c(x1, x2)
[1] 1 2
Ecco il risultato è solo un vettore di oggetti di classe numerica, e l'attributo originale n è andato.
Guardando il codice per i vari pacchetti, a volte vedere il codice come il seguente, in cui abbiamo bisogno di preservare l'attributo class, ma nient'altro:
c.myclass <- function(..., recursive = F) {
structure(c(unlist(lapply(list(...), unclass))), class="myclass")
}
Purtroppo anche io non può ottenere questo al lavoro. Il risultato della chiamata c.myclass (x1, x2) è un vettore in cui il vettore stesso ha classe "myclass", ma nel quale ciascun elemento del vettore ha classe numerica; Voglio davvero ogni elemento del vettore di avere classe "myclass". In pratica ho anche bisogno di aggiornare questo metodo per conservare altri attributi, come pure (come l'attributo "n" in myclass).
Soluzione
Questo funziona, ma presumo che concludere che ogni elemento del vettore ha classe numerica perché si sta facendo qualcosa di simile a questo:
foo <- c(x1, x2)
class(foo[1])
class(foo[2])
Se questo è il caso e si desidera elementi estratti di mantenere l'attributo myclass
, è necessario scrivere un metodo sottoinsieme "[.myclass"
per mantenere gli attributi.
Altri suggerimenti
Ecco un esempio che fa (credo) ciò che si vuole tramite metodi specifici per c
e [
:
c.myclass <- function(..., recursive = FALSE) {
dots <- list(...)
ns <- sapply(dots, attr, which = "n")
classes <- rep("myclass", length(dots))
res <- structure(unlist(dots, recursive = FALSE), class = classes)
attr(res, "n") <- ns
res
}
`[.myclass` <- function (x, i) {
y <- unclass(x)[i]
ns <- attr(x, "n")[i]
class(y) <- "myclass"
attr(y, "n") <- ns
y
}
myclass <- function(x, n) structure(x, class = "myclass", n = n)
x1 <- myclass(1, 5)
x2 <- myclass(2, 6)
c(x1, x2)
c(x1, x2)[2]
Ma questo è un fondente in che dobbiamo gestire la movimentazione l'impostazione e sottoinsiemi di attributi extra per tenere il n
. Questo è in realtà solo un vettore numerico con un attributo per la registrazione n
.
Potrebbe essere più naturale per il lavoro con il generico di tutti i vettori, una lista. Bit che è più coinvolto e forse quanto sopra è sufficiente nel tuo caso?