Ich möchte eine Klasse erstellen, die so ziemlich ein Datenrahmen ist, mit ein paar Verbesserungen (zusätzliche Funktionen, zusätzliche Eigenschaften), und ich frage mich, was der beste Weg dafür ist. Die Klasse ist im Grunde genommen ein Datenrahmen, aber mit einigen zusätzlichen Attributen, wie dem Schema dieses Datenrahmens (nachfolgend als "Formular" bezeichnet), automatisch abgeleitet, dargestellt als ein Datenrahmen, der verwendet wird, um den Datenrahmen in die richtigen Typen zu werfen), und ein paar andere Dinge. Wenn Benutzer dieses Objekt in anderen Funktionen verwenden, die seinen speziellen Typ nicht erkennen, möchte ich, dass sie sich mit dem data.frame-Teil des Objekts befassen. Was ist der beste Weg, dies zu tun?
Die beiden Methoden, die ich gefunden habe, sind beide unbefriedigend; Ich liste sie auf und welche Probleme ich noch sehe und zu lösen versuche; Frage ist: Was ist der beste Weg zu tun, was ich versuche zu tun?
Methode 1: Verwenden Sie "data.frame" als Basis-Slot (inspiriert von diesem SO-Beitrag)
%Vor%Diese Methode erlaubt mir Dinge wie:
%Vor%[Update: Stellt sich heraus, dass der "Zusammenbruch" durch meine Umgebung verursacht wurde, in der ich setClass ('formhubData', ...) wiederholt mit verschiedenen Argumenten aufgerufen habe. In einer neuen R-Sitzung funktionieren alle unten aufgeführten Funktionen wie erwartet.]
Aber es bricht ziemlich schnell zusammen:
%Vor% Im Gegensatz zu dem oben verlinkten Post funktioniert auch das einfache is.data.frame
nicht für mich
Methode 2, verwenden Sie "Daten" slot (inspiriert von SP)
%Vor%Ich verliere die Standarddefinitionen:
%Vor%Aber zumindest kann ich die meisten von ihnen neu definieren (muss noch etwas über [, [[, etc.) lernen:
%Vor% Es scheint jedoch so zu sein, dass ich die Tatsache nicht ausdrücken kann, dass für jede Methode, die einen data.frame verwendet, meine Klasse als Passthrough zu ihrem @ data-Slot verwendet werden soll. Ich habe das Bedürfnis nach etwas wie *.formhubData <- function(x, ...) *(x, ...)
, anstatt zu versuchen, alle Funktionen zu erraten, die die Clients meiner Klasse verwenden könnten, und definiere sie wie dim.formhubData
, names.formhubData
, etc.
Gibt es irgendwelche Möglichkeiten, so etwas zu erreichen?
Während beide Ansätze in gewissem Maße funktionieren, würde ich eigentlich Methode 2 vorschlagen. "Standard" objektorientierte Überlegungen zu "ist-a" versus "hat-a" Designs fallen generell zugunsten von "hat-a" aus . Ferner können in R Methoden zu Objekten jederzeit hinzugefügt werden, also ist "is-a" in gewisser Weise Werbung dafür, dass es sinnvoll ist, eine beliebige Anzahl von vielleicht beliebigen Dingen für Ihre Klasse zu tun. Dies ist ein harter Vertrag, selbst für definierte Funktionen wie die Untereinstellung - vermutlich, wenn der Benutzer Zeilen / Spalten zum zugrunde liegenden data
in formhubData
hinzufügt / hinzufügt, möchten Sie die Informationen in% co_de aktualisieren %.
Stattdessen scheint es, als ob Sie wirklich eine Has-a-Beziehung implementieren möchten, und nutzen Sie die Möglichkeit, die Schnittstelle auf Operationen zu beschränken, die Sinn ergeben. Sie können immer noch wesentliche Code-Wiederverwendung mit minimalem neuen Code durch einfaches Versenden an zugrunde liegende Implementierungen erhalten, z. B.
%Vor% gibt Ihnen beispielsweise form
und nrow
. Für allgemeine Operationen (z. B. Subsetting) möchten Sie Implementierungen bereitstellen, die die Integrität Ihrer Datenstruktur berücksichtigen. Und wenn es tatsächlich der Fall ist, dass der Benutzer in der Lage sein sollte, ziemlich willkürliche Dinge zu tun, können Sie einfache "Zugriffsmechanismen" für ncol
bereitstellen, vielleicht indem Sie den Setter verwenden, um das data
-Feld in Einklang zu bringen mit dem aktualisierten data.frame, der vom Benutzer bereitgestellt wird.
Tags und Links r