7 Tutorial 7: Funktionen & Bedingungen in R

In Tutorial 7 lernen Sie:

  • wie Sie Funktionen anhand von Bedingungen ausführen: if-else-Bedingungen
  • wie Sie Funktionen iterativ ausführen: Loops

Wofür brauchen Sie das?

In vielen Fällen wollen wir eine Funktion nur ausführen, wenn eine bestimmte Bedingung erfüllt ist. Dafür brauchen wir sogenannte if-else-Bedingungen. In anderen Fällen wollen wir eine Funktion iterativ, d.h. mehrfach, für verschiedene Objekte ausführen, Dafür brauchen wir sogenannte loops.

Wir arbeiten in diesem Tutorial mit einem neuen fiktiven Datensatz: Daten_Tutorial 7.csv. Laden Sie diesen bitte aus OLAT herunter (via: Materialien / Datensätze für R).

Bei dem Datensatz handelt es sich um eine fiktive Umfrage unter 1000 Bürger:innen (N = 1000), für die vier Variablen erfasst wurden:

  • Land: das Land, in dem Teilnehmer:innen wohnen
  • Geschlecht: das Geschlecht der Teilnehmer:innen
  • Vertrauen_Politik: das Vertrauen der Teilnehmer:innen in die Politik (auf einer Skala von 1 = gar nicht zufrieden bis 4 = sehr zufrieden)
  • Vertrauen_Medien: das Vertrauen der Teilnehmer:innen in die Medien (auf einer Skala von 1 = gar nicht zufrieden bis 4 = sehr zufrieden)

Lesen wir den Datensatz zunächst ein:

So sieht der Datensatz aus:

## 'data.frame':    1000 obs. of  4 variables:
##  $ Land             : Factor w/ 4 levels "Deutschland",..: 1 4 2 3 1 4 2 3 1 4 ...
##  $ Geschlecht       : Factor w/ 2 levels "männlich","weiblich": 2 1 NA 1 2 1 1 2 1 1 ...
##  $ Vertrauen_Politik: int  3 2 1 2 3 1 2 2 4 4 ...
##  $ Vertrauen_Medien : int  1 1 3 2 1 2 2 4 4 4 ...

Bild: Datensatz für Tutorial 7

7.1 if-else-Bedingungen

If-else-Bedingungen sind Bedingungen, die eine Funktion ausführen, falls eine Bedingung zutrifft. Dabei können wir R sowohl anweisen, eine Funktion nur auszuführen, falls eine Bedingung zutrifft - if - als auch, welche Funktion andernfalls ausgeführt werden soll, falls die if-Bedingung nicht zutrifft - else.

Wir beginnen mit der simpleren Variante: Wir wollen eine Funktion nur ausführen, wenn eine Bedingung zutrifft: if-Bedingung.

7.1.1 if-Bedingungen

Stellen Sie sich vor, Sie haben die Umfrage data geladen. Bevor Sie mit der Analyse des Datensatzes anfangen, wollen Sie sicherstellen, dass alle Variablen als character, d.h. Text, und nicht als Faktoren abgespeichert sind, weil Sie Ihre Variablen nur im character-Format benötigen. Mein Rechner hat alle Variablen, die Text enthalten - hier Land und Geschlecht, als Faktoren eingelesen - das will ich aber ändern.

Mein Ziel: Ich will einen neuen Datensatz data_edited erstellen, in dem alle Variablen, die zuvor im Faktor-Format abgespeichert wurden, nun im Character-Format abgespeichert werden.

Hinweis: Wenn Ihr Rechner die Variablen Land und Geschlecht nicht als Faktoren eingelesen hat (das hängt von den Einstellungen Ihres Rechners ab), verwandeln Sie diese im Dataframe data via as.factor() in Faktor-Variablen.

Ich erstelle zunächst den neuen Datensatz data_edited:

## 'data.frame':    1000 obs. of  4 variables:
##  $ Land             : Factor w/ 4 levels "Deutschland",..: 1 4 2 3 1 4 2 3 1 4 ...
##  $ Geschlecht       : Factor w/ 2 levels "männlich","weiblich": 2 1 NA 1 2 1 1 2 1 1 ...
##  $ Vertrauen_Politik: int  3 2 1 2 3 1 2 2 4 4 ...
##  $ Vertrauen_Medien : int  1 1 3 2 1 2 2 4 4 4 ...

