Supponiamo che io sono un vettore-come classe S4:Perché lapplicazione non funziona su oggetti S4 che hanno un metodo as.list.default?
.MyClass <- setClass("MyClass", representation(a="numeric", b="character"))
setMethod("[", c("MyClass", "numeric", "missing"), function(x, i, j, ...) {
do.call(initialize, c(x, sapply(slotNames(x), function(y) slot(x, y)[i],
simplify=FALSE)))
})
setMethod("length", "MyClass", function(x) length([email protected]))
E dire che sono anche definiti i metodi per as.list
e as.list.default
:
setGeneric("as.list")
setMethod("as.list", "MyClass",
function(x) lapply(seq_along(x), function(i) x[i]))
setGeneric("as.list.default")
setMethod("as.list.default", "MyClass",
function(x) lapply(seq_along(x), function(i) x[i]))
Ora dato un oggetto di questa classe, myobj
:
myobj <- .MyClass(a=1:4, b=letters[1:4])
Quando uso lapply
, si lamenta:
> lapply(myobj, function(i) rep([email protected], [email protected]))
Error in as.list.default(X) :
no method for coercing this S4 class to a vector
Ma se io uso as.list.default
, la funzione fornisce l'output desiderato:
> lapply(as.list.default(myobj), function(i) rep([email protected], [email protected]))
[[1]]
[1] "a"
[[2]]
[1] "b" "b"
...
Perché lapply
non funziona anche se ho definito un metodo per as.list.default
per la classe?
Ovviamente è possibile definire manualmente un metodo lapply
per la classe e funzionerà correttamente (sotto), ma mi chiedevo dove si trova effettivamente l'errore. Perché lapply
tenta di forzare il mio oggetto in un vettore anche se la funzione che sta chiamando deve trasformare l'oggetto in un elenco?
setGeneric("lapply")
setMethod("lapply", c("MyClass", "function"), function(X, FUN, ...) {
lapply(as.list(X), FUN, ...)
})
lapply(myobj, function(i) rep([email protected], [email protected]))
Non c'è bisogno di ridefinire i farmaci generici qui. Altrimenti, il tuo codice dovrebbe funzionare perfettamente. – agstudy
Generalmente creo i generici, quindi non vedo i messaggi di "Creazione di una funzione generica per ...". Potrei usare 'sink' o' capture.output', ma ciò sembra più complicato della semplice definizione di generici. –