**[ [[r:de:introduction|Sammlung: Einstieg in die Statistik mit R]] ]** ====== Übungseinheit 1: Erste Schritte ====== ===== Grundlagen ===== ==== Funktionen ==== Wenn Sie R öffnen, sehen Sie nur eine Eingabeaufforderung (''>''). Sie können nun eine Funktion eingeben. Die Funktionen haben typischerweise die Form name.funktion(datenstruktur, parameter="wert", ...) wobei ''name.funktion'' für den jeweiligen Namen der Funktion und ''datenstruktur'' für den Name einer Datenstruktur steht; hinzu können einer oder mehrere Parameter kommen, in dem Sie genauer spezifizieren, wie die Funktion ausgeführt werden soll. Ein einfaches Beispiel ist die ''print''-Funktion, die nichts weiter tut, als die Datenstruktur auszugeben: print("Hello, World!") print(3.141592653589793116, digits=4) Der erste Befehl gibt den Satz "Hello, World!" aus. Der zweite Befehl gibt die genannte Zahl aus, allerdings nur die Stelle vor dem Dezimalkomma und die ersten drei Nachkommastellen, denn so ist es in dem Parameter ''digits'' definiert. > AUFGABE: Ändern Sie den Wert des Parameters ''digits'' so, dass Sie 1, 7, 23 bzw. 42 Nachkommastellen ausgegeben bekommen. ((''print(3.141592653589793116, digits=1)'', ''print(3.141592653589793116, digits=7)'', ''print(3.141592653589793116, digits=23)'', bzw, ''print(3.141592653589793116, digits=42)''.)) ==== Datentypen ==== Wir sehen in den beiden Befehlen auch schon zwei verschiedene Arten von Daten: - Text hat den Datentyp ''CHARACTER'' -- dieser Datentyp muss immer in (geraden) Anführungsstrichen stehen (typischerweise verwenden wir doppelte Anführungszeichen, aber einfache funktionieren auch); - Zahlen (verschiedene Datentypen: ''INTEGER'' für ganze Zahlen, ''NUMERIC'' für Dezimalzahlen, ''COMPLEX'' für komplexe Zahlen (keine Sorge, letzteren werden wir nicht verwenden...) -- diese Datentypen dürfen nicht in Anführungsstrichen stehen, sonst werden Sie als Text behandelt, Sie können dann z.B. keine Berechnungen durchführen. Außer Funktionen der o.g. Form können wir auch mathematische Operatoren wie //Plus// (''+''), //Minus// (''-''), //Mal// (''*'') und //Geteilt (durch)// (''/'') verwenden. Nehmen wir an, in einer Prüfungsordnung steht, dass Hausarbeiten eine Länge von 40000 Zeichen haben sollen. Wenn Sie wissen, dass die durchschnittliche Wortlänge in geschriebenen englischen Texten 4.729511018095062802 ist, können Sie ausrechnen, wieviele Wörter die Hausarbeit etwa haben muss, wenn Sie sie in englischer Sprache verfassen: 40000 / 4.729511018095062802 [1] 8457.534 > AUFGABE: Die durchschnittliche Wortlänge in deutschen Texten ist 6.1216408854526553895. Berechnen Sie, wie viele Wörter die Hausarbeit etwa haben muss, wenn Sie sie auf Deutsch schreiben. ((''40000/6.1216408854526553895'' = 6534.196.)) > AUFGABE: Wie viel länger wird ein englischer Text ungefähr, wenn Sie ihn ins Deutsche übersetzen? ((Ungefähr ein Drittel länger: ''6.1216408854526553895/4.729511018095062802'' = 1.29435.)) Mathematische Operatoren funktionieren nur mit Zahlen (Typen ''INTEGER'' und ''NUMERIC''). Wenn Sie es mit Text versuchen, erhalten Sie eine Fehlermeldung: "Vierzigtausend" / 4.729511018095062802 Fehler in "Vierzigtausend"/4.72951101809506 : nicht-numerisches Argument für binären Operator Das gilt auch, wenn der Text aus Zahlen besteht — wie oben erwähnt, behandelt R alles als Text, was in Anführungszeichen steht: "40000" / 4.729511018095062802 Fehler in "40000"/4.72951101809506 : nicht-numerisches Argument für binären Operator ==== Variablen ==== Wie eingangs gesagt, ist R (auch) eine Programmiersprache. Wie es für Programmiersprachen typisch ist, können wir unsere Daten (z.B. Text oder Zahlen) auch in sogenannten Variablen ablegen. Eine Variable können wir uns als einen Behälter mit einem Etikett (dem Variablennamen) vorstellen, in dem verschiedene Dinge liegen können; auf diese verschiedenen Dinge können wir uns immer beziehen, in dem wir den Variablennamen nennen. Variablen können beliebige Namen haben, solange diese nicht mit einer Zahl beginnen oder mit dem Namen einer Funktion identisch sind. In R legen wir Daten in einer Variable ab (bzw. weisen einer Variable unsere Daten als Wert zu), indem wir ein Pfeilsymbol aus einem "Kleiner-Als"- oder "Größer-Als"-Zeichen zusammensetzen und dieses Symbol zwischen den Variablennamen und den Wert schreiben, so, dass er auf die Variable zeigt. Die Reihenfolge von Variablenname und Wert ist in R egal, wichtig ist nur die Richtung des Pfeils. Um z.B. die o.g. Durchschnittslängen für Wörter in englischen und deutschen Texten in Variablen namens ''wl_en'' und ''wl_deu'' abzulegen, geben wir die folgenden Befehle ein: wl_en <- 4.729511018095062802 wl_deu <- 6.1216408854526553895 oder 4.729511018095062802 -> wl_en 6.1216408854526553895 -> wl_deu Um die gewünschte Länge der Hausarbeit in der o.g. fiktiven Prüfungsordnung in einer Variable mit dem Namen ''gewuenschte_laenge_hausarbeit'' abzulegen, schreiben wir Folgendes: gewuenschte_laenge_hausarbeit <- 40000 Nun können wir mit den Variablen rechnen als seien es Zahlen gewuenschte_laenge_hausarbeit / wl_en [1] 6534.196 Auch einen Text können wir einer Variable als Wert zuweisen: gewuenschte_laenge_hausarbeit <- "40.000 Zeichen" Damit können wir aber dann nicht rechnen – wenn wir den Befehl erneut ausführen, erhalten wir eine Fehlermeldung: gewuenschte_laenge_hausarbeit / wl_en Fehler in gewuenschte_laenge_hausarbeit/wl_en : nicht-numerisches Argument für binären Operator > AUFGABE: a.) In wiefern ist ''gewuenschte_laenge_hausarbeit'' ein guter und inwiefern ein schlechter Variablenname? ((Es ist ein guter Variablenname, weil er seinen Inhalt genau beschreibt. Er ist ein schlechter Variablenname, weil er sehr lang ist; es ist umständlich, ihn jedes Mal zu tippen und es ist leicht, sich zu vertippen. Also: Variablennamen sollten so lang wie nötig aber so kurz wie möglich sein. Mehr zu Naming Conventions in R finden Sie unter https://journal.r-project.org/archive/2012-2/RJournal_2012-2_Baaaath.pdf und https://www.r-bloggers.com/2014/07/consistent-naming-conventions-in-r/.)) Wie das Wort //Variable// sagt, ist der Inhalt variabel. Wenn Sie einer Variable einen neuen Wert zuweisen, wird der alte Wert überschrieben. Der selbe Befehl kann also unterschiedliche Ergebnisse liefern, je nachdem, welchen Wert die darin verwendete Variable hat. Nehmen wir noch einmal das Beispiel von ''wl_en''. Die o.g. Wortlänge ist die, die man erhält, wenn man verschiedene schriftliche Textsorten zusammennimmt; Hausarbeiten sind aber akademische Texte, deren durchschnittliche Wortlänge etwas größer ist — man liest häufig die Zahl 6,2. Wir können die Variable entsprechend neu definieren: 6.2 -> wl_en Wenn wir nun die oben durchgeführte Rechnung erneut durchführen, erhalten wir ein anderes Ergebnis: gewuenschte_laenge_hausarbeit / wl_en [1] 6451.613 Das ist natürlich richtig so, denn der Wert der Variable ''wl_en'' hat sich geändert — stellen Sie aber immer sicher, dass Sie den Inhalt Ihrer Variablen //zum Zeitpunkt der Berechnung// kennen! ===== Datenstrukturen ===== Wir haben von "Datenstrukturen" gesprochen, aber bisher waren unsere Daten einzelne Zahlen (oder Texte). Es gibt in R aber auch komplexere Strukturen. Die wichtigsten sind: - der Vektor (//vector//) - die Kreuztabelle (//table//) - die Tabelle (//data frame//) ==== Vektoren ==== Vektoren sind (anders als der Name erwarten lässt), geordnete Listen von Daten desselben Typs. Sie werden mit der Funktion ''c()'' erzeugt. Der folgende Befehl erzeugt einen solchen Vektor, der die Wortanzahl der 23 Kapitel von Jane Austens _Pride and Predjudice_ (Band 1) enthält, und weist ihn einer Variable mit dem Namen pp_v1 zu. pp_v1 <- c(855, 800, 1710, 1067, 964, 2358, 1999, 1939, 1744, 2227, 1615, 667, 1707, 1124, 1705, 3403, 1283, 5193, 1921, 1653, 2009, 1736, 1622) > AUFGABE: a) Erzeugen Sie einen Vektor mit den Einwohnendenzahlen der fünf größten deutschen Städte und nennen Sie ihn ''Einwohner''. Vektoren sind praktisch, um nicht für jeden Wert einer Reihe zusammenhängender Datenpunkte (hier: Wortlänge der Kapitel bzw. Anzahl der Einwohnenden) eine eigene Variable erzeugen zu müssen. Für die Kapitel in Band 1 von _Pride and Predjudice_ bräuchten wir 23 Variablen, z.B. wie die folgenden: pp_v1_ch1 <- 855 pp_v1_ch2 <- 800 pp_v1_ch3 <- 1710 pp_v1_ch4 <- 1067 pp_v1_ch5 <- 964 pp_v1_ch6 <- 2358 pp_v1_ch7 <- 1999 pp_v1_ch8 <- 1939 pp_v1_ch9 <- 1744 pp_v1_ch10 <- 2227 pp_v1_ch11 <- 1615 pp_v1_ch12 <- 667 pp_v1_ch13 <- 1707 pp_v1_ch14 <- 1124 pp_v1_ch15 <- 1705 pp_v1_ch16 <- 3403 pp_v1_ch17 <- 1283 pp_v1_ch18 <- 5193 pp_v1_ch19 <- 1921 pp_v1_ch20 <- 1653 pp_v1_ch21 <- 2009 pp_v1_ch22 <- 1736 pp_v1_ch23 <- 1622 Das wird schnell unübersichtlich, ein Vektor ist hier praktischer und leichter zu verwalten. Wir können auf die einzelnen Elemente eines Vektors zugreifen, indem wir den Namen des Vektors gefolgt von einer Position in eckigen Klammern verwenden. Um zum Beispiel die Wortanzahl des 5. Kapitels zu erhalten, geben wir Folgendes ein: pp_v1[5] Mit diesem Variablennamen können wir auch Berechnungen durchführen, ebenso wie wir es könnten, wenn wir den entsprechenden Wert in einer eigenen Variable (z.B. ''pp_v1_ch5'') abgelegt hätten. Wir können zum Beispiel ausrechnen, wie lange es bei einer durchschnittlichen Lesegeschwindigkeit von 150 Wörtern pro Minute dauern würde, das Kapitel zu lesen: pp_v1[5] / 150 Wenn wir bei solchen Berechnungen den Namen des Vektors selbst verwenden, erhalten wir übrigens einen neuen Vektor, der das Ergebnis der Berechnung für jedes Element des Vektors enthält: pp_v1 / 150 R erkennt also, dass hier eine Berechnung durchgeführt wird, für die eine einzelne Zahl benötigt wird. Da der Vektor mehrere Zahlen enthält, geht R automatisch davon aus, dass die Berechnung für jede dieser Zahlen durchgeführt werden soll. Es gibt aber auch eine Reihe von Funktionen, die wir speziell auf solche Vektoren anwenden können, z.B. * ''max()'': gibt das Element mit dem höchsten Wert aus * ''min()'': gibt das Element mit dem niedrigsten Wert aus * ''sum()'': zählt alle Zahlen im Vektor zusammen * ''mean()'': berechnet den Durchschnitt aller Zahlen Die Länge des längsten Kapitels in Band 1 von _Pride and Predjudice_ erhalten wir z.B. mit max(pp_v1) die Länge des kürzesten Kapitels mit min(pp_v1) und die durchschnittliche Länge mit mean(pp_v1) > AUFGABE: Ermitteln Sie die Gesamtlänge des Bandes. ((''sum(pp_v1)'')) > AUFGABE: Verwenden Sie die Variable ''wl_en'', um einen Vektor zu erzeugen, der die ungefähre Buchstabenzahl der Kapitel enthält.((''pp_v1 / wl_en'')) Falls Sie auch die Wortlängen der Kapitel im zweiten und dritten Band von Pride and Prejudice haben möchten, sind hier die Funktionen für die entsprechenden Vektoren: pp_v2 <- c(1939, 1520, 2341, 1268, 1456, 2397, 1233, 1568, 1504, 1870, 2111, 3007, 2025, 1375, 1042, 1645, 1683, 2280, 1837) pp_v3 <- c(d) Sie können diese Vektoren übrigens mit dem Befehl ''c()'' ganz einfach zu einem einzigen langen Vektor vereinigen: pp_all <- c(pp_v1, pp_v2, pp_v3) Nun können Sie z.B. ausrechnen, wie lang der Roman insgesamt ist: sum(pp_all) > AUFGABE: Berechnen Sie die durchschnittliche Kapitellänge des gesamten Romans. ((''mean(pp_all)'')) Wir können solche Funktionen auch direkt in einer Berechnung verwenden, R verwendet an der betreffenden Stelle dann das Ergebnis der Funktion. Zum Beispiel: pp_v1 - mean(pp_v1) R berechnet hier zunächst das Ergebnis der Funktion ''mean(pp_v1)'' -- die Zahl 1795.696. Da Subtraktion immer das Subtrahieren einer Zahl von einer anderen Zahl ist, erkennt R, dass es die Berechnung nun auf jedes Element des Vektors anwenden muss. Das Ergebnis ist ein Vektor, der für jedes Kapitel den Wert enthält, um den es länger oder kürzer ist als der Durchschnitt. ==== Data Frames (Tabellen) ==== Vektoren sind oft nützlich, aber sie haben ein Problem: sie enthalten nur Werte (in unserem Fall, Zahlen), aber keine Information darüber, worauf sich diese Zahlen beziehen. Wenn wir z.B. die Gesamtlänge von Romanen miteinander vergleichen wollen würden, würden wir normalerweise eine Tabelle wie die folgende anlegen: ^ Title ^ Author ^ Length ^ | Les Miserables | Victor Hugo | 568751 | | War and Peace | Leo Tolstoy | 567246 | | The Lord of the Rings | J. R. R. Tolkien | 564187 | | ... | | | Solche Tabellen können wir auch innerhalb von R verwenden. Sie heißen dort "Data Frames". Theoretisch könnten wir eine solche Tabelle erzeugen, indem wir zunächst einen Vektor für jede Spalte anlegen, und diese Vektoren dann zu einem Data Frame kombinieren. Für die o.g. Tabelle würde das so aussehen: title <- c("Les Miserables", "War and Peace", "The Lord of the Rings") author <- c("Victor Hugo", "Leo Tolstoy", "J. R. R. Tolkien") length <- c(568751, 567246, 564187) data.frame(title, author, length) Bei nur drei Zeilen ist das vorstellbar, aber was, wenn wir eine Tabelle der beliebtesten 100 Romane in dieser Form erstellen wollen? Dann ist es sinnvoller, die Tabelle in einem externen Programm zu erzeugen (z.B. in einem Tabellenkalkulationsprogramm wie Libre Office Calc, Google Sheets oder Microsoft Excel). === Einlesen extern erzeugter Tabellen === Um eine solche Tabelle in R einzulesen, gibt es verschiedene Möglichkeiten. Die beste ist die, die Tabelle zunächst als csv-Datei abzuspeichern, wobei //csv// für "comma-separated values" steht. In einer solchen Datei entspricht jede Zeile einer Zeile der Tabelle, die Spalten der Tabelle sind durch Kommas (oder manchmal auch Semikolons oder Tabulatoren) getrennt. Text sollte (wie bei R) in geraden Anführungszeichen stehen (normalerweise werden doppelte Anführungszeichen verwendet, aber einfache gehen auch). Innerhalb solcher Anführungszeichen dürfen Kommas, Tabulatoren oder Semikolons vorkommen, ohne, dass sie als Spaltengrenze interpretiert werden. Die o.g. Tabelle würde also so aussehen: "Title","Author","Length" "Les Miserables","Victor Hugo",568751 "War and Peace","Leo Tolstoy",567246 "The Lord of the Rings","J. R. R. Tolkien",564187 Unter https://userpage.fu-berlin.de/~structeng/data/wc-novels.csv finden Sie eine Liste der 100 beliebtesten Romane in diesem Format (für die Richtigkeit der Informationen kann ich nicht haften, ich habe die Tabelle aus dem Blog "Word Counter" übernommen, die Länge von Jane Austens Pride and Prejudice stimmt z.B. nicht mit der von uns oben errechneten überein, bei einigen Büchern ist es äußerst zweifelhaft, dass sie zu den 100 beliebtesten gehören, und einige sind auch keine Romane, ...). Es geht uns aber nicht um den Inhalt der Tabelle, wir wollen ja nur lernen, mit solchen Daten zu Arbeiten. Speichern Sie diese Tabelle auf Ihrem Computer an einer Stelle, an der Sie sie leicht wiederfinden, ich speichere sie bei mir z.B. auf dem Desktop. Um solche csv-Dateien in R einzulesen, verwenden Sie den Befehl ''read.table()''. Dieser benötigt einen Dateipfad zu der Datei, die Sie einlesen möchten, sowie drei weitere Informationen: - enthält die Tabelle eine Kopfzeile, in der die Spaltennamen stehen? - Welches Zeichen wird verwendet, um die Spalten voneinander zu trennen? - Welches Zeichen wird verwendet, um Text zu kennzeichnen? In unserer Tabelle sind die Antworten: - Ja, die Tabelle enthält eine Kopfzeile, - es wird das Komma verwendet, um Spalten zu trennen, und - Text wird durch doppelte Anführungszeichen gekennzeichnet. Wir können die Tabelle also wie folgt einlesen: read.table(file="DATEIPFAD/wc-novels.csv", header=TRUE, sep=",", quot="\"") -> novels ''file'' verlangt als Argument den Dateipfad und den Dateinamen (da ich die Datei auf meinen Desktop gelegt habe, wäre das bei mir z.B. /Users/anatol/Desktop/wc-novels.csv (auf einem Mac) oder /home/anatol/Desktop/wc-novels.csv (auf einem Computer mit Linux). Wenn Sie den Pfad zu Ihrer Datei nicht kennen, können Sie anstelle des Dateinamens die Funktion ''file.choose()'' einsetzen. Wenn Sie die Funktion dann ausführen, öffnet sich ein Auswahlfenster, in dem Sie die Datei von Hand auswählen können: read.table(file=file.choose(), header=TRUE, sep=",", quot="\"") -> novels Übrigens kann R eine Datei auch aus dem Internet einlesen. Nennen Sie dann statt des Dateipfades die URL, z.B.: read.table(file="https://userpage.fu-berlin.de/~structeng/data/wc-novels.csv", header=TRUE, sep=",", quot="\"") -> novels Die Funktion ''read.table()'' hat weitere Parameter: ''header'' verlangt das Argument TRUE wenn eine Kopfzeile vorhanden ist, und FALSE, wenn dies nicht der Fall ist. ''sep'' verlangt das Spaltentrennzeichen (in Anführungszeichen, da es ja Text ist), und ''quot'' verlangt die geraden doppelten Anführungzeichen (ebenfalls in Anführungszeichen -- damit R weiß, was gemeint ist, muss vor dem Anführungszeichen ein rückwärtiger Schrägstrich eingefügt werden. === Arbeiten mit Tabellen === Wenn wir die Tabelle eingelesen haben, können wir uns mit dem Befehl ''head'' die ersten 6 Zeilen des Data Frame anzeigen lassen, um zu überprüfen, ob alles funktioniert hat: head(novels) (wenn Sie mehr oder weniger Zeilen sehen wollen, können Sie als Parameter noch eine Zahl zum Befehl hinzufügen, z.B.: head(novels, 20) Wie bei einem Vektor können Sie sich auch bei einem Data Frame einzelne Elemente anzeigen lassen. Da die Tabelle, anders als ein Vektor, zwei Dimensionen hat, müssen Sie dabei hinter dem Namen des Data Frame immer zwei Werte in eckicken Klammern angeben (getrennt duch ein Komma): die Zeilennummer und die Spaltennummer (bei der Nummerierung zählt die Kopfzeile nicht mit). Z.B., um sich den Autor des beliebtesten Buches anzeigen zu lassen: novels[1,2] Oder um sich die Länge des drittbeliebtesten Buches anzeigen zu lassen: novels[3,3] Wenn Sie die Zahl hinter dem Komma weglassen, bekommen Sie eine ganze Zeile angezeigt: novels[28,] Wenn Sie die Zahl vor dem Komma weglassen, bekommen Sie eine ganze Spalte angezeigt. novels[,3] Diese verhält sich dann übrigens wie ein Vektor, sie können damit entsprechende Berechnungen durchführen: mean(novels[,3]) Wenn unser Data Frame eine Kopfzeile hat, können wir einzelne Spalten auch aufrufen, indem wir den Namen des Data Frame gefolgt von einem Dollar-Zeichen gefolgt vom Namen der betreffenden Spalte eingeben: novels$Length Auch in dieser Schreibweise verhält sich die Spalte wie ein Vektor. ==== Kreuztabellen ==== Uns fehlt noch die zweite der oben genannten Datenstrukturen: die Kreuztabelle. Wie Sie Kreuztabellen erstellen, erfahren Sie in der Übungseinheit //Statistische Tests für nominale Daten//.