Hilfe erstellen für Funktionen in eigenen R-Paketen (roxygen2)

Nachdem wir in früheren Beiträgen gesehen haben, warum und wann es überhaupt sinnvoll ist, eigene R-Pakete zu erstellen und wie man ein erstes Paket in zwei Minuten erstellen kann, wollen wir uns heute mit einem wesentlichen Aspekt von R-Paketen näher beschäftigen: Der Dokumentation. Erst mit einer guten Dokumentation wird unser Paket für andere und, nicht zu vernachlässigen, für uns selbst in der Zukunft leicht(er) anwendbar.

Eine Beispielfunktion: Zufallsalbum ausgeben

Als Beispiel betrachten wir eine relativ simple Funktion, die aus einem Datensatz mit Musikalben ein Album zufällig auswählt und in der Konsole ausgibt. Die Daten stammen von der empfehlenswerten Webseite tsort.info – The World’s Music Charts.

zufallsalbum <- function(band = "The Beatles", data = albums) {
   banddaten <- data[data$artist == band, ]
   if(nrow(banddaten) == 0) stop(paste("Keine Daten zu", band))
   album <- base::sample(banddaten$name, 1)
   cat(paste0("Zufällig ausgewähltes Album von ", band, ": ", album))
 }

The Funktion filtert nach der angegebenen Band (voreingestellter Wert: „The Beatles“), gibt eine Meldung aus, falls keine Daten zur entsprechenden Band vorliegen, zieht zufällig ein Album und gibt dieses aus.

> zufallsalbum()
Zufällig ausgewähltes Album von The Beatles: Anthology 3 

Eine Hilfe steht für diese Funktion zunächst jedoch nicht zur Verfügung:

?zufallsalbum
No documentation for ‘zufallsalbum’ in specified packages and libraries:
you could try ‘??zufallsalbum’ 

Eigene Funktionen dokumentieren wie in der Hilfe von R

Die Dokumentation zu unserem Paket erstellen wir mit Hilfe von sogenannten roxygen-Kommentaren. Das Paket roxygen2, entwickelt von einem Team um Hadley Wickham (siehe help(package = „roxygen2“)), unterstützt uns dabei. Dazu sollten wir in RStudio unter Tools – Project Options – Build Tools die entsprechenden Einstellungen vornehmen:

RStudio: Tools - Project Options - Build Tools: Roxygen aktivieren für die Paket-Dokumentation
RStudio: Tools – Project Options – Build Tools: Roxygen aktivieren für die Paket-Dokumentation

Hier sollten wir Roxygen aktivieren, mindestens für Rd files, sehr empfehlenswert auch für den NAMESPACE. Wer diese Dateien per Hand bearbeitet, kann sich sehr leicht Fehler einbauen.

Vorteile von roxygen2 gegenüber dem Bearbeiten von .Rd-Dateien

.Rd-Dateien enthalten Latex-ähnliche Zeichen, um die Dokumentation zu kennzeichnen. Aus ihnen erstellt R bei der Paket-Installation die gewohnte Hilfe für R-Funktionen. Roxygen2 bietet folgende Vorteile gegenüber der direkten Bearbeitung der .Rd-Dateien:

  • Code und Dokumentation werden verknüpft. Bei Änderungen am Code werden wir erinnert, auch die Dokumentation zu aktualisieren.
  • Roxygen2 „denkt mit“ und erkennt Objekte – so müssen wir nicht alle Standardtexte per Hand schreiben
  • Roxygen2 abstrahiert von Detail-Unterschieden in der Dokumentation unterschiedlicher Objekttypen. Wir als Anwender müssen so weniger Einzelheiten lernen.
  • Roxygen2 kann auch den NAMESPACE verwalten: die Datei, in der z. B. eingetragen wird, welche Funktionen unseres Pakets für Anwender von außen sichtbar werden („exportiert“).

Wie sehen roxygen-Kommentare aus?

Roxygen-Kommentare beginnen, wie die üblichen Kommentare in R-Skripten, mit dem Doppelkreuz #, allerdings zusätzlich gefolgt von einem einfachen Anführungszeichen. Hier einige der wichtigsten roxygen tags – weitere siehe hier oder im Buch R Packages von Hadley Wickham und Jenny Bryan.

Einige der wichtigsten roxygen2 Tags (@param, @return, @examples, @export)
Einige der wichtigsten roxygen2 Tags.

