Angenommen, ich eine Vektor-like S4 Klasse:Warum funktioniert das nicht auf S4-Objekten, die eine as.list.default-Methode haben?
.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]))
Und sagen, ich habe auch für as.list
Methoden definiert und 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]))
nun ein Objekt dieser Klasse gegeben, myobj
:
myobj <- .MyClass(a=1:4, b=letters[1:4])
Wenn ich lapply
verwende, klagt es:
> 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
Aber wenn ich as.list.default
verwenden, gibt die Funktion die gewünschte Ausgabe:
> lapply(as.list.default(myobj), function(i) rep([email protected], [email protected]))
[[1]]
[1] "a"
[[2]]
[1] "b" "b"
...
Warum funktioniert lapply
nicht, obwohl ich eine Methode für as.list.default
für die Klasse definiert haben?
Offensichtlich kann ich manuell eine lapply
Methode für die Klasse definieren und es wird gut funktionieren (unten), aber ich frage mich, wo der Fehler tatsächlich angetroffen wird. Warum versucht lapply
, mein Objekt in einen Vektor zu zwingen, obwohl die Funktion, die es aufruft, das Objekt in eine Liste verwandeln soll?
setGeneric("lapply")
setMethod("lapply", c("MyClass", "function"), function(X, FUN, ...) {
lapply(as.list(X), FUN, ...)
})
lapply(myobj, function(i) rep([email protected], [email protected]))
Keine Notwendigkeit, die Generika hier neu zu definieren. Ansonsten sollte der Code wunderbar funktionieren. – agstudy
Ich erstelle normalerweise Generics, so dass ich die 'Creating a generic function for ...' Nachrichten nicht sehe. Ich könnte 'sink' oder' capture.output' verwenden, aber das scheint unsinniger als nur Generika zu definieren. –