Wie kann ich nun alle Variablen, die im Faktor-Format eingelesen wurden, umwandeln?

Ein aufwendiger Weg wäre jetzt, alle Variablen einzeln vom Faktor zum Character-Format umzuwandeln. Dafür würden Sie mehrere Befehl-Zeilen benutzen und manuell schauen, ob die Variablen als Faktoren eingelesen wurden:

  1. Sie würden erst testen, welche Variablen als Faktoren (und nicht als numeric oder character) abgespeichert wurden.
  2. Sie würden dann nur die Faktor-Variablen abändern (denn z.B. sollen numeric-Variablen nicht als zu Text umgewandelt werden).
## [1] TRUE
## [1] TRUE
## [1] FALSE
## [1] FALSE

Das Problem ist, dass Sie für jede Variable nachschauen müssen, ob sie im Faktor-Format eingelesen wurde - und dann manuell definieren müssen, ob die Variable umgewandelt werden soll.

Lösung: Ein effizienterer Weg ist die if-Bedingung: Sie weisen R an, Variablen im Datensatz zum Character-Format umzuwandeln, FALLS (if) sie im -Faktor-Format vorliegen.

Eine if-Bedingung besteht aus drei Elementen

Was sehen Sie hier?

  • Die erste Zeile beschreibt die Bedingung, die zutreffen muss, damit die nachfolgende Funktion ausgeführt wird: if (Bedingung). Wichtig: If-Bedingungen evaluieren nur, ob es etwas zutrifft oder nicht, d.h., TRUE oder FALSE ist. Die geschweifte Klammer nach dieser Bedingung eröffnet die Funktion, die ausgeführt werden soll.
  • Die zweite Zeile beschreibt die auszuführende Funktion.
  • Die dritte Zeile enthält die geschweifte Klammer, welche die auszuführende Funktion abschliesst.

Um eine Variable nur umzuwandeln, falls Sie als Faktor abgespeichert ist, könnten wir jetzt eine if-Bedingung nutzen. Wir nehmen zunächst wieder unseren ursprünglichen Datensatz.

Dann wenden wir die if-Bedingung als Beispiel auf eine Variable an, die im Faktor-Format eingelesen wurde, hier Land, und auf eine Variable, die nicht im Faktor-Format eingelesen wurde, hier Vertrauen_Politik.

## 'data.frame':    1000 obs. of  4 variables:
##  $ Land             : chr  "Deutschland" "Schweiz" "Frankreich" "Italien" ...
##  $ Geschlecht       : Factor w/ 2 levels "männlich","weiblich": 2 1 NA 1 2 1 1 2 1 1 ...
##  $ Vertrauen_Politik: int  3 2 1 2 3 1 2 2 4 4 ...
##  $ Vertrauen_Medien : int  1 1 3 2 1 2 2 4 4 4 ...
## 'data.frame':    1000 obs. of  4 variables:
##  $ Land             : chr  "Deutschland" "Schweiz" "Frankreich" "Italien" ...
##  $ Geschlecht       : Factor w/ 2 levels "männlich","weiblich": 2 1 NA 1 2 1 1 2 1 1 ...
##  $ Vertrauen_Politik: int  3 2 1 2 3 1 2 2 4 4 ...
##  $ Vertrauen_Medien : int  1 1 3 2 1 2 2 4 4 4 ...

Sie sehen also, dass nur die Variable Land zum Character-Format umgewandelt wird - die Variable Vertrauen_Politik dagegen nicht.

Wie funktionieren diese if-Bedingungen?

  • Die erste Zeile beschreibt die Bedingung, die zutreffen muss: Die der geschweiften Klammer nachfolgenden Funktion soll nur durchgeführt werden, falls die Variable ein Faktor ist, d.h., die Bedingung is.factor für diese Variable den Wert TRUE annimmt.
  • Die zweite Zeile beschreibt die auszuführende Funktion, nämlich die Umwandlung von einem Faktor zu einem Character.
  • Die dritte Zeile enthält die geschweifte Klammer, welche die auszuführende Funktion abschliesst.