Die roxygen2 Tags werden direkt in das Skript mit der entsprechenden R-Funktion eingefügt, und zwar oberhalb des R-Codes. Das Skript kann dann im Falle unserer Beispielfunktion von oben so aussehen:

Skript mit Beispielfunktion zufallsalbum() sowie den roxygen-Kommentaren, aus denen die Hilfe erstellt wird
Skript mit Beispielfunktion zufallsalbum() sowie den roxygen-Kommentaren, aus denen die Hilfe erstellt wird

Man kann die Hilfe Schritt für Schritt manuell eintragen – oder es sich leichter machen und in RStudio unter Code den Punkt Insert Roxygen Skeleton (Strg + Alt + Shift + R) ausführen. Dann erhält man ein Grundgerüst mit roxygen-Tags, das man nur noch inhaltlich auffüllen muss.

Dokumentation erstellen: Workflow

Wie wird nun aus diesem Skript eine dokumentierte Funktion, deren Hilfe wir wie gewohnt in der Konsole mit ?funktion, hier ?zufallsalbum, aufrufen können?

Die Dokumentation wird erstellt, wenn wir das Paket installieren: Unter Build – Install and Restart. Bei größeren Paketen kann das eine ganze Weile dauern. Es gibt eine Abkürzung: Mit Build – More – Document bzw. mit Strg + Shift + D wird die Hilfe ebenfalls erstellt, ohne dass gleich das ganze Paket installiert wird. In Kombination mit Strg + Shift + L oder Build – More – Load All können wir so schnell in kleinen Schritten die Funktion erweitern, die Hilfe ergänzen und gleich testen, wie sie aussieht. (Hinweis: Die Funktion sollte nur im Paket liegen, nicht im Environment / der Arbeitsumgebung!)

Ein kleiner Haken besteht darin, dass zumindest bei mir in der development version, der schnellen Variante über Strg + Shift + D, die Umlaute nicht korrekt dargestellt werden. Nach vollständiger Installation des Pakets werden sie jedoch richtig angezeigt.

Die R-Hilfe zu unserer Beispielfunktion zufallsalbum, aufgerufen in der Konsole mit ?zufallsalbum

Dokumentation ergänzen: Weitere Möglichkeiten

Die Dokumentation muss nicht bei der Erläuterung einzelner Funktionen stehen bleiben. Weitere Möglichkeiten:

  • Datensätze ins Paket integrieren und dokumentieren
    Beispiel: siehe ?mtcars
  • Vignetten erstellen: ausführliche, allgemeiner gehaltene Hilfe-Seite, die ins Paket einführt (d. h. man muss nicht schon den Namen einer bestimmten Funktion kennen, um zu ihrer Hilfe zu gelangen).
    Beispiel: siehe help(package = „ggplot2“) – es erscheint im Hilfefenster eine Übersicht, die unterhalb von DESCRIPTION zu den Vignetten verlinkt.

Viel Erfolg mit ihren R-Paketen! Wenn Sie für Ihre Projekte / Ihre Firma / Abteilung ein Paket erstellen möchten und dazu Unterstützung benötigen, stehe ich für einen Workshop gern zur Verfügung.

5 Gedanken zu „Hilfe erstellen für Funktionen in eigenen R-Paketen (roxygen2)“

  1. Vielen Dank für die schnelle Antwort, ich denke ich komme der Lösung ein Stück näher.

    Es ist so, dass ich an einem Projekt arbeite, welches ich über GIT importiert habe. In diesem Projekt Ordner befindet sich keine DESCRIPTION Datei. Aus diesem Grund habe ich den Befehl package.skeleton() verwendet, mit der ein Ordner IN meinem Projekt angelegt wird, der diese Datei und auch den man-Ordner sowie die NAMESPACE Datei enthält. Also genau die Struktur wie ein neu angelegtes Package.

    Wenn ich das richtig verstehe, kann ich mit dem von Ihnen genannten Befehl usethis::create_package() aber nur ein neues Package anlegen, welches nichts mit meinem bereits bestehenden Projekt zu tun hat. Ich habe das ganze mal mit so einem neu angelegten Oackage ausprobiert und hier funktioniert es einwandfrei!

    Gibt es nun eine Möglichkeit, das Package in meinem bereits bestehendes Projekt zu erstellen?

    1. Zumindest über die Menüführung von RStudio geht das anscheinend nicht direkt. Projekte können aber verschoben (an andere Orte übertragen) werden. Ich würde ein neues RStudio-Projekt als R-Paket anlegen (genau mit dem Paketnamen, den Sie brauchen) und dann die .Rproj-Datei (sowie weitere Dateien, falls nötig, wie NAMESPACE und DESCRIPTION) in ihren bisherigen Ordner übertragen.

      Alternative (klingt mehr nach quick & dirty): Müssen Sie genau die bestehende Ordnerstruktur behalten? Kann man da nicht tricksen, z. B. den bisherigen Ordner umbenennen (etwa _alt_xxx), dann als RStudio-Paket / Projekt mit dem bisherigen Namen neu anlegen, und alle bisher verwendeten Dateien reinkopieren?

  2. Hallo Herr Riepl,

    ich versuche grade für meine Masterarbeit eine Dokumentation zu erstellen, habe aber das Problem, dass die .rd files nicht erstellt werden. Ich beschreibe mal mein Vorgehen (das was ich nicht beschriebe habe ich genau so wie in Ihrem Video gemacht):

    1. Ich habe zunächst ein Package mit dem Befehl package.skeleton() erstellt und die NAMESPACE Datei sowie den man Ordner gelöscht.

    2. Dann habe ich mit setwd(…) den Path zu dem erstellten Package festgelegt. festgelegt. Wenn ich jetzt Install and Restart klicke wird das neue Package ohne Probleme installiert, ist aber leer.

    3. Die Funktion die ich dokumentieren möchte sieht wie folgt aus:

    #‘ generate Demand
    #‘
    #‘ Generates a random series of numbers, from which the sum is normalized to TQ and returned
    #‘ @param NUMB_C Length of the series of numbers
    #‘ @param TQ Sum of the series of numbers
    #‘ @param Q_VAR ??
    #‘ @return Vektor which contains the randomly generated values
    #‘ @example .gen_Demand(1,100,-1)
    #‘ @export

    .gen_Demand <- function(NUMB_C,TQ,Q_VAR){…}

    4. Wenn ich jetzt auf Dokument (bzw. strg shift d) klicke passiert nur folgendes:

    Updating anRpackage documentation
    Loading anRpackage
    Documentation completed

    Ich bekomme also keine Fehlermeldung, die .rd file wird aber nicht erstellt. Der man Ordner bleibt auch leer.

    Ich hoffe Sie können mir weiterhelfen. Vielen Dank für Ihre Mühen!

    Mit freundlichen Grüßen

    Lasse

    1. Hallo Herr Kehrhahn,

      ohne genau ihren Rechner zu sehen, kann ich es nicht sicher sagen. Folgendes erscheint mir suspekt:

      package.skeleton(). Könnte aus Rcpp oder utils stammen. Ich empfehle usethis::create_package() oder die Menüführung von RStudio.

      setwd() ist mir SEHR suspekt. Ich empfehle, diesen Befehl zu vermeiden. Siehe hier: https://www.tidyverse.org/blog/2017/12/workflow-vs-script/
      Ich würde das Paket als RStudio-Projekt erstellen, dann ist setwd() nicht erforderlich. Sie können dann mit relativen Pfaden arbeiten.

      In den Projekt-Optionen sollte unter „Build Tools“ eingestellt sein, dass die Dokumentation mit Roxygen erstellt wird (Häkchen setzen). Unter „Configure“ mindestens die „Rd files“ aktivieren (Häkchen setzen).

      Außerdem ist mir der Funktionsname .gen_Demand suspekt. Ich würde Punkte in Funktionsnamen vermeiden, sowohl am Anfang als auch später. Grund: Methoden in R werden über Punkte gekennzeichnet. Beispiel: Die generische summary-Funktion kennt je nach Objekttyp unterschiedliche Methoden, z. B. summary.lm oder summary.aov oder summary.POSIXct. Siehe

      ?summary.

      RStudio blendet dann ein Kontextmenü mit den verfügbaren Methoden ein. Alternative: methods(„summary“).

      Manchmal hilft es auch einfach, nicht nur die Dokumentation zu erstellen, sondern auch die Funktion(en) neu zu laden: Load All oder Strg+Shift+L.

      Ich hoffe es war ein hilfreicher Tipp dabei …

      Viel Erfolg

Freue mich über Kommentare!