Wenn ich ein komplexes R-Projekt durchführe, werden meine Skripte schnell lang und verwirrend.
Welche Methoden kann ich anwenden, damit es immer Spaß macht, mit meinem Code zu arbeiten? Ich denke über Dinge wie nach
- Platzierung von Funktionen in Quelldateien
- Wann soll etwas in eine andere Quelldatei aufgeteilt werden?
- Was sollte in der Master-Datei sein
- Verwenden von Funktionen als Organisationseinheiten (ob dies sinnvoll ist, da R den Zugriff auf den globalen Status erschwert)
- Einrückungs- / Zeilenumbruchpraktiken.
- Behandle (wie {?
- Dinge wie)} in 1 oder 2 Zeilen setzen?
Was sind Ihre Faustregeln für die Organisation großer R-Skripte?
r
package
conventions
code-organization
project-organization
Dan Goldstein
quelle
quelle
ProjectTemplate
Paket ansehen .Antworten:
Die Standardantwort ist die Verwendung von Paketen - siehe das Handbuch Writing R Extensions sowie verschiedene Tutorials im Web.
Es gibt dir
R CMD check
Nur
source()
über Code zu laufen funktioniert für wirklich kurze Schnipsel. Alles andere sollte in einem Paket enthalten sein - auch wenn Sie nicht vorhaben, es zu veröffentlichen, da Sie interne Pakete für interne Repositorys schreiben können.Was den Teil "Bearbeiten" betrifft, enthält das R Internals- Handbuch in Abschnitt 6 hervorragende R-Codierungsstandards . Andernfalls verwende ich im ESS-Modus von Emacs normalerweise Standardeinstellungen .
Update 13.08.2008: David Smith hat gerade über den Google R Style Guide gebloggt .
quelle
Ich mag es, verschiedene Funktionen in ihre eigenen Dateien zu stellen.
Aber ich mag Rs Paketsystem nicht. Es ist ziemlich schwer zu bedienen.
Ich bevorzuge eine einfache Alternative, um die Funktionen einer Datei in einer Umgebung zu platzieren (was jede andere Sprache als "Namespace" bezeichnet) und sie anzuhängen. Zum Beispiel habe ich eine 'util'-Gruppe von Funktionen wie folgt erstellt:
Das ist alles in einer Datei util.R . Wenn Sie es beschaffen, erhalten Sie die Umgebung "util", so dass Sie anrufen können
util$bgrep()
und so; aber darüber hinausattach()
macht der Anruf es so gerechtbgrep()
und solche Arbeit direkt. Wenn Sie nicht alle diese Funktionen in ihre eigene Umgebung stellen würden, würden sie den obersten Namespace des Interpreters (den angezeigten) verschmutzenls()
.Ich habe versucht, Pythons System zu simulieren, bei dem jede Datei ein Modul ist. Das wäre besser zu haben, aber das scheint in Ordnung zu sein.
quelle
sys.source
:MyEnv <- attach(NULL, name=s_env); sys.source(file, MyEnv)
. Ich deklariere sogar (in seiner eigenen Umgebung!) Beim Start eine Funktion,sys.source2
die nachschaut, ob bereits eine gleichnamige Umgebung vorhanden ist, und diese füttert, anstatt eine neue zu erstellen. Es macht das Hinzufügen persönlicher Funktionen schnell, einfach und irgendwie organisiert :-)Dies mag ein wenig offensichtlich klingen, besonders wenn Sie ein Programmierer sind, aber hier ist, wie ich über logische und physische Codeeinheiten denke.
Ich weiß nicht, ob dies Ihr Fall ist, aber wenn ich in R arbeite, beginne ich selten mit einem großen komplexen Programm. Normalerweise beginne ich in einem Skript und trenne Code in logisch trennbare Einheiten, wobei ich häufig Funktionen verwende. Datenmanipulations- und Visualisierungscode werden in ihre eigenen Funktionen usw. eingefügt. Diese Funktionen sind in einem Abschnitt der Datei zusammengefasst (Datenmanipulation oben, dann Visualisierung usw.). Letztendlich möchten Sie darüber nachdenken, wie Sie die Verwaltung Ihres Skripts vereinfachen und die Fehlerrate senken können.
Wie fein / grobkörnig Sie Ihre Funktionen gestalten, hängt von verschiedenen Faustregeln ab: z. B. 15 Codezeilen oder "Eine Funktion sollte für die Ausführung einer Aufgabe verantwortlich sein, die durch ihren Namen gekennzeichnet ist" usw. Ihr Kilometerstand variiert . Da R Call-by-Reference nicht unterstützt, kann ich meine Funktionen normalerweise zu feinkörnig gestalten, wenn Datenrahmen oder ähnliche Strukturen weitergegeben werden. Aber dies kann eine Überkompensation für einige dumme Leistungsfehler sein, als ich mit R anfing.
Wann sollten logische Einheiten in ihre eigenen physischen Einheiten extrahiert werden (wie Quelldateien und größere Gruppierungen wie Pakete)? Ich habe zwei Fälle. Erstens ist es ärgerlich, wenn die Datei zu groß wird und zwischen logisch nicht verwandten Einheiten gescrollt wird. Zweitens, wenn ich Funktionen habe, die von anderen Programmen wiederverwendet werden können. Normalerweise beginne ich damit, eine gruppierte Einheit, beispielsweise Datenmanipulationsfunktionen, in einer separaten Datei abzulegen. Ich kann diese Datei dann aus jedem anderen Skript beziehen.
Wenn Sie Ihre Funktionen bereitstellen möchten, müssen Sie über Pakete nachdenken. Ich setze R-Code aus verschiedenen Gründen nicht in der Produktion oder zur Wiederverwendung durch andere ein (kurz: Die Organisationskultur bevorzugt andere Sprachen, Bedenken hinsichtlich der Leistung, der GPL usw.). Außerdem neige ich dazu, meine Sammlungen von Quelldateien ständig zu verfeinern und zu erweitern, und ich möchte mich lieber nicht mit Paketen befassen, wenn ich Änderungen vornehme. Weitere Informationen zu diesem Thema finden Sie in den anderen paketbezogenen Antworten wie Dirk's.
Schließlich denke ich, dass Ihre Frage nicht unbedingt speziell für R ist. Ich würde wirklich empfehlen, Code Complete von Steve McConnell zu lesen, der viel Weisheit über solche Probleme und Codierungspraktiken im Allgemeinen enthält.
quelle
Ich stimme Dirk Rat! IMHO ist das Organisieren Ihrer Programme von einfachen Skripten bis zu dokumentierten Paketen für das Programmieren in R wie das Wechseln von Word zu TeX / LaTeX zum Schreiben. Ich empfehle einen Blick auf die sehr nützlichen R-Pakete erstellen: Ein Tutorial von Friedrich Leisch.
quelle
Meine prägnante Antwort:
Ich glaube, dass R in der Produktion immer häufiger verwendet wird, daher ist der Bedarf an wiederverwendbarem Code größer als zuvor. Ich finde den Dolmetscher viel robuster als zuvor. Es besteht kein Zweifel, dass R 100-300x langsamer als C ist, aber normalerweise konzentriert sich der Engpass auf einige Codezeilen, die an C / C ++ delegiert werden können. Ich denke, es wäre ein Fehler, die Stärken von R bei der Datenmanipulation und statistischen Analyse an eine andere Sprache zu delegieren. In diesen Fällen ist der Leistungsverlust gering und auf jeden Fall die Einsparungen beim Entwicklungsaufwand wert. Wenn nur die Ausführungszeit in Frage käme, würden wir alle Assembler schreiben.
quelle
Ich wollte herausfinden, wie man Pakete schreibt, habe aber nicht die Zeit investiert. Für jedes meiner Mini-Projekte behalte ich alle meine Low-Level-Funktionen in einem Ordner namens 'functions /' und speichere sie in einem separaten Namespace, den ich explizit erstelle.
Die folgenden Codezeilen erstellen eine Umgebung mit dem Namen "myfuncs" im Suchpfad, falls diese noch nicht vorhanden ist (mithilfe von "Anhängen"), und füllen sie mit den Funktionen, die in den .r-Dateien in meinem Verzeichnis "functions /" enthalten sind (mithilfe von " sys.source). Normalerweise füge ich diese Zeilen oben in mein Hauptskript ein, das für die "Benutzeroberfläche" bestimmt ist, über die Funktionen auf hoher Ebene (Aufrufen der Funktionen auf niedriger Ebene) aufgerufen werden.
Wenn Sie Änderungen vornehmen, können Sie diese jederzeit mit denselben Zeilen neu beziehen oder so etwas verwenden
um Ergänzungen / Änderungen in der von Ihnen erstellten Umgebung zu bewerten.
Ich weiß, dass es kludgey ist, aber es vermeidet, zu formal zu sein (aber wenn Sie die Chance bekommen, ermutige ich das Paketsystem - hoffentlich werde ich in Zukunft auf diese Weise migrieren).
Codierungskonventionen sind das einzige, was ich in Bezug auf Ästhetik gesehen habe (ich mag sie und folge locker, aber ich verwende nicht zu viele geschweifte Klammern in R):
http://www1.maths.lth.se/help/R/RCC/
Es gibt andere "Konventionen" bezüglich der Verwendung von [, drop = FALSE] und <-, wie der Zuweisungsoperator in verschiedenen Präsentationen (normalerweise Keynote) bei useR vorgeschlagen hat! Konferenzen, aber ich denke nicht, dass diese streng sind (obwohl [, drop = FALSE] für Programme nützlich ist, bei denen Sie sich nicht sicher sind, welche Eingabe Sie erwarten).
quelle
Zählen Sie mich als eine andere Person für Pakete. Ich gebe zu, dass ich ziemlich schlecht darin bin, Manpages und Vignetten zu schreiben, bis ich muss (dh veröffentlicht werde), aber es ist eine sehr praktische Möglichkeit, das Quell-Doe zu bündeln. Wenn Sie es ernst meinen, Ihren Code zu pflegen, kommen die Punkte, die Dirk anspricht, alle in Plya.
quelle
Ich stimme auch zu. Verwenden Sie die Funktion package.skeleton (), um loszulegen. Selbst wenn Sie der Meinung sind, dass Ihr Code möglicherweise nie wieder ausgeführt wird, kann dies Sie motivieren, allgemeineren Code zu erstellen, der Ihnen später Zeit sparen könnte.
Der Zugriff auf die globale Umgebung ist mit dem Operator << - einfach, obwohl davon abgeraten wird.
quelle
Nachdem ich noch nicht gelernt habe, wie man Pakete schreibt, habe ich mich immer durch die Beschaffung von Unterskripten organisiert. Es ist ähnlich wie beim Schreiben, aber nicht so involviert. Es ist nicht programmatisch elegant, aber ich finde, dass ich im Laufe der Zeit Analysen aufbaue. Sobald ich einen großen Abschnitt habe, der funktioniert, verschiebe ich ihn oft in ein anderes Skript und beziehe ihn einfach, da er die Arbeitsbereichsobjekte verwendet. Vielleicht muss ich Daten aus mehreren Quellen importieren, alle sortieren und die Schnittpunkte finden. Ich könnte diesen Abschnitt in ein zusätzliches Skript einfügen. Wenn Sie Ihre "Anwendung" jedoch für andere Personen verteilen möchten oder interaktive Eingaben verwenden, ist ein Paket wahrscheinlich eine gute Route. Als Forscher muss ich meinen Analysecode selten verteilen, aber ich muss ihn oft erweitern oder optimieren.
quelle
Ich habe auch nach dem heiligen Gral des richtigen Workflows gesucht, um ein R-Großprojekt zusammenzustellen. Ich habe letztes Jahr dieses Paket namens rsuite gefunden , und es war sicherlich das, wonach ich gesucht habe. Dieses R-Paket wurde explizit für die Bereitstellung großer R-Projekte entwickelt, aber ich habe festgestellt, dass es für kleinere, mittlere und große R-Projekte verwendet werden kann. Ich werde in einer Minute (unten) Links zu Beispielen aus der realen Welt geben, aber zuerst möchte ich das neue Paradigma des Baus von R-Projekten erklären
rsuite
.Hinweis. Ich bin nicht der Schöpfer oder Entwickler von
rsuite
.Wir haben mit RStudio alle Projekte falsch gemacht. Das Ziel sollte nicht die Erstellung eines Projekts oder eines Pakets sein, sondern einen größeren Umfang. In rsuite erstellen Sie ein Superprojekt oder Masterprojekt, das die Standard-R-Projekte und R-Pakete in allen möglichen Kombinationen enthält.
Mit einem R-Superprojekt benötigen Sie kein Unix mehr
make
, um die unteren Ebenen der darunter liegenden R-Projekte zu verwalten. Sie verwenden oben R-Skripte. Lass mich dir zeigen. Wenn Sie ein rsuite-Masterprojekt erstellen, erhalten Sie folgende Ordnerstruktur:In dem Ordner
R
legen Sie Ihre Projektverwaltungsskripte ab, die ersetzt werdenmake
.Der Ordner
packages
ist der Ordner, in demrsuite
alle Pakete enthalten sind, aus denen das Superprojekt besteht. Sie können auch ein Paket kopieren und einfügen, auf das über das Internet nicht zugegriffen werden kann, und rsuite erstellt es ebenfalls.der Ordner
deployment
ist , worsuite
alle Paket - Binärdateien schreiben werden , die in den Paketen angegeben wurdenDESCRIPTION
Dateien. Auf diese Weise projizieren Sie für sich genommen eine vollständig reproduzierbare Accros-Zeit.rsuite
kommt mit einem Client für alle Betriebssysteme. Ich habe sie alle getestet. Sie können es aber auch alsaddin
RStudio installieren .rsuite
Außerdem können Sie eine isolierteconda
Installation in einem eigenen Ordner erstellenconda
. Dies ist keine Umgebung, sondern eine physische Python-Installation, die von Anaconda auf Ihrem Computer abgeleitet wurde. Dies funktioniert zusammen mitSystemRequirements
Rs, von denen aus Sie alle gewünschten Python-Pakete von jedem gewünschten Conda-Kanal aus installieren können.Sie können auch lokale Repositorys erstellen, um R-Pakete abzurufen, wenn Sie offline sind oder das Ganze schneller erstellen möchten.
Wenn Sie möchten, können Sie das R-Projekt auch als Zip-Datei erstellen und für Kollegen freigeben. Es wird ausgeführt, vorausgesetzt, Ihre Kollegen haben dieselbe R-Version installiert.
Eine weitere Option ist das Erstellen eines Containers des gesamten Projekts in Ubuntu, Debian oder CentOS. Anstatt eine Zip-Datei für Ihren Projektaufbau freizugeben, teilen Sie den gesamten
Docker
Container mit Ihrem Projekt, das zur Ausführung bereit ist.Ich habe viel mit der
rsuite
Suche nach vollständiger Reproduzierbarkeit experimentiert und es vermieden, von den Paketen abhängig zu sein, die man in der globalen Umgebung installiert. Dies ist falsch, da das Projekt nach der Installation eines Paketupdates häufig nicht mehr funktioniert, insbesondere bei Paketen mit sehr spezifischen Aufrufen einer Funktion mit bestimmten Parametern.Das erste, was ich anfing zu experimentieren, war mit
bookdown
E-Books. Ich hatte nie das Glück, eine Buchung zu haben, um den Test der Zeit länger als sechs Monate zu überstehen. Also habe ich das ursprüngliche Bookdown-Projekt so konvertiert, dass es demrsuite
Framework folgt . Jetzt muss ich mich nicht mehr um die Aktualisierung meiner globalen R-Umgebung kümmern, da das Projekt eigene Pakete imdeployment
Ordner hat.Das nächste, was ich tat, war das Erstellen von Projekten für maschinelles Lernen, aber im
rsuite
Weg. Ein Master, ein Orchestrierungsprojekt an der Spitze und alle Unterprojekte und Pakete, die vom Master gesteuert werden sollen. Es verändert wirklich die Art und Weise, wie Sie mit R codieren, und macht Sie produktiver.Danach fing ich an, in einem neuen Paket von mir zu arbeiten
rTorch
. Dies war größtenteils möglich wegenrsuite
; es lässt dich denken und groß werden.Ein Ratschlag. Lernen
rsuite
ist nicht einfach. Da es eine neue Art der Erstellung von R-Projekten darstellt, fühlt es sich schwierig an. Bestürzung nicht bei den ersten Versuchen, klettere weiter den Hang hinauf, bis du es schaffst. Es erfordert fortgeschrittene Kenntnisse Ihres Betriebssystems und Ihres Dateisystems.Ich gehe davon aus, dass
RStudio
wir eines Tages Orchestrierungsprojekte wiersuite
im Menü erstellen können. Es wäre großartig.Links:
RSuite GitHUb Repo
r4ds bookdown
Keras und glänzendes Tutorial
moderndive-book-rsuite
interpretable_ml-rsuite
IntroMachineLearningWithR-rsuite
clark-intro_ml-rsuite
hyndman-bookdown-rsuite
statistische_Rethinking-Rsuite
Fread-Benchmarks-Rsuite
dataviz-rsuite
Retail-Segmentation-H2O-Tutorial
telco-customer-churn-tutorial
sclerotinia_rsuite
quelle
R ist für die interaktive Verwendung und kleine Skripte in Ordnung, aber ich würde es nicht für ein großes Programm verwenden. Ich würde für den größten Teil der Programmierung eine Mainstream-Sprache verwenden und diese in eine R-Schnittstelle einbinden.
quelle
Rcpp
Pakets, einschließlich C ++ - Code in R-Programmen, ist recht einfach. Das Umschreiben bestimmter Teile des R-Codes kann also ganz einfach in R integriert werden. Darüber hinaus hat das Aufkommen von RStudio eine IDE für R eingeführt, die möglicherweise noch nicht so leistungsfähig ist wie Visual Studio.