definiert benutzerdefinierte dplyr-Methoden im R-Paket

8

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 .

das funktioniert

%Vor%

Hier ist das Problem

%Vor%

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.

was ich versucht habe

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

%Vor%

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!

    
Andrew 31.01.2017, 21:21
quelle

2 Antworten

7

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.

%Vor%

Dabei ist reclass ein generischer Code, der die Klasse mindestens wieder hinzufügt:

%Vor%

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.

%Vor%

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%     
jwdink 29.06.2017, 15:27
quelle
8

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.

%Vor%     
Jonathan Carroll 31.01.2017 22:33
quelle

Tags und Links