Angewandte Datenverarbeitung und Visualisierung
  • D. Palleschi
  • Moodle
  1. Fortgeschrittene Themen
  2. 10  Base R
  • Kursübersicht
    • Kursübersicht
    • Erforderliche Software
    • Sitzungsinformationen
  • Grundlagen
    • 1  Einführung in R und RStudio
    • 2  Datenvisualiserung 1
    • 3  Dynamische Berichte mit Quarto
    • 4  Data Wrangling 1: Transformation
    • 5  Datenvisualisierung 2
  • Nächste Stufe
    • 6  Einlesen von Daten
    • 7  Deskriptive Statistik
    • 8  Datenvisualisierung 3
    • 9  Data Wrangling 2: Tidying
  • Fortgeschrittene Themen
    • 10  Base R
    • 11  Datenvisualisierung 4
    • 12  Troubleshooting
  • Berichte
    • 13  Bericht 1
    • 14  Bericht 2
  • Literaturverzeichnis
  • Anhang
    • A  Aufgaben

Kapitelinhalt

  • 10.1 Base R
    • 10.1.1 Warum beides lernen?
  • 10.2 Einrichten {.unnumbered}
    • 10.2.1 Einlesen
    • 10.2.2 CSV
    • 10.2.3 Andere Begrenzungszeichen
    • 10.2.4 Datenrahmen versus Tibbles
  • 10.3 Umgang mit Spalten und Zeilen
    • 10.3.1 Variablen extrahieren
    • 10.3.2 Beobachtungen extrahieren/filtern
    • 10.3.3 Einzelne Datenpunkte auswählen
    • 10.3.4 Neue Variablen erstellen
    • 10.3.5 Zusammenfassen
  • 10.4 Pipes
  • 10.5 Plots
  • Weitere Übungen
  • Session Info
  1. Fortgeschrittene Themen
  2. 10  Base R

10  Base R

Ein Vergleich mit tidyverse

Autor:in
Zugehörigkeit

Daniela Palleschi

Humboldt-Universität zu Berlin

Veröffentlichungsdatum

Mi. den 24.01.2024

Geändert

Di. den 25.06.2024

Lesungen

Die Pflichtlektüre zur Vorbereitung auf dieses Thema ist Kapital 27 (A field guide to Base R) in Wickham et al. (2023).

Lernziele

In diesem Kapitel werden wir…

  • lernen, was Base R ist
  • Base R und Tidyverse vergleichen
  • die Base-R-Äquivalente der Tidyverse-Verben kennenlernen

10.1 Base R

Die Basissoftware, die die Programmiersprache R enthält, heißt base-R oder natives R. Dieses Basissystem enthält das Paket base, das zum Ausführen von R erforderlich ist. Ähnlich wie tidyverse enthält das Basissystem auch einige Pakete wie utils und stats (unter anderem). Um zu sehen, welche Pakete enthalten sind, gehen Sie einfach auf die Registerkarte Pakete unten rechts in Ihrer RStudio-Sitzung. Unter der Annahme, dass Sie mit einer sauberen Arbeitsumgebung beginnen, sollten nur die Pakete geladen werden, die zum R-Basissystem gehören. Alle diese Pakete werden bei der Installation von R installiert. Mit dieser Sammlung von Paketen können die meisten (wenn nicht alle) der gleichen Ziele wie mit tidyverse erreicht werden, auch wenn beide für bestimmte Ziele vorzuziehen oder besser zu rationalisieren sind.

Wie wir bereits gelernt haben, ist das Tidyverse (Wickham et al., 2019a) eine Familie von R-Paketen, die das Bereinigen und Verwalten von Daten erleichtern sollen. Der Hauptentwickler von Tidyverse ist Hadley Wickham, der Chefwissenschaftler von Posit (ehemals RStudio), dem Softwareunternehmen, das die integrierte Entwicklungsumgebung (IDE) RStudio entwickelt hat. Alle Pakete in Tidyverse “teilen eine High-Level-Design-Philosophie und Low-Level-Grammatik und Datenstrukturen, so dass das Erlernen eines Pakets es einfacher macht, das nächste zu erlernen” (Wickham et al., 2019b). Allerdings wurde das Tidyverse in der Programmiersprache R geschrieben, sodass die beiden nicht vollständig voneinander getrennt sind.

Sowohl Base R als auch tidyverse sind Open-Source-Sprachen, die für die Datenwissenschaft geschrieben wurden. Ein Hauptziel von Base R ist die Stabilität, d. h. der Code sollte über viele Jahre hinweg stabil sein. Tidyverse hingegen fügt ständig Funktionen und Argumente hinzu, aktualisiert sie und ändert sie mit neuen Paketversionen im Hinblick auf die Optimierung. Dies bedeutet, dass Tidyverse-Code anfällig für “Brüche” ist: Tidyverse-Code, der heute läuft, läuft vielleicht in ein paar Jahren nicht mehr, wenn einige Funktionen oder Argumente “veraltet” sind. Deshalb ist es so wichtig, dass Sie immer Ihre sessionInfo() mit einem Bericht mitschicken, sie dokumentiert, welche Pakete und deren Versionen Sie verwendet haben.

In der Debatte zwischen Base R und Tidyverse gibt es in der Regel drei Lager: die starken Befürworter von Base R, die starken Befürworter von Tidyverse und die Agnostiker. In Bezug auf den R-Unterricht gibt es mehrere Arbeiten, in denen die potenziellen Vorteile des Unterrichts von Base R oder des Tidyverse bzw. einer Kombination aus beidem untersucht werden. Einige argumentieren, dass das Lehren der Tidyverse für Schüler intuitiver ist, während andere behaupten, dass Base R der “einzige” Weg ist, um echte R-Kenntnisse zu erlangen. Base R ist z.B. einfacher, wenn es darum geht, eine einzelne Variable zu extrahieren, aber selbst unter standhaften Base R-Nutzern wird das Paket ggplot2 oft bevorzugt, um Diagramme zu erstellen. Unten sehen wir einen Tweet von Prof. Christopher Zorn (Penn State), der vorschlägt, dass die Kenntnis des “tidyverse” nicht bedeutet, dass man R kennt, mit einer Antwort von Prof. Bodo Winter (University of Birmingham) zur Unterstützung des tidyverse. Viele andere Antworten wiesen auf die verschiedenen Vorteile des Tidyverse hin, von der Lehre von R bis zur Arbeit in der Industrie. Wichtig (und für Sie als Linguistikstudenten relevant) ist, dass Bodo Winter der Autor von ‘Statistics for Linguists: An Introduction Using R’ (Winter, 2019), das ebenfalls tidyverse verwendet. Sein Buch sowie die Tutorien, die er als Doktorand geschrieben hat (Winter, 2013, 2014), sind in einer verständlichen Sprache verfasst, die sie für Studierende zugänglich macht. Es ist also kein Wunder, dass er ein Befürworter von tidyverse ist, das auch für Nicht-Programmierer zugänglich sein soll.

What a thing to say when modern R is pretty much synonymous with the tidyverse for many in the community!

I was a Base R masochist once too.. but there's no need for statements like this when the tidyverse has helped so many of us be more productive and write more readable code.

— Bodo Winter ((BodoWinter?)) January 10, 2023