Warum hat R also nur die Variablen Land zu einem Character umgewandelt und die Variable Vertrauen_Politik im ursprünglichen Format beibehalten?

Ganz einfach: Weil nur für die Variable Land die Bedingung is.factor den Wert TRUE annimmt - und nur deswegen die nachfolgende Funktion ausgeführt wird.

7.1.2 if-else-Bedingungen

Es könnte sein, dass wir mehrere Befehle auf einmal durchführen wollen - nämlich einen Befehl, falls eine Bedingung zutrifft, if, und einen anderen Befehl, falls eine Bedingung nicht zutrifft, else.

Ziel: Wir wollen die Variable Vertrauen_Medien so transformieren, dass die Zahlenwerte 1, 2, 3 und 4 mit “gar kein Vertrauen, wenig Vertrauen, etwas Vertrauen, sehr viel Vertrauen” ersetzt werden - aber nur, falls die Variable Vertrauen_Medien keinen fehlenden Wert enthält. Ist das der Fall, sollen alle Werte auf NA gesetzt werden.

Eine Version, die Sie schon kennen, wäre die folgende: Sie können die Variable einfach filtern, d.h. nur bestimmte Fälle selektieren, und für diese den Wert der Variable ändern:

## [1] 0
## 'data.frame':    1000 obs. of  4 variables:
##  $ Land             : Factor w/ 4 levels "Deutschland",..: 1 4 2 3 1 4 2 3 1 4 ...
##  $ Geschlecht       : Factor w/ 2 levels "männlich","weiblich": 2 1 NA 1 2 1 1 2 1 1 ...
##  $ Vertrauen_Politik: int  3 2 1 2 3 1 2 2 4 4 ...
##  $ Vertrauen_Medien : chr  "gar kein Vertrauen" "gar kein Vertrauen" "etwas Vertrauen" "wenig Vertrauen" ...

Eine andere, effizientere Version wäre, eine if-else-Bedingung zu nutzen.

Diese hat den Vorteil, dass Sie nicht manuell testen müssen, ob eine Bedingung zutrifft und welche Funktion daher durchgeführt werden sollen - stattdessen geben Sie beide möglichen Funktionen an und weisen R an, wann welche Funktion durchgeführt werden soll.

Ziel: Sie wollen R anweisen, im Datensatz die Variable Vertrauen_Medien zu den oben genannten Textbausteinen transfomieren, FALLS (if) sie niemals den NA annimmt, d.h. fehlt.

Andernfalls (else) sollen alle Werte der Variablen zu NA gesetzt werden.

Eine if-else-Bedingung besteht aus fünf Elementen:

Was sehen Sie hier?

  • Die erste Zeile beschreibt die Bedingung, die zutreffen muss, damit die nachfolgende Funktion ausgeführt wird: if (Bedingung). Die geschweifte Klammer nach dieser Bedingung eröffnet die Funktion, die ausgeführt werden soll.
  • Die zweite Zeile beschreibt die auszuführende Funktion, falls eine Bedingung zutrifft.
  • Die dritte Zeile enthält die geschweifte Klammer, welche die auszuführende Funktion abschliesst und weist darauf hin, welche Funktion ausgeführt werden soll, falls die if-Bedingung nicht zutrifft: else.
  • Die vierte bis fünfte Zeile definiert, welche Funktion ausgeführt werden soll, wenn die else-Bedingung durchgeführt werden soll.

Für unsere Transformation sähe dies folgendermassen aus:

## 'data.frame':    1000 obs. of  4 variables:
##  $ Land             : Factor w/ 4 levels "Deutschland",..: 1 4 2 3 1 4 2 3 1 4 ...
##  $ Geschlecht       : Factor w/ 2 levels "männlich","weiblich": 2 1 NA 1 2 1 1 2 1 1 ...
##  $ Vertrauen_Politik: int  3 2 1 2 3 1 2 2 4 4 ...
##  $ Vertrauen_Medien : chr  "gar kein Vertrauen" "gar kein Vertrauen" "etwas Vertrauen" "wenig Vertrauen" ...

Was sehen Sie hier?

Der Befehlt weist R an, nur dann die Transformation der Variable Vertrauen_Medien zu “gar kein Vertrauen”, “wenig Vertrauen”, “etwas Vertrauen” und “sehr viel Vertrauen” nur durchzuführen, wenn die Variable gar keine fehlenden Werte enthält. Ansonsten wird die Variable Vertrauen_Medien komplett zu fehlenden Werten umgewandelt.

7.2 Loops

In R wollen wir oft den gleichen Befehl für verschiedene Objekte durchführen. Erinnern Sie sich daran, wie wir mit einer if-Bedingung geprüft haben, welche Variablen Faktoren sind und diese in den Datentyp character umgewandelt haben?

Wenn wir diesen Befeh für alle vier Variablen durchführen wollen, müssten wir folgende lange Kette an Befehlen durchführen:

## 'data.frame':    1000 obs. of  4 variables:
##  $ Land             : chr  "Deutschland" "Schweiz" "Frankreich" "Italien" ...
##  $ Geschlecht       : chr  "weiblich" "männlich" NA "männlich" ...
##  $ Vertrauen_Politik: int  3 2 1 2 3 1 2 2 4 4 ...
##  $ Vertrauen_Medien : int  1 1 3 2 1 2 2 4 4 4 ...

Puh, ganz schön kompliziert - und vor allem lang. Wir weisen R hier an, vier unterschiedliche Objekte (die Variablen Land, Geschlecht, Vertrauen_Politik und Vertrauen_Medien) mit ein- und demselben Befehl zu transformieren - aber in unterschiedlichen Zeilen Code.

Das geht auch leichter.

Ziel: Ich will einen neuen Datensatz data_edited erstellen, in dem alle Variablen, die zuvor im Faktor-Format abgespeichert wurden, nun im Character-Format abgespeichert werden. Dabei wollen wir diesen Befehl nicht für alle Variablen einzeln ausführen, sondern den gleichen Befehl über die Variablen hinweg ausführen.

Die Lösung: Wir arbeiten mit einem for-Loop.

For-Loops führen den gleichen Befehl über mehrere Objekte hinweg aus. Sie sind folgendermassen aufgebaut:

Was sehen Sie hier?

  • Die erste Zeile beschreibt, für welches Objekt i in einer Reihe von Objekten Objekte ein Befehl durchgeführt wird. Der Loop nimmt also jedes Objekte i aus dem Vektor Objekte und führt die nachfolgende definierte Funktion für jedes Objekt i einzeln aus.
  • Die zweite Zeile beschreibt die auszuführende Funktion.
  • Die dritte Zeile enthält die geschweifte Klammer, welche die auszuführende Funktion abschliesst. Nachdem die Funktion für das erste Objekt durchgeführt wurde, beginnt der Loop mit dem zweiten Objekt i der Reihe von Objekten Objekte, dann dem dritten Objekt i und so weiter.

Wir weisen R also an, für jedes Element i in der Reihe an Objekten Objekte eine Funktion auszuführen.

Ein ganz einfaches Beispiel zum Verständnis: Wir wollen R bitten, uns das Land der Teilnehmer:innen auszugeben - aber nur für jede 100ste Person im Datensatz. Der entsprechende Loop sähe folgendermassen aus:

## [1] "Italien"
## [1] "Italien"
## [1] "Italien"
## [1] "Italien"
## [1] "Italien"
## [1] "Italien"
## [1] "Italien"
## [1] "Italien"
## [1] "Italien"
## [1] "Italien"

Wenden wir diese Transformation nun auf unser Beispiel an:

Wir wollten einen neuen Datensatz data_edited erstellen, in dem alle Variablen, die zuvor im Faktor-Format abgespeichert wurden, nun im Character-Format abgespeichert werden. Dabei wollen wir diesen Befehl nicht für alle Variablen einzeln ausführen, sondern den gleichen Befehl über die Variablen hinweg ausführen.

Für unser Ziel sähe das so aus:

Gehen wir den Code einmal Zeile für Zeile durch:

  • Die erste Zeile lautet: for (i in variablen). Wir weisen R hier also an für jedes Objekt i im Vektor Variablen den nachfolgenden Befehl auszuführen. Im ersten Durchlauf des Loops wäre dieses Objekt i also das erste Element des vektors variablen: variablen[1]. Der Loop würde also für die erste Variable des Datensatzes durchgeführt werden. Das Objekt i ist für den ersten Durchgang des Loops also einfach die erste Variable “Land”. Sobald der Loop einmal durchgeführt wurde, beginnt R von vorne - mit dem zweiten Elemente des Vektors Objekte.

  • Die zweite Zeile lautet: if (is.factor(data[,i])==TRUE) {. Wir weisen R hier also an, die Spalte i im Datensatz data_edited zu nehmen und zu prüfen, ob es sich bei dieser Spalte um einen Faktor handelt. Im ersten Durchlauf des Loops wird hier also die Spalte i = “Land” genommen und für diese wird geprüft, ob es sich um einen Faktor handelt.

  • Die dritte Zeile lautet: data_edited[,i] <- as.character(data_edited[,i]). Wir weisen R hier also an, die Spalte i im Datensatz data_edited in einen character zu verwandeln falls die if-Bedingung zutrifft.

  • Die vierte Zeile lautet: }. Hier wird nur die if-Bedingung “geschlossen”.

  • Die fünfte Zeile lautet: }. Hier wird nur der Loop “geschlossen”.

Statt mehrerer Zeilen Code, bei dem wir den gleichen Befehl mehrere Male durchführen, könnten wir also denselben Befehl für verschiedene Objekte durch wenige Zeilen Code durchführen.

7.3 Take Aways

  • if-else-Bedingungen: Mit if-else-Bedingungen können Sie Funktionen anhand von Bedingungen ausführen. Befehle: if{}, if{} else{}
  • Loops: Mit loops können Sie Funktionen iterativ, d.h. wiederholt für eine Reihe unterschiedlicher Objekte, ausführen. Befehle: for i in Vektor {}

7.5 Übungsaufgabe

Sie haben das Tutorial erfolgreich durchgearbeitet? Dann finden Sie hier einige Aufgaben zum Selbsttest, mit denen Sie Ihr Wissen testen können. Wir arbeiten wieder mit dem fiktiven Datensatz: Daten_Tutorial 7.csv (via OLAT: Materialien / Datensätze für R).

Bei dem Datensatz handelt es sich um eine fiktive Umfrage unter 1000 Bürger:innen (N = 1000), für die vier Variablen erfasst wurden:

Datensatz Tutorial 7:

  • Land: das Land, in dem diese wohnt
  • Geschlecht: das Geschlecht der jeweiligen Person
  • Vertrauen_Politik: ihr Vertrauen in die Politik (auf einer Skala von 1 = gar nicht zufrieden bis 4 = sehr zufrieden)
  • Vertrauen_Medien: ihr Vertrauen in die Medien (auf einer Skala von 1 = gar nicht zufrieden bis 4 = sehr zufrieden)

7.5.1 Aufgabe 7.1

Lesen Sie den Datensatz ein. Schreiben Sie eine if_else-Bedingung, die die Variable Land folgendermassen verändert:

Alle Teilnehmer:innen, die aus “Deutschland” oder der “Schweiz” kommen, sollen für die Variable Land den Wert “deutschsprachig” aufweisen. Alle Teilnehmer:innen, die aus “Frankreich” oder “Italien” kommen, sollen für die Variable Land den Wert “nicht deutschsprachig” aufweisen.

Wichtig: Diese Transformation soll nur durchgeführt werden, falls nicht mehr als 100 Befragte aus Deutschland an der Umfrage teilgenommen werden. Ansonsten sollen die Werte der Variable Land für alle Teilnehmer:innen, die aus “Deutschland” kommen den Wert “deutschsprachig” und für alle anderen Teilnehmer:innen den Wert “nicht deutschsprachig” annehmen.

7.5.2 Aufgabe 7.2

Schreiben Sie einen for-Loop, der für alle Fälle der Variablen Vertrauen_Politik die ursprünglichen Werte um 0.5 erhöht, d.h., für jeden Fall .5 zum ursprünglichen Variablenwert hinzufügt.

Die Lösungen finden Sie bei Lösungen zu Tutorial 7.

Wir machen weiter: mit Tutorial 8: Einfuehrung in die automatisierte Inhaltsanalyse.