Come scrivere una funzione c () per la personalizzazione di classe S3 in R

StackOverflow https://stackoverflow.com/questions/4241229

  •  27-09-2019
  •  | 
  •  

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).

È stato utile?

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?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top