Offensichtlich halte ich das Erlernen des Tidyversums für wichtig, denn ich habe mich entschieden, diesen Kurs auf Tidyversum-Pakete zu stützen. Das liegt daran, dass das Tidyverse den Menschen in den Mittelpunkt stellt, und dieser Kurs ist nicht für Programmierer oder Informatiker gedacht. Wie wir im obigen Tweet sehen, stimmt nicht jeder mit mir überein, aber es gibt auch viele Leute, die das tun.

10.1.1 Warum beides lernen?

Ich persönlich lernte Base R Jahre bevor ich Tidyverse lernte. Ich habe nie zurückgeblickt, und mein Code ist seit der Einführung von tidyverse und den dahinter stehenden Philosophien viel sauberer und besser lesbar geworden. Trotzdem gibt es immer noch bestimmte Aufgaben, für die ich Base R verwende, z. B. für einen schnellen Blick auf eine einzelne Variable oder wenn ich mit Listen oder verschachtelten Datenstrukturen arbeite (die wir in diesem Kurs nicht behandeln werden).

Auch wenn ich persönlich mit ähnlichen Ansichten wie im ursprünglichen Tweet oben nicht einverstanden bin (wie viele andere auch), ist die Kenntnis von Base R eine wichtige Fähigkeit, um Ihre R-Horizonte zu erweitern. Sie werden mit Sicherheit auf Base R-Code stoßen, wenn Sie nach Lösungen für Probleme suchen oder sich den Code von anderen ansehen. Unabhängig davon, ob jemand eine starke Vorliebe für Base R oder Tidyverse hat, ist es eine gute Idee, mit beiden Optionen vertraut zu sein, um das Beste aus der R-Community herauszuholen. Es ist wichtig zu verstehen, dass es so etwas wie perfekten Code nicht gibt, und dass es fast immer mehrere Möglichkeiten gibt, das gleiche Ziel zu erreichen, sogar innerhalb von Base R oder Tidyverse. Was wir heute lernen werden, ist im Wesentlichen, wie wir den Tidyverse-Code, mit dem wir vertraut sind, in Base R übersetzen können.

10.2 Einrichten {.unnumbered}

Wir werden heute ziemlich minimalistisch arbeiten. Alles was wir brauchen sind die Pakete tidyverse und here.

pacman::p_load(
  tidyverse,
  here
)

10.2.1 Einlesen

Wir werden den Datensatz languageR_english.csv einlesen, der sich bereits in Ihrem daten-Ordner befinden sollte. Dieser Datensatz enthält Daten aus einer Benennungs- und lexikalischen Entscheidungsaufgabe in Englisch.

10.2.2 CSV

Wir haben bereits gesehen, wie man die read_() Familie von Funktionen (read_csv(), read_csv2(), read_delim(), etc.) aus dem readr Paket aus dem tidyverse benutzt.

tidyverse
df_tidy <-
  read_csv(
    here("daten", "languageR_english.csv")
  )

Um einen Datensatz mit kommagetrennten Werten (CSV) einzulesen, können wir die Funktion read.csv() verwenden, die eine Version der umfassenderen Funktion read.table() aus dem Paket utils ist. Das utils-Paket ist ein Standard-Installationspaket in R, so wie einige Anwendungen bereits installiert sind, wenn man ein neues Telefon kauft.

Base R
df_base <-
  read.csv(
    here("daten", "languageR_english.csv")
  )

Das erste, was Ihnen vielleicht auffällt, ist, dass wir beim Ausführen von read_csv() eine Meldung erhalten haben, die uns die Anzahl der Zeilen und Spalten in den Daten, das verwendete Trennzeichen (bei read_csv() immer ein Komma) und den Datentyp, zu dem unsere Variablen gehören, mitteilt. Hier haben wir gesehen, dass wir drei Zeichenvariablen (chr) und vier numerische Variablen (dbl für “double”) haben. Bei der Verwendung von read.csv() erhalten wir keine derartige Meldung. Im Allgemeinen ist Tidyverse ein besserer Gesprächspartner als Base R. Sie erhalten mehr Meldungen, und die Warn- oder Fehlermeldungen sind anschaulicher.

Ein weiterer Unterschied zwischen diesen beiden Funktionen ist die Art und Weise, wie sie read und csv trennen: tidyverse verwendet typischerweise _, um Wörter zu trennen, während Base R dazu neigt, eine Mischung aus . und _ zu verwenden. Dies geht auf die Prinzipien von tidyverse zurück, in denen versucht wird, konsistente Konventionen beizubehalten, um sauberen Code und saubere Daten zu fördern. Dazu gehört auch die konsequente Verwendung von `_” in Funktions- und Variablennamen.

Schauen wir uns nun die beiden Objekte an, die wir jetzt haben. Wie viele Spalten haben sie?

length(df_tidy)
[1] 7
length(df_base)
[1] 7

Beide haben 7 Spalten. Wie lauten die Namen dieser Spalten?

names(df_base)
[1] "AgeSubject"       "Word"             "LengthInLetters"  "WrittenFrequency"
[5] "WordCategory"     "RTlexdec"         "RTnaming"        
names(df_tidy)
[1] "AgeSubject"       "Word"             "LengthInLetters"  "WrittenFrequency"
[5] "WordCategory"     "RTlexdec"         "RTnaming"        

Sie haben auch die gleichen Namen, so weit, so gut. Wie viele Zeilen gibt es in jedem?

nrow(df_tidy)
[1] 4568
nrow(df_base)
[1] 4568

Beide haben 4568 Zeilen. Die Datenstruktur ist also identisch.

10.2.3 Andere Begrenzungszeichen

Erinnern Sie sich, dass wir mit dem tidyverse-Paket readr read_delim(delim = "") verwenden können, um das Trennzeichen explizit zu definieren. Hier verwenden wir delim = ",", weil wir immer noch eine kommagetrennte Wertedatei verwenden.

tidyverse
df_tidy <-
  read_delim(
    here("daten", "languageR_english.csv"),
    delim = ","
  )

Wir können dies mit read.table(sep = "") aus dem Paket utils tun.

Base R
df_base <-read.table(
    here("daten", "languageR_english.csv"),
    sep = ",",
    header = TRUE
  )
Begrenzungszeichen und Trennzeichen

Versuchen Sie, das Trennzeichen in den obigen Code-Blöcken durch ein Semikolon (;) zu ersetzen. Was ändert sich, und warum? Ändern Sie es wieder in ein Komma und führen Sie es erneut aus, bevor Sie fortfahren.

10.2.4 Datenrahmen versus Tibbles

Daten, die mit tidyverse eingelesen werden, werden als Tibble gespeichert, das als eine aufgeräumtere Version eines Datenrahmens gilt. Wichtig ist, dass die Struktur eines Tibbles und die darin enthaltenen Informationen mit denen eines Datenrahmens identisch sind. Im Folgenden werden wir einige Unterschiede zwischen Tibbles und Datenrahmen sehen.

10.3 Umgang mit Spalten und Zeilen

Wir sind bereits mit einer Reihe von dplyr-Verben vertraut, die zum Manipulieren, Filtern und Extrahieren von Zeilen und Spalten verwendet werden. Jetzt sehen wir uns alternative Wege an, um die gleichen Ergebnisse mit Base R zu erzielen.

10.3.1 Variablen extrahieren

Wir sind bereits vertraut mit select() aus dplyr:

tidyverse
df_tidy |> 
  select(AgeSubject)
# A tibble: 10 × 1
   AgeSubject
   <chr>     
 1 young     
 2 young     
 3 young     
 4 young     
 5 young     
 6 young     
 7 young     
 8 young     
 9 young     
10 young     

In Base R können wir ein Dollarzeichen ($) verwenden, um eine Spalte aus einem Datenrahmen (oder Tibble) zu extrahieren. Dadurch erhalten wir einen Vektor, während dplyr::select() die Datenrahmen-/Tibble-Attribute der Spalte beibehält.

Base R
df_base$AgeSubject
 [1] "young" "young" "young" "young" "young" "young" "young" "young" "young"
[10] "young" "young" "young" "young" "young" "young" "young" "young" "young"

Alternativ kann man auch dataframe[row,column] verwenden, um Zeilen und Spalten zu definieren. Wir können den Namen einer Spalte in Anführungszeichen verwenden oder den Index der Spalte angeben, wobei 1 für die erste Spalte steht, 2 für die zweite Spalte usw. Wir konzentrieren uns zunächst auf die Spalten, geben also nicht an, welche Zeile wir wollen, sondern geben alle Zeilen dieser Spalte aus.

Base R
# using variable name
df_base[,"AgeSubject"]
 [1] "young" "young" "young" "young" "young" "young" "young" "young" "young"
[10] "young" "young" "young" "young" "young" "young" "young" "young" "young"
Base R
# using variable index
df_base[,1]
 [1] "young" "young" "young" "young" "young" "young" "young" "young" "young"
[10] "young" "young" "young" "young" "young" "young" "young" "young" "young"

Ein Hauptunterschied zwischen der Verwendung von tidyverse und Base R zum Extrahieren einer einzelnen Variablen besteht darin, dass Base R einen Vektor extrahiert, während das tidyverse-Verb select() die Variable als Tibble behält. Beachten Sie, dass es auch möglich ist, mehrere Variablen mit der Funktion select() auszuwählen. Sie können dies auch mit Base R tun, aber Sie müssen die Funktion c() verwenden.

tidyverse
df_tidy |> 
  select(AgeSubject, RTlexdec)
# A tibble: 10 × 2
   AgeSubject RTlexdec
   <chr>         <dbl>
 1 young          695.
 2 young          600.
 3 young          547.
 4 young          617.
 5 young          633.
 6 young          687.
 7 young          584.
 8 young          527.
 9 young          741.
10 young          536.
Base R
# using variable name
df_base[,c("AgeSubject", "RTlexdec")]
   AgeSubject RTlexdec
1       young   694.89
2       young   600.40
3       young   547.27
4       young   616.60
5       young   633.08
6       young   686.75
7       young   584.40
8       young   526.82
9       young   741.48
10      young   536.38
Base R
# using variable index
df_base[,c(1, 6)]
   AgeSubject RTlexdec
1       young   694.89
2       young   600.40
3       young   547.27
4       young   616.60
5       young   633.08
6       young   686.75
7       young   584.40
8       young   526.82
9       young   741.48
10      young   536.38

10.3.1.1 Mischen von Tibbles und Datenrahmen

Die Ausgabe dieser Operationen hängt nicht nur davon ab, ob Sie eine Tidyverse- oder eine R-Basisfunktion verwenden. Es macht auch einen Unterschied, ob die Daten ein Datenrahmen oder ein Tibble sind. Versuchen wir, die Funktion select() von tidyverse auf einen Datenrahmen anzuwenden:

tidyverse
df_base |> 
  select(AgeSubject)
# A tibble: 10 × 1
   AgeSubject
   <chr>     
 1 young     
 2 young     
 3 young     
 4 young     
 5 young     
 6 young     
 7 young     
 8 young     
 9 young     
10 young     

Base R behandelt Tibbles jedoch genauso wie Datenrahmen und gibt einen Vektor mit allen Werten einer einzelnen Spalte aus.

Base R
df_tidy$AgeSubject
 [1] "young" "young" "young" "young" "young" "young" "young" "young" "young"
[10] "young"

Dies sollte keine Folgen haben, aber es ist wichtig, die innere Struktur Ihrer Daten zu verstehen, damit Sie entsprechend damit arbeiten können.

10.3.2 Beobachtungen extrahieren/filtern

Wir haben bereits die Funktion filter() von dplyr gesehen, die Zeilen extrahiert, die logischen Bedingungen entsprechen.

tidyverse
df_tidy |> 
  filter(RTlexdec > 600 & RTnaming < 480)
# A tibble: 856 × 7
   AgeSubject Word  LengthInLetters WrittenFrequency WordCategory RTlexdec
   <chr>      <chr>           <dbl>            <dbl> <chr>           <dbl>
 1 young      doe                 3             3.91 N                695.
 2 young      pork                4             5.02 N                617.
 3 young      prop                4             4.77 N                687.
 4 young      arc                 3             4.89 N                741.
 5 young      tile                4             4.08 N                647.
 6 young      slope               5             5.80 N                633.
 7 young      pith                4             2.48 N                696.
 8 young      blitz               5             4.19 N                672.
 9 young      port                4             6.08 N                683.
10 young      plan                4             7.46 N                636.
# ℹ 846 more rows
# ℹ 1 more variable: RTnaming <dbl>

Wir können diese bedingten Anweisungen in [,] einfügen, wobei zu beachten ist, dass die Zeilen vor dem Komma und die Spalten nach dem Komma angegeben werden. Wir lassen die Spaltenangabe leer, d. h. wir wollen alle Spalten ausgeben. Wichtig ist, dass wir in den bedingten Anweisungen den Namen des Datenrahmens mit dem Dollarzeichen vor dem Spaltennamen angeben.

Base R
df_base[df_base$RTlexdec > 600 & df_base$RTnaming < 480,]
   AgeSubject  Word LengthInLetters WrittenFrequency WordCategory RTlexdec
1       young   doe               3         3.912023            N   694.89
4       young  pork               4         5.017280            N   616.60
6       young  prop               4         4.770685            N   686.75
9       young   arc               3         4.890349            N   741.48
17      young  tile               4         4.077537            N   647.07
18      young slope               5         5.802118            N   632.54
22      young  pith               4         2.484907            N   695.86
26      young blitz               5         4.189655            N   671.59
29      young  port               4         6.084499            N   683.36
34      young  plan               4         7.462789            N   636.10
   RTnaming
1     466.4
4     460.3
6     477.1
9     453.8
17    459.3
18    476.2
22    473.3
26    469.5
29    459.3
34    470.4

10.3.3 Einzelne Datenpunkte auswählen

Wir können bestimmte Zeilen und bestimmte Spalten auf einmal extrahieren. Wenn wir zum Beispiel die relevanten Zeilen wie oben ausgeben wollen, aber nur die Spalten AgeSubject und RTlexdec, können wir dies mit filter() und select() tun (was wir bereits zuvor getan haben).

tidyverse
df_tidy |> 
  filter(RTlexdec > 600, RTnaming < 480) |> 
  select(AgeSubject, RTlexdec)
# A tibble: 10 × 2
   AgeSubject RTlexdec
   <chr>         <dbl>
 1 young          695.
 2 young          617.
 3 young          687.
 4 young          741.
 5 young          647.
 6 young          633.
 7 young          696.
 8 young          672.
 9 young          683.
10 young          636.

In Base R würden wir dies einfach in [,] einfügen. Dadurch erhalten wir keinen Vektor mehr, sondern die Datenrahmenstruktur bleibt erhalten. Nicht, dass wir auch die Zeilennummern erhalten.

Base R
df_base[df_base$RTlexdec > 600 & df_base$RTnaming < 480,c("AgeSubject", "RTlexdec")]
   AgeSubject RTlexdec
1       young   694.89
4       young   616.60
6       young   686.75
9       young   741.48
17      young   647.07
18      young   632.54
22      young   695.86
26      young   671.59
29      young   683.36
34      young   636.10

Auch hier können Sie die Spaltennamen durch den Indexwert ersetzen.

Base R
df_base[df_base$RTlexdec > 600 & df_base$RTnaming < 480,c(1, 6)]
   AgeSubject RTlexdec
1       young   694.89
4       young   616.60
6       young   686.75
9       young   741.48
17      young   647.07
18      young   632.54
22      young   695.86
26      young   671.59
29      young   683.36
34      young   636.10

10.3.4 Neue Variablen erstellen

Wir haben gelernt, wie man mit der Funktion mutate(), die ebenfalls aus dplyr stammt, neue Variablen erstellt oder bestehende Variablen ändert.

tidyverse
df_tidy |> 
  mutate(rt_lexdec_s = RTlexdec/1000)
# A tibble: 4,568 × 8
   AgeSubject Word   LengthInLetters WrittenFrequency WordCategory RTlexdec
   <chr>      <chr>            <dbl>            <dbl> <chr>           <dbl>
 1 young      doe                  3             3.91 N                695.
 2 young      whore                5             4.52 N                600.
 3 young      stress               6             6.51 N                547.
 4 young      pork                 4             5.02 N                617.
 5 young      plug                 4             4.89 N                633.
 6 young      prop                 4             4.77 N                687.
 7 young      dawn                 4             6.38 N                584.
 8 young      dog                  3             7.16 N                527.
 9 young      arc                  3             4.89 N                741.
10 young      skirt                5             5.93 N                536.
# ℹ 4,558 more rows
# ℹ 2 more variables: RTnaming <dbl>, rt_lexdec_s <dbl>

In Base R geschieht dies, indem wir den Namen der neuen Variablen definieren und ihr mit dem Zuweisungsoperator <- einen Wert zuweisen.

Base R
df_base$rt_lexdec_s <- df_base$RTlexdec/1000

10.3.5 Zusammenfassen

Als Letztes wollen wir lernen, wie man in Base R zusammenfasst. Das ist nicht einfach, wenn man eine Gruppe hat, deshalb werden wir das nicht behandeln.

tidyverse
  df_tidy |> 
  summarise(
    mean_lexdec = mean(RTlexdec),
    sd_lexdec = sd(RTlexdec),
    mean_naming = mean(RTnaming, na.rm = T),
    sd_naming = sd(RTnaming, na.rm = T)
  )
# A tibble: 1 × 4
  mean_lexdec sd_lexdec mean_naming sd_naming
        <dbl>     <dbl>       <dbl>     <dbl>
1        708.      115.        566.      101.

In Base R müssen wir neue Objekte erstellen, die den Wert jeder Operation enthalten, und sie mit der Funktion “data.frame()” zu einem Datenrahmen zusammenfassen.

Base R
data.frame(mean_lexdec = mean(df_base$RTlexdec),
           sd_lexdec = sd(df_base$RTlexdec),
           mean_naming = mean(df_base$RTnaming, na.rm = T),
           sd_naming = sd(df_base$RTnaming, na.rm = T))
  mean_lexdec sd_lexdec mean_naming sd_naming
1    708.1336  114.8599    565.9233  100.8153

10.4 Pipes

Lange Zeit waren Pipes ein Feature des Tidyverse, mit der %>% Pipe aus dem magrittr Paket. Seit 2023 bietet R eine native Pipe |>. Sie haben vielleicht schon beide Versionen gesehen (ich tendiere dazu, |> zu benutzen). Für unsere Zwecke sind sie austauschbar, aber es gibt wichtige Unterschiede für komplexere Fälle, die wir nicht behandeln werden.

tidyverse
df_base$RTlexdec |> 
  mean()
[1] 708.1336
Base R
df_base$RTlexdec %>%
  mean()
[1] 708.1336

10.5 Plots

ggplot2 ist auch bei Leuten beliebt, die sonst nicht die tidyverse-Paketfamilie nutzen. Das liegt daran, dass es einige nützliche Funktionen und ein sauberes Aussehen hat.

Das Plotten mit Base R kann auch sehr praktisch sein, wenn man einfache Diagramme erstellen will, um einen ersten Blick auf die Daten zu bekommen. Die nützlichsten Funktionen sind hist() und plot(), die jeweils Histogramme und Streudiagramme erzeugen. Beachten Sie, dass diese Funktionen mit Vektoren arbeiten, weswegen wir $ verwenden müssen, um die Spalten aus dem Datenrahmen zu extrahieren.

Base R
# left
hist(df_base$RTlexdec)
# right
plot(df_base$RTlexdec, df_base$RTnaming) 
Abbildung 10.1: Histogram and scatterplot with Base R
Abbildung 10.2: Histogram and scatterplot with Base R

To achieve the same thing with the tidyverse:

tidyverse
# histogram
df_base |> 
  ggplot() +
  aes(x = RTlexdec) +
  geom_histogram()

# scatter plot
  df_base |> 
  ggplot() +
  aes(x = RTlexdec, y = RTnaming) +
  geom_point() 
Abbildung 10.3: Histogram and scatterplot with ggplot2

Lernziele 🏁

In diesem Kapitel werden wir…

  • lernen, was Base R ist ✅
  • Base R und Tidyverse vergleichen ✅
  • die Base-R-Äquivalente der Tidyverse-Verben kennenlernen ✅

Weitere Übungen

Weitere Übungen zu diesem Kapitel finden Sie in Kapitel A.10

Session Info

Hergestellt mit R version 4.4.0 (2024-04-24) (Puppy Cup) und RStudioversion 2023.9.0.463 (Desert Sunflower).

print(sessionInfo(),locale = F)
R version 4.4.0 (2024-04-24)
Platform: aarch64-apple-darwin20
Running under: macOS Ventura 13.2.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.0

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
 [1] patchwork_1.2.0 janitor_2.2.0   here_1.0.1      lubridate_1.9.3
 [5] forcats_1.0.0   stringr_1.5.1   dplyr_1.1.4     purrr_1.0.2    
 [9] readr_2.1.5     tidyr_1.3.1     tibble_3.2.1    ggplot2_3.5.1  
[13] tidyverse_2.0.0

loaded via a namespace (and not attached):
 [1] utf8_1.2.4        generics_0.1.3    renv_1.0.7        stringi_1.8.3    
 [5] hms_1.1.3         digest_0.6.35     magrittr_2.0.3    evaluate_0.23    
 [9] grid_4.4.0        timechange_0.3.0  fastmap_1.1.1     rprojroot_2.0.4  
[13] jsonlite_1.8.8    fansi_1.0.6       scales_1.3.0      cli_3.6.2        
[17] crayon_1.5.2      rlang_1.1.3       bit64_4.0.5       munsell_0.5.1    
[21] withr_3.0.0       yaml_2.3.8        parallel_4.4.0    tools_4.4.0      
[25] tzdb_0.4.0        colorspace_2.1-0  pacman_0.5.1      vctrs_0.6.5      
[29] R6_2.5.1          lifecycle_1.0.4   snakecase_0.11.1  htmlwidgets_1.6.4
[33] bit_4.0.5         vroom_1.6.5       pkgconfig_2.0.3   pillar_1.9.0     
[37] gtable_0.3.5      glue_1.7.0        xfun_0.43         tidyselect_1.2.1 
[41] rstudioapi_0.16.0 knitr_1.46        farver_2.1.1      htmltools_0.5.8.1
[45] labeling_0.4.3    rmarkdown_2.26    compiler_4.4.0   
Wickham, H., Averick, M., Bryan, J., Chang, W., McGowan, L. D., François, R., Grolemund, G., Hayes, A., Henry, L., Hester, J., Kuhn, M., Pedersen, T. L., Miller, E., Bache, S. M., Müller, K., Ooms, J., Robinson, D., Seidel, D. P., Spinu, V., … Yutani, H. (2019a). Welcome to the tidyverse. Journal of Open Source Software, 4(43), 1686. https://doi.org/10.21105/joss.01686
Wickham, H., Averick, M., Bryan, J., Chang, W., McGowan, L., François, R., Grolemund, G., Hayes, A., Henry, L., Hester, J., Kuhn, M., Pedersen, T., Miller, E., Bache, S., Müller, K., Ooms, J., Robinson, D., Seidel, D., Spinu, V., … Yutani, H. (2019b). Welcome to the Tidyverse. Journal of Open Source Software, 4(43), 1686. https://doi.org/10.21105/joss.01686
Wickham, H., Çetinkaya-Rundel, M., & Grolemund, G. (2023). R for Data Science (2. Aufl.).
Winter, B. (2013). Linear Models and Linear Mixed Effects Models in R: Tutorial 1 (Nr. arXiv:1308.5499).
Winter, B. (2014). A Very Basic Tutorial for Performing Linear Mixed Effects Analyses (Tutorial 2) (Nr. arXiv:1308.5499).
Winter, B. (2019). Statistics for Linguists: An Introduction Using R. In Statistics for Linguists: An Introduction Using R. Routledge. https://doi.org/10.4324/9781315165547
9  Data Wrangling 2: Tidying
11  Datenvisualisierung 4
Quellcode
---
# title: "Base R"
subtitle: "Ein Vergleich mit tidyverse"
author: "Daniela Palleschi"
institute: Humboldt-Universität zu Berlin
footer: "Woche 13 - Base R" 
date: "01/24/2024"
date-format: "ddd [den] DD.MM.YYYY"
date-modified: last-modified
shift-heading-level-by: +1
---

# Base R {#sec-baseR}

```{r}
#| echo: false
knitr::opts_chunk$set(eval = T, ## evaluate chunks
                      echo = T, ## 'print code chunk?'
                      message = F, ## 'print messages (e.g., warnings)?'
                      error = T, ## continueeven when error encountered
                      warning = F) ## don't print warnings
```

# Lesungen {.unnumbered .unlisted}

Die **Pflichtlektüre** zur Vorbereitung auf dieses Thema ist [Kapital 27 (A field guide to Base R)](https://r4ds.hadley.nz/base-r) in @wickham_r_2023.

# Lernziele {.unnumbered .unlisted}

In diesem Kapitel werden wir...

- lernen, was Base R ist
- Base R und Tidyverse vergleichen
- die Base-R-Äquivalente der Tidyverse-Verben kennenlernen

# Base R

Die Basissoftware, die die Programmiersprache R enthält, heißt base-R oder natives R. Dieses Basissystem enthält das Paket `base`, das zum Ausführen von R erforderlich ist. Ähnlich wie tidyverse enthält das Basissystem auch einige Pakete wie `utils` und `stats` (unter anderem). Um zu sehen, welche Pakete enthalten sind, gehen Sie einfach auf die Registerkarte `Pakete` unten rechts in Ihrer RStudio-Sitzung. Unter der Annahme, dass Sie mit einer sauberen Arbeitsumgebung beginnen, sollten nur die Pakete geladen werden, die zum R-Basissystem gehören. Alle diese Pakete werden bei der Installation von R installiert. Mit dieser Sammlung von Paketen können die meisten (wenn nicht alle) der gleichen Ziele wie mit tidyverse erreicht werden, auch wenn beide für bestimmte Ziele vorzuziehen oder besser zu rationalisieren sind.

Wie wir bereits gelernt haben, ist das [Tidyverse](https://www.tidyverse.org/) [@tidyverse-package] eine Familie von R-Paketen, die das Bereinigen und Verwalten von Daten erleichtern sollen. Der Hauptentwickler von Tidyverse ist Hadley Wickham, der Chefwissenschaftler von Posit (ehemals RStudio), dem Softwareunternehmen, das die integrierte Entwicklungsumgebung (IDE) RStudio entwickelt hat. Alle Pakete in Tidyverse "teilen eine High-Level-Design-Philosophie und Low-Level-Grammatik und Datenstrukturen, so dass das Erlernen eines Pakets es einfacher macht, das nächste zu erlernen" [@wickham_welcome_2019]. Allerdings wurde das Tidyverse in der Programmiersprache R geschrieben, sodass die beiden nicht vollständig voneinander getrennt sind. 

Sowohl Base R als auch tidyverse sind Open-Source-Sprachen, die für die Datenwissenschaft geschrieben wurden. Ein Hauptziel von Base R ist die Stabilität, d. h. der Code sollte über viele Jahre hinweg stabil sein. Tidyverse hingegen fügt ständig Funktionen und Argumente hinzu, aktualisiert sie und ändert sie mit neuen Paketversionen im Hinblick auf die Optimierung. Dies bedeutet, dass Tidyverse-Code anfällig für "Brüche" ist: Tidyverse-Code, der heute läuft, läuft vielleicht in ein paar Jahren nicht mehr, wenn einige Funktionen oder Argumente "veraltet" sind. Deshalb ist es so wichtig, dass Sie immer Ihre `sessionInfo()` mit einem Bericht mitschicken, sie dokumentiert, welche Pakete und deren Versionen Sie verwendet haben.

In der Debatte zwischen Base R und Tidyverse gibt es in der Regel drei Lager: die starken Befürworter von Base R, die starken Befürworter von Tidyverse und die Agnostiker. In Bezug auf den R-Unterricht gibt es mehrere Arbeiten, in denen die potenziellen Vorteile des Unterrichts von Base R oder des Tidyverse bzw. einer Kombination aus beidem untersucht werden. Einige argumentieren, dass das Lehren der Tidyverse für Schüler intuitiver ist, während andere behaupten, dass Base R der "einzige" Weg ist, um echte R-Kenntnisse zu erlangen. Base R ist z.B. einfacher, wenn es darum geht, eine einzelne Variable zu extrahieren, aber selbst unter standhaften Base R-Nutzern wird das Paket `ggplot2` oft bevorzugt, um Diagramme zu erstellen. Unten sehen wir einen Tweet von Prof. Christopher Zorn (Penn State), der vorschlägt, dass die Kenntnis des "tidyverse" nicht bedeutet, dass man R kennt, mit einer Antwort von Prof. Bodo Winter (University of Birmingham) zur Unterstützung des tidyverse. Viele andere Antworten wiesen auf die verschiedenen Vorteile des Tidyverse hin, von der Lehre von R bis zur Arbeit in der Industrie. Wichtig (und für Sie als Linguistikstudenten relevant) ist, dass Bodo Winter der Autor von '*Statistics for Linguists: An Introduction Using R*' [@winter_statistics_2019], das ebenfalls tidyverse verwendet. Sein Buch sowie die Tutorien, die er als Doktorand geschrieben hat [@winter_linear_2013; @winter_very_2014], sind in einer verständlichen Sprache verfasst, die sie für Studierende zugänglich macht. Es ist also kein Wunder, dass er ein Befürworter von tidyverse ist, das auch für Nicht-Programmierer zugänglich sein soll.

::: {.content-visible when-format="html"}

<center>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">What a thing to say when modern R is pretty much synonymous with the tidyverse for many in the community!<br><br>I was a Base R masochist once too.. but there&#39;s no need for statements like this when the tidyverse has helped so many of us be more productive and write more readable code.</p>&mdash; Bodo Winter (@BodoWinter) <a href="https://twitter.com/BodoWinter/status/1612882152483586049?ref_src=twsrc%5Etfw">January 10, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</center>

:::

::: {.content-visible when-format="pdf"}
```{r}
#| echo: false
#| label: fig-twitter-white
#| fig-cap: A tweet exchange about base R versus the tidyverse (original tweet above, with reply below). [Click here to view tweet.](https://x.com/BodoWinter/status/1612882152483586049?s=20)
#| out-width: "70%"
knitr::include_graphics(
  here::here("media", "twitter_baser_tidyverse_white.png")
)  
```
:::

```{r}
#| eval: false
#| echo: false
#| label: fig-twitter
#| fig-cap: A tweet (A) with a reply in support of the tidyverse, with two other replies pointing out the benefits of the tidyverse (B) and its use in industry (C)
#| fig-height: 8

library(ggpubr)
library(grid)
library(png)


tweet_bodo <- readPNG(
  here::here("media", "twitter_baser_tidyverse.png")
)  

tweet_cleaner <- readPNG(
  here::here("media", "twitter_cleaner.png")
)

tweet_industry <- readPNG(
  here::here("media", "twitter_industry.png")
)

ggarrange(rasterGrob(tweet_bodo, width = .65),
          rasterGrob(tweet_cleaner, width = .65),
          rasterGrob(tweet_industry, width = .65), 
          ncol = 1,
          labels = c("A","B","C"),
          heights = c(0.5, 1/4,1/4))
```

Offensichtlich halte ich das Erlernen des Tidyversums für wichtig, denn ich habe mich entschieden, diesen Kurs auf Tidyversum-Pakete zu stützen. Das liegt daran, dass das Tidyverse den Menschen in den Mittelpunkt stellt, und dieser Kurs ist nicht für Programmierer oder Informatiker gedacht. Wie wir im obigen Tweet sehen, stimmt nicht jeder mit mir überein, aber es gibt auch viele Leute, die das tun.


## Warum beides lernen?

Ich persönlich lernte Base R Jahre bevor ich Tidyverse lernte. Ich habe nie zurückgeblickt, und mein Code ist seit der Einführung von tidyverse und den dahinter stehenden Philosophien viel sauberer und besser lesbar geworden. Trotzdem gibt es immer noch bestimmte Aufgaben, für die ich Base R verwende, z. B. für einen schnellen Blick auf eine einzelne Variable oder wenn ich mit Listen oder verschachtelten Datenstrukturen arbeite (die wir in diesem Kurs nicht behandeln werden). 

Auch wenn ich persönlich mit ähnlichen Ansichten wie im ursprünglichen Tweet oben nicht einverstanden bin (wie viele andere auch), ist die Kenntnis von Base R eine wichtige Fähigkeit, um Ihre R-Horizonte zu erweitern. Sie werden mit Sicherheit auf Base R-Code stoßen, wenn Sie nach Lösungen für Probleme suchen oder sich den Code von anderen ansehen. Unabhängig davon, ob jemand eine starke Vorliebe für Base R oder Tidyverse hat, ist es eine gute Idee, mit beiden Optionen vertraut zu sein, um das Beste aus der R-Community herauszuholen. Es ist wichtig zu verstehen, dass es so etwas wie perfekten Code nicht gibt, und dass es fast immer mehrere Möglichkeiten gibt, das gleiche Ziel zu erreichen, sogar innerhalb von Base R oder Tidyverse. Was wir heute lernen werden, ist im Wesentlichen, wie wir den Tidyverse-Code, mit dem wir vertraut sind, in Base R übersetzen können.

# Einrichten {.unnumbered} {#sec-baseR_setup}

Wir werden heute ziemlich minimalistisch arbeiten. Alles was wir brauchen sind die Pakete `tidyverse` und `here`.

```{r}
pacman::p_load(
  tidyverse,
  here
)
```

```{r}
#| echo: false
pacman::p_load(janitor,
               patchwork)
```


## Einlesen

Wir werden den Datensatz `languageR_english.csv` einlesen, der sich bereits in Ihrem `daten`-Ordner befinden sollte. Dieser Datensatz enthält Daten aus einer Benennungs- und lexikalischen Entscheidungsaufgabe in Englisch.

## CSV

Wir haben bereits gesehen, wie man die `read_()` Familie von Funktionen (`read_csv()`, `read_csv2()`, `read_delim()`, etc.) aus dem `readr` Paket aus dem `tidyverse` benutzt.

```{r filename = "tidyverse"}
df_tidy <-
  read_csv(
    here("daten", "languageR_english.csv")
  )
```

Um einen Datensatz mit kommagetrennten Werten (CSV) einzulesen, können wir die Funktion `read.csv()` verwenden, die eine Version der umfassenderen Funktion `read.table()` aus dem Paket `utils` ist. Das `utils`-Paket ist ein Standard-Installationspaket in R, so wie einige Anwendungen bereits installiert sind, wenn man ein neues Telefon kauft.

```{r filename = "Base R"}
df_base <-
  read.csv(
    here("daten", "languageR_english.csv")
  )
```

Das erste, was Ihnen vielleicht auffällt, ist, dass wir beim Ausführen von `read_csv()` eine Meldung erhalten haben, die uns die Anzahl der Zeilen und Spalten in den Daten, das verwendete Trennzeichen (bei `read_csv()` immer ein Komma) und den Datentyp, zu dem unsere Variablen gehören, mitteilt. Hier haben wir gesehen, dass wir drei Zeichenvariablen (`chr`) und vier numerische Variablen (`dbl` für "double") haben. Bei der Verwendung von `read.csv()` erhalten wir keine derartige Meldung. Im Allgemeinen ist Tidyverse ein besserer Gesprächspartner als Base R. Sie erhalten mehr Meldungen, und die Warn- oder Fehlermeldungen sind anschaulicher.

Ein weiterer Unterschied zwischen diesen beiden Funktionen ist die Art und Weise, wie sie `read` und `csv` trennen: tidyverse verwendet typischerweise `_`, um Wörter zu trennen, während Base R dazu neigt, eine Mischung aus `.` und `_` zu verwenden. Dies geht auf die Prinzipien von tidyverse zurück, in denen versucht wird, konsistente Konventionen beizubehalten, um sauberen Code und saubere Daten zu fördern. Dazu gehört auch die konsequente Verwendung von `_" in Funktions- und Variablennamen.

Schauen wir uns nun die beiden Objekte an, die wir jetzt haben. Wie viele Spalten haben sie?

```{r}
length(df_tidy)
```

```{r}
length(df_base)
```

Beide haben `r length(df_base)` Spalten. Wie lauten die Namen dieser Spalten?

```{r}
names(df_base)
```

```{r}
names(df_tidy)
```

Sie haben auch die gleichen Namen, so weit, so gut. Wie viele Zeilen gibt es in jedem?

```{r}
nrow(df_tidy)
```

```{r}
nrow(df_base)
```

Beide haben `r nrow(df_base)` Zeilen. Die Datenstruktur ist also identisch.

## Andere Begrenzungszeichen

Erinnern Sie sich, dass wir mit dem tidyverse-Paket `readr` `read_delim(delim = "")` verwenden können, um das Trennzeichen explizit zu definieren. Hier verwenden wir `delim = ","`, weil wir immer noch eine kommagetrennte Wertedatei verwenden. 

```{r filename = "tidyverse"}
df_tidy <-
  read_delim(
    here("daten", "languageR_english.csv"),
    delim = ","
  )
```

Wir können dies mit `read.table(sep = "")` aus dem Paket `utils` tun.

```{r filename = "Base R"}
df_base <-read.table(
    here("daten", "languageR_english.csv"),
    sep = ",",
    header = TRUE
  )
```

::: {.callout-tip}

## Begrenzungszeichen und Trennzeichen

Versuchen Sie, das Trennzeichen in den obigen Code-Blöcken durch ein Semikolon (`;`) zu ersetzen. Was ändert sich, und warum? Ändern Sie es wieder in ein Komma und führen Sie es erneut aus, bevor Sie fortfahren.

:::

## Datenrahmen versus Tibbles

Daten, die mit tidyverse eingelesen werden, werden als Tibble gespeichert, das als eine aufgeräumtere Version eines Datenrahmens gilt. Wichtig ist, dass die Struktur eines Tibbles und die darin enthaltenen Informationen mit denen eines Datenrahmens identisch sind. Im Folgenden werden wir einige Unterschiede zwischen Tibbles und Datenrahmen sehen. 


# Umgang mit Spalten und Zeilen

Wir sind bereits mit einer Reihe von `dplyr`-Verben vertraut, die zum Manipulieren, Filtern und Extrahieren von Zeilen und Spalten verwendet werden. Jetzt sehen wir uns alternative Wege an, um die gleichen Ergebnisse mit Base R zu erzielen.

## Variablen extrahieren

Wir sind bereits vertraut mit `select()` aus `dplyr`:

```{r filename = "tidyverse"}
#| eval: false
df_tidy |> 
  select(AgeSubject)
```

```{r filename = "tidyverse"}
#| echo: false
df_tidy |> 
  select(AgeSubject) |> 
  head(10)
```

In Base R können wir ein Dollarzeichen (`$`) verwenden, um eine Spalte aus einem Datenrahmen (oder Tibble) zu extrahieren. Dadurch erhalten wir einen Vektor, während `dplyr::select()` die Datenrahmen-/Tibble-Attribute der Spalte beibehält.

```{r filename = "Base R"}
#| eval: false
df_base$AgeSubject
```

```{r filename = "Base R"}
#| echo: false
head(df_base$AgeSubject,18)
```

Alternativ kann man auch `dataframe[row,column]` verwenden, um Zeilen und Spalten zu definieren. Wir können den Namen einer Spalte in Anführungszeichen verwenden oder den Index der Spalte angeben, wobei 1 für die erste Spalte steht, 2 für die zweite Spalte usw. Wir konzentrieren uns zunächst auf die Spalten, geben also nicht an, welche Zeile wir wollen, sondern geben alle Zeilen dieser Spalte aus.

```{r filename = "Base R"}
#| eval: false
# using variable name
df_base[,"AgeSubject"]
```

```{r}
#| echo: false
# using variable name
head(df_base[,"AgeSubject"],18)
```

```{r filename = "Base R"}
#| eval: false
# using variable index
df_base[,1]
```

```{r}
#| echo: false
# using variable index
head(df_base[,1],18)
```

Ein Hauptunterschied zwischen der Verwendung von tidyverse und Base R zum Extrahieren einer einzelnen Variablen besteht darin, dass Base R einen Vektor extrahiert, während das tidyverse-Verb `select()` die Variable als Tibble behält. Beachten Sie, dass es auch möglich ist, mehrere Variablen mit der Funktion `select()` auszuwählen. Sie können dies auch mit Base R tun, aber Sie müssen die Funktion `c()` verwenden.

```{r filename = "tidyverse"}
#| eval: false
df_tidy |> 
  select(AgeSubject, RTlexdec)
```

```{r}
#| echo: false
df_tidy |> 
  select(AgeSubject, RTlexdec) |> 
  head(10)
```

```{r filename = "Base R"}
#| eval: false
# using variable name
df_base[,c("AgeSubject", "RTlexdec")]
```

```{r}
#| echo: false
# using variable name
df_base[,c("AgeSubject", "RTlexdec")] |> 
  head(10)
```


```{r filename = "Base R"}
#| eval: false
# using variable index
df_base[,c(1, 6)]
```

```{r}
#| echo: false
# using variable index
df_base[,c(1, 6)] |>  head(10)
```

### Mischen von Tibbles und Datenrahmen

Die Ausgabe dieser Operationen hängt nicht nur davon ab, ob Sie eine Tidyverse- oder eine R-Basisfunktion verwenden. Es macht auch einen Unterschied, ob die Daten ein Datenrahmen oder ein Tibble sind. Versuchen wir, die Funktion `select()` von tidyverse auf einen Datenrahmen anzuwenden:

```{r filename = "tidyverse"}
#| eval: false
df_base |> 
  select(AgeSubject)
```

```{r}
#| echo: false
df_tidy |> 
  select(AgeSubject) |> 
  head(10)
```

Base R behandelt Tibbles jedoch genauso wie Datenrahmen und gibt einen Vektor mit allen Werten einer einzelnen Spalte aus.

```{r filename = "Base R"}
#| eval: false
df_tidy$AgeSubject
```

```{r}
#| echo: false
head(df_tidy$AgeSubject, 10)
```

Dies sollte keine Folgen haben, aber es ist wichtig, die innere Struktur Ihrer Daten zu verstehen, damit Sie entsprechend damit arbeiten können.

## Beobachtungen extrahieren/filtern

Wir haben bereits die Funktion `filter()` von `dplyr` gesehen, die Zeilen extrahiert, die logischen Bedingungen entsprechen.

```{r filename = "tidyverse"}
df_tidy |> 
  filter(RTlexdec > 600 & RTnaming < 480)
```

Wir können diese bedingten Anweisungen in `[,]` einfügen, wobei zu beachten ist, dass die Zeilen vor dem Komma und die Spalten nach dem Komma angegeben werden. Wir lassen die Spaltenangabe leer, d. h. wir wollen alle Spalten ausgeben. Wichtig ist, dass wir in den bedingten Anweisungen den Namen des Datenrahmens mit dem Dollarzeichen vor dem Spaltennamen angeben.

```{r filename = "Base R"}
#| eval: false
df_base[df_base$RTlexdec > 600 & df_base$RTnaming < 480,]
```

```{r}
#| echo: false
df_base[df_base$RTlexdec > 600 & df_base$RTnaming < 480,] |> 
  head(10)
```


## Einzelne Datenpunkte auswählen

Wir können bestimmte Zeilen und bestimmte Spalten auf einmal extrahieren. Wenn wir zum Beispiel die relevanten Zeilen wie oben ausgeben wollen, aber nur die Spalten `AgeSubject` und `RTlexdec`, können wir dies mit `filter()` und `select()` tun (was wir bereits zuvor getan haben).

```{r filename = "tidyverse"}
#| eval: false
df_tidy |> 
  filter(RTlexdec > 600, RTnaming < 480) |> 
  select(AgeSubject, RTlexdec)
```

```{r}
#| echo: false
df_tidy |> 
  filter(RTlexdec > 600, RTnaming < 480) |> 
  select(AgeSubject, RTlexdec) |> 
  head(10)
```

In Base R würden wir dies einfach in `[,]` einfügen. Dadurch erhalten wir keinen Vektor mehr, sondern die Datenrahmenstruktur bleibt erhalten. Nicht, dass wir auch die Zeilennummern erhalten.

```{r filename = "Base R"}
#| eval: false
df_base[df_base$RTlexdec > 600 & df_base$RTnaming < 480,c("AgeSubject", "RTlexdec")]
```

```{r}
#| echo: false
df_base[df_base$RTlexdec > 600 & df_base$RTnaming < 480,c("AgeSubject", "RTlexdec")] |> 
  head(10)
```

Auch hier können Sie die Spaltennamen durch den Indexwert ersetzen.

```{r filename = "Base R"}
#| eval: false
df_base[df_base$RTlexdec > 600 & df_base$RTnaming < 480,c(1, 6)]
```

```{r}
#| echo: false
df_base[df_base$RTlexdec > 600 & df_base$RTnaming < 480,c(1, 6)] |> 
  head(10)
```

## Neue Variablen erstellen

Wir haben gelernt, wie man mit der Funktion `mutate()`, die ebenfalls aus `dplyr` stammt, neue Variablen erstellt oder bestehende Variablen ändert.

```{r filename = "tidyverse"}
df_tidy |> 
  mutate(rt_lexdec_s = RTlexdec/1000)
```

In Base R geschieht dies, indem wir den Namen der neuen Variablen definieren und ihr mit dem Zuweisungsoperator `<-` einen Wert zuweisen.

```{r filename = "Base R"}
df_base$rt_lexdec_s <- df_base$RTlexdec/1000
```

## Zusammenfassen

Als Letztes wollen wir lernen, wie man in Base R zusammenfasst. Das ist nicht einfach, wenn man eine Gruppe hat, deshalb werden wir das nicht behandeln. 

```{r, filename = "tidyverse"}
  df_tidy |> 
  summarise(
    mean_lexdec = mean(RTlexdec),
    sd_lexdec = sd(RTlexdec),
    mean_naming = mean(RTnaming, na.rm = T),
    sd_naming = sd(RTnaming, na.rm = T)
  )
```

In Base R müssen wir neue Objekte erstellen, die den Wert jeder Operation enthalten, und sie mit der Funktion "data.frame()" zu einem Datenrahmen zusammenfassen.

```{r, filename = "Base R"}
data.frame(mean_lexdec = mean(df_base$RTlexdec),
           sd_lexdec = sd(df_base$RTlexdec),
           mean_naming = mean(df_base$RTnaming, na.rm = T),
           sd_naming = sd(df_base$RTnaming, na.rm = T))
```

# Pipes

Lange Zeit waren Pipes ein Feature des Tidyverse, mit der `%>%` Pipe aus dem `magrittr` Paket. Seit 2023 bietet R eine native Pipe `|>`. Sie haben vielleicht schon beide Versionen gesehen (ich tendiere dazu, `|>` zu benutzen). Für unsere Zwecke sind sie austauschbar, aber es gibt wichtige Unterschiede für komplexere Fälle, die wir nicht behandeln werden.


```{r filename = "tidyverse"}
df_base$RTlexdec |> 
  mean()
```

```{r filename = "Base R"}
df_base$RTlexdec %>%
  mean()
```

# Plots

`ggplot2` ist auch bei Leuten beliebt, die sonst nicht die tidyverse-Paketfamilie nutzen. Das liegt daran, dass es einige nützliche Funktionen und ein sauberes Aussehen hat. 

Das Plotten mit Base R kann auch sehr praktisch sein, wenn man einfache Diagramme erstellen will, um einen ersten Blick auf die Daten zu bekommen. Die nützlichsten Funktionen sind `hist()` und `plot()`, die jeweils Histogramme und Streudiagramme erzeugen. Beachten Sie, dass diese Funktionen mit Vektoren arbeiten, weswegen wir `$` verwenden müssen, um die Spalten aus dem Datenrahmen zu extrahieren.

::: {.content-visible when-format="html"}

```{r, filename = "Base R"}
#| fig-width: 4
#| fig-asp: 1
#| dev: png
#| layout-ncol: 2
#| label: fig-baser
#| fig-cap: Histogram and scatterplot with Base R

# left
hist(df_base$RTlexdec)
# right
plot(df_base$RTlexdec, df_base$RTnaming) 
```
:::

::: {.content-visible when-format="pdf"}
```{r, filename = "Base R histogram"}
#| fig-width: 4
#| fig-asp: 1.1
#| label: fig-baser-hist
#| fig-cap: Histogram with Base R

# histogram
hist(df_base$RTlexdec)
```

```{r, filename = "Base R histogram"}
#| fig-width: 4
#| fig-asp: 1.1
#| label: fig-baser-scatter
#| fig-cap: Scatterplot with Base R

# scatterplot
plot(df_base$RTlexdec, df_base$RTnaming)
```


:::

To achieve the same thing with the tidyverse:

```{r, filename = "tidyverse"}
#| eval: false

# histogram
df_base |> 
  ggplot() +
  aes(x = RTlexdec) +
  geom_histogram()

# scatter plot
  df_base |> 
  ggplot() +
  aes(x = RTlexdec, y = RTnaming) +
  geom_point() 
```

```{r}
#| fig-width: 8
#| fig-asp: .5
#| dev: png
#| label: fig-ggplot
#| fig-cap: Histogram and scatterplot with ggplot2
#| echo: false
# histogram
df_base |> 
  ggplot() +
  aes(x = RTlexdec) +
  geom_histogram() +
# scatter plot
  df_base |> 
  ggplot() +
  aes(x = RTlexdec, y = RTnaming) +
  geom_point() +
  plot_annotation(tag_levels = "A")
```




# Lernziele 🏁 {.unnumbered .unlisted}

In diesem Kapitel werden wir...

- lernen, was Base R ist ✅
- Base R und Tidyverse vergleichen ✅
- die Base-R-Äquivalente der Tidyverse-Verben kennenlernen ✅

# Weitere Übungen {.unnumbered}

Weitere Übungen zu diesem Kapitel finden Sie in @sec-app_baseR

# Session Info {.unnumbered}

```{r}
#| eval: false
#| echo: false
RStudio.Version()$version
```


Hergestellt mit `r R.version.string` (`r R.version$nickname`) und RStudioversion 2023.9.0.463 (Desert Sunflower).

```{r}
print(sessionInfo(),locale = F)
```