Ich habe ein Paket mit benutzerdefinierten Methoden summary()
, print()
für Objekte mit einer bestimmten Klasse. Dieses Paket verwendet auch das wunderbare Paket dplyr
für die Datenbearbeitung - und ich erwarte, dass meine Benutzer Skripte schreiben, die sowohl mein Paket als auch dplyr verwenden.
Eine Straßensperre, die von anderen hier und hier ist, dass dplyr-Verben keine benutzerdefinierten Klassen beibehalten - was bedeutet, dass ein ungroup
-Befehl meine data.frames ihrer eigenen Klassen streichen kann, und damit den Methodenversand für summary
, etc.
Hadley sagt: "Das richtig zu tun liegt an Ihnen - Sie müssen eine Methode für Ihre Klasse für jede dplyr-Methode definieren, die alle Klassen und Attribute korrekt wiederherstellt" und ich versuche, die Ratschläge - aber ich kann nicht herausfinden, wie man die dplyr-Verben korrekt umschließt.
Hier ist ein einfaches Spielzeugbeispiel. Angenommen, ich habe eine cars
-Klasse definiert und dafür eine benutzerdefinierte summary
.
dass summary
call für small_cars
gibt mir nur die allgemeine Zusammenfassung, nicht meine benutzerdefinierte Methode, weil small_cars
nicht mehr die Klasse cars
nach dplyr-Filterung beibehält.
Zuerst habe ich versucht, eine benutzerdefinierte Methode um filter
( filter.cars
) zu schreiben. Das hat nicht funktioniert, weil filter
tatsächlich ein Wrapper um filter_
ist, was eine nicht standardmäßige Auswertung erlaubt.
Also schrieb ich eine benutzerdefinierte filter_
-Methode für cars
-Objekte und versuchte @jwdinks Beratung
Das funktioniert nicht - ich bekomme einen unendlichen Rekursionsfehler:
%Vor% Alles, was ich tun möchte, ist, die Klassen auf dem eingehenden df zu nehmen, an dplyr zu übergeben und dann das Objekt mit den gleichen Klassennamen wie vor dem dplyr-Aufruf zurückzugeben. Wie ändere ich meinen filter_
-Wrapper, um das zu erreichen? Danke!
Weitere Vorschläge wurden in dem Thread angeboten, also dachte ich, ich würde mit dem aktualisieren, was als Best Practice erscheint , die NextMethod()
verwenden soll.
Dabei ist reclass
ein generischer Code, der die Klasse mindestens wieder hinzufügt:
Sie können jedoch eine benutzerdefinierte Methode für Ihre Klasse definieren, die auch Attribute zurückkopiert:
%Vor%Ich glaube eigentlich, eine bessere Standardmethode würde einfach annehmen, dass es ein Attribut gibt, dessen Name mit der Klasse identisch ist:
%Vor% Beachten Sie, dass für dplyr 0.7 die Unterstrichversion der Verben veraltet ist. Wenn Ihre Klasse "Autos" von tbl_df
erbt, müssen Sie eine Methode für die Nicht-Unterstrich-Verben schreiben. Aber dann sollten Sie die Unterstreichungsversion aus Gründen der Abwärtskompatibilität beibehalten.
Angesichts all dieser Replik mag ich die Idee eines Adverbs hier.
%Vor%Dann sind die Dinge in Ihrem Paket schön und prägnant:
%Vor%usw.
BEARBEITEN:
Verwenden Sie nicht preservatively
. Es wird zerbrechen, wenn jemand das Verb dplyr mit einem benannten ersten Argument aufruft, da der Name im Allgemeinen .data
, nicht x
ist.
Ich werde diese Antwort aktualisieren, wenn sich herausstellt, dass ein Adverb doch funktionieren kann. Ansonsten denke ich, das ist wirklich nicht mehr ausführlich:
%Vor% Ihre neue filter_
-Methode versucht, auf die neue Klasse innerhalb der Definition anzuwenden, daher die Rekursion.
Folgen Sie nach dem Ratschlag in dem Problem, das Sie verlinkt haben , versuchen Sie, diese neue Klasse vor filter_
zu entfernen aktualisierte Methode.