GNU R: Eigene Funktionen programmieren
Einführung
[Bearbeiten]In R erstellt man in der Regel eigene Funktionen, wenn man eine Sequenz aus mehreren Befehlen wiederholt ausführen muss (z.B. an unterschiedlichen Stellen im Programmcode).
Beispiel - wiederholte Nutzung von Befehlsequenzen
[Bearbeiten]Das folgende Beispiel zeigt die wiederholte Nutzung von Befehlsequenzen, die einmal auf die Variablen und weiter im R-Code noch einmal auf die Variablen angewendet wird.
a <- befehl1(a)
b <- befehl1(b)
c <- befehl2(a,b)
...
x <- befehl1(x)
y <- befehl1(y)
z <- befehl2(x,y)
Nun schreibt man dafür eine eigene Funktion in R, die man für die weitere mehrfache Nutzung in den eigen Code integriert.
meinefunktion <- function(p1,p2) {
## Parameter der Funktion sind p1 und p2
p1 <- befehl1(p1)
p2 <- befehl1(p2)
r <- befehl2(p1,p2)
## Rueckgabewert der Funktion: r
r
}
Wenn man die Funktion definiert hat, vereinfacht sich der Ausgangscode wie folgt.
c <- meinefunktion(a,b)
...
z <- meinefunktion(x,y)
Auswahl der Programmiersprache für Funktionen
[Bearbeiten]In dem obigen Beispiel wurde die Funktion in R programmiert. Das ist einfachste und häufigste Methode, Funktionen in der R-Sprache zu schreiben. Dies wird in den folgenden Abschnitten beschrieben. Weiterhin besteht auch die Möglichkeit, neue Funktionen in anderen Programmiersprachen wie z.B. C++ zu programmieren, die erfolgt in der Regel dann, wenn man die Laufzeit des Algorithmus z.B. bei großen Datenmengen optimieren muss.
Funktionsdefinitionen im Vergleich anderen Sprachen
[Bearbeiten]Funktionen in R unterscheiden sich von Funktionen in anderen Programmiersprachen wie z.B. Java. Auffällige Unterschiede sind, dass Funktionen in ihrer Signatur keine Rückgabewerte beschreiben. Datenkapselung und Zugriffsarten wie sie aus Objektorientierten Programmiersprachen bekannt sind, gibt es nicht. Man kann Funktionen nicht als private oder public definieren. Auch kann man Variablen oder Parameter von Funktionen nicht als final deklarieren. Auch ein Fehlermanagement mit z.B. Exceptions ist in R nicht vorhanden.
Funktionen in R
[Bearbeiten]Eine Funktion besteht aus
- Namen für die Funktion (z.B.
meinefunktion
) - Argumente bzw. Parameter (z.B.
p1
undp2
), - Befehlsblock, der die Arbeitsschritte in der Funktion definiert
p1 <- befehl1(p1)
p2 <- befehl1(p2)
r <- befehl2(p1,p2)
- ggf. einem Rückgabewert, der im obigen Beispiel den Variableninhalt von
r
in der letzten Zeile festlegt.
Auruf der Funktion
[Bearbeiten]Ist eine Funktion definiert, kann diese mit dem Funktionsnamen aufgerufen werden. Im obigen Beispiel ist das an zwei Stellen mit jeweils unterschiedlichen Parametern erfolgt.
c <- meinefunktion(a,b)
...
z <- meinefunktion(x,y)
Beim Aufruf erfolgt jeweils eine Ersetzung der Parameter p1
und p2
durch die jeweiligen konkreten Parameter bei dem Funktionsaufruf. Nach dem ersten Aufruf meinefunktion(a,b)
ist dann p1=a
und p2=b
und im zweiten
Aufrufmeinefunktion(x,y)
entsprechendp1=x
undp2=y
. Die kann man auch in dem Funktionsaufruf durch folgende Schreibweise deutlich machen.
c <- meinefunktion(p1=a,p2=b)
...
z <- meinefunktion(p1=x,p2=y)
Dieser Aufruf führt zu dem gleichen Ergebnis. Die zweite Form des Aufrufs macht immer dann Sinn, wenn nicht alle Parameter der Funktion benötigt werden. Das verkürzt den Aufruf der Funktion auf die wesentlichen Parameter und verbessert die Lesbarkeit des Codes.
Parameter und Standardwerte in unterschiedlichen Formen
[Bearbeiten]Die folgende Funktion testpar()
zeigt Parameteraufrufen und das Setzen von Standwerten in der Funktionsdefinition. Als Standardwert für x ist 1000 und für y ist 100 gesetzt. Das
## Funktionsdefinition
testpar <- function (x=1000,y=100) {
x-y
}
## Aufruf der Funktion mit unterschiedlichen Parametern
testpar() ## Ergebnis 900
testpar(200,10) ## Ergebnis 190
testpar(200) ## Ergebnis 1800
testpar(y=3) ## Ergebnis 1997
testpar(x=3) ## Ergebnis -97
testpar(y=30,x=200) ## Ergebnis 170
Funktion in Datei
[Bearbeiten]Wenn man Funktionen z.B. in mehrere Projekten verwenden möchte, macht es Sinn diese in eine externe Datei auszulagern. Wenn man diese Funktion verbessert oder erweitert, dann stehen diese Verbesserung auch in allen Projekten zur Verfügung und müssen nicht individuelle in alle Projektdateien kopiert werden. Dies insbesondere bei Fehler (Bugs) im R-Code effizient, da die Fehlerbeseitigung damit in allen Projekten erfolgt. Projekte können dabei unterschiedliche
- statische Projekte als R-Dateien sein, die die Funktion gemeinsam nutzen,
- dynamische Dokumentengenerieung mit KnitR,
- webbasierte Anwendung mit dynamischer Auswertung von Daten mit Shiny.
Sammlungen von Funktionen
[Bearbeiten]R-Funktionen werden in der Regel in eigenen Dateien gespeichert. Diese R-Skriptdateien kann man mittels source()
laden. Wenn die oben definierte Funktion z.B. in der Datei sammlung4funktionen.R
gespeichert wurde, kann man nach dem Befehl
source("sammlung4funktionen.R")
alle Funktionen in sammlung4funktionen.R
definierten Funktionen nutzen, die in der Datei definiert wurden. In der Datei können zusätzlich auch Textvariable oder andere numerische Konstanten definiert sein, die man in vielen Projekten benötigt. Wenn man diese Datei geladen hat, kann man die darin enthaltenen Funktionen aufrufen. Die R-Skriptdateien haben im Vergleich zu anderen Programmiersprachen keine weitere Bedeutung. Oft muss man Dinge in R wiederholen, dann kann man diese Wiederkehrenden Prozessschritte in R-Scriptedateien auslagern. Dies spart Tipparbeit und macht die Analysen und Resultate nachvollziehbar.
Beispiel - Erstellung einer Funktion
[Bearbeiten]Zum Erstellen einer eigenen Funktion steht der Befehl function()
zur Verfügung.
In dem folgende Beispiel wird eine einfache Funktion definiert, die die Summe von zwei Zahlen berechnet. Daher wird die Funktion mit zwei Parametern aufgerufen. Allerdings hängt die konkrete Anzahl der Parameter von den Aufgaben der Funktion ab und ist allgemein wie folgt aufzurufen:
function(Parameter1, Parameter2, Parameter3...) {
Anweisungen;
}
In den Klammern direkt nach function
können Parameter benannt werden, welche dann beim Funktionsaufruf der Funktion zur Verfügung stehen. Innerhalb der geschweiften Klammern wird die eigentliche Funktionsweise geschrieben. Zu beachten dabei ist, dass mehrere Anweisungen innerhalb der FUNKTIONSWEISE mit einem Semikolon terminiert werden müssen.
Die neue Funktion soll man in R mit zwei Summanden aufrufen können und benötigt für den Aufruf einen Namen. Die Funktionsweise wird nach der Definition in einem neuen Objekt (z.B. myfunc
) zugeordnet.
myfunc <- function(x,y){
z <- x+y;
z
}
Der obigen Funktion "myfunc" werden im Funktionsaufruf die Parameter x und y übergeben. Innerhalb der Funktion wird die Summe aus x und y gebildet, und per return()
an die R-Konsole zurückgemeldet. Rufen wir diese Funktion beispielsweise auf mit:
myfunc(4,6)
erhalten wir als Rückmeldung:
10
Ein Vorteil von R ist die Möglichkeit, Standardwerte für die Parameter vorzugeben, welche verwendet werden, falls der Funktionsaufruf ohne diese Parameter erfolgt.
myfunc <- function(x=3,y=7){ # Neue Funktion mit Standardwerten für die Parameter x und y z <- x+y # Die Summe von x und y wird in z gespeichert return(z) # z wird zurückgemeldet }
Rufen wir die Funktion ohne Parameter auf:
myfunc()
so werden die Standardwerte genutzt, und wir erhalten das Ergebnis
10
Rufen wir die Funktion mit Parametern auf, z.B.
myfunc(12,4)
so erhalten wir das Ergebnis
16
Schleifen
[Bearbeiten]In R sind die aus anderen Programmiersprachen bekannten Schleifen wie die For-Schleife oder die While-Schleife ebenfalls vorhanden. Mit Schleifen können wir gewisse Textstellen in unserer Funktion beliebig bis unendlich oft wiederholen und uns somit Unmengen von Arbeit sparen. Schleifen können nicht nur in eigenen Skripten sondern auch normal in der Konsole verwandt werden. Dies ist aber eher untypisch.
Ein Beispiel für eine While-Schleife in einer eigenen Funktion:
Strecke <- function(x=10,y=x) { while(a=0,a<=,a++) { z=z+x # z wird zu z+x z=z+y # z wird zu z+y } return(z) } # z wird zurückgemeldet
Ein Beispiel für eine For-Schleife, bei der über eine Spalte "ERRORRATIO" einer Tabelle "tt" iteriert wird und ein neuer Wert "ANSTIEG" berechnet wird.
l = dim(tt)[1]; for(i in 2:l){ tt[i,"ANSTIEG"] = tt[i, "ERRORRATIO"] - tt[i-1, "ERRORRATIO"]; }
Literatur
[Bearbeiten]Weblinks
[Bearbeiten]
Inhaltsverzeichnis[Bearbeiten]
|