R Code [zeigen / verbergen]
<- read_excel("data/flea_dog_cat_fox.xlsx") flea_tbl
Letzte Änderung am 21. August 2024 um 14:48:54
“The only way to learn a new programming language is by writing programs in it.” — Dennis Ritchie
Wir haben in dem vorherigen Kapitel Daten eingelesen. Jetzt wollen wir die Daten aufräumen (eng. tidy). Es ist notwendig, dass wir die Daten so aufarbeiten, dass R damit umgehen kann. Insbesondere das Erstellen von Faktoren ist wichtig, wenn die Spalte ein Faktor ist. R muss wissen was für Eigenschaften eine Spalte hat. Sonst funktionieren spätere Anwendungen in R nicht richtig oder geben einen Fehler wieder. Es gibt nun aber verschiedene Möglichkeiten wie du mit deinen Daten umgehst. Dabei sind alle gleichwertig. Wichtig ist, dass es für dich funktioniert.
select()
, filter()
und mutate()
nutzen. Dann kannst du hier nochmal schauen, was die Funktionen machen. Ich nutze die Funktionen viel in meinen Videos und auch in den Vorlesungen.Im Folgenden wollen wir den Datensatz flea_tbl
in R bearbeiten. Das heißt wir wollen Spalten auswählen mit select()
oder Zeilen auswählen mit filter()
. Schlussendlich wollen wir auch die Eigenschaften von Spalten mit der Funktion mutate()
ändern. Wir laden also den Datensatz flea_dog_cat.xlsx
einmal in R.
<- read_excel("data/flea_dog_cat_fox.xlsx") flea_tbl
Es ergibt sich folgende Datentabelle, die wir schon aus vorherigen Kapiteln kennen.
animal
gibt an, welche Flohspezies gemessen wurde. Die Tabelle ist im Long-Format dargestellt.
animal | jump_length | flea_count | weight | grade | infected |
---|---|---|---|---|---|
dog | 5.7 | 18 | 2.1 | 8 | 0 |
dog | 8.9 | 22 | 2.3 | 8 | 1 |
dog | 11.8 | 17 | 2.8 | 6 | 1 |
dog | 5.6 | 12 | 2.4 | 8 | 0 |
dog | 9.1 | 23 | 1.2 | 7 | 1 |
dog | 8.2 | 18 | 4.1 | 7 | 0 |
dog | 7.6 | 21 | 3.2 | 9 | 0 |
cat | 3.2 | 12 | 1.1 | 7 | 1 |
cat | 2.2 | 13 | 2.1 | 5 | 0 |
cat | 5.4 | 11 | 2.4 | 7 | 0 |
cat | 4.1 | 12 | 2.1 | 6 | 0 |
cat | 4.3 | 16 | 1.5 | 6 | 1 |
cat | 7.9 | 9 | 3.7 | 6 | 0 |
cat | 6.1 | 7 | 2.9 | 5 | 0 |
fox | 7.7 | 21 | 3.1 | 5 | 1 |
fox | 8.1 | 25 | 4.2 | 4 | 1 |
fox | 9.1 | 31 | 5.1 | 4 | 1 |
fox | 9.7 | 12 | 3.5 | 5 | 1 |
fox | 10.6 | 28 | 3.2 | 4 | 0 |
fox | 8.6 | 18 | 4.6 | 4 | 1 |
fox | 10.3 | 19 | 3.7 | 3 | 0 |
Wir wollen folgende R Pakete in diesem Kapitel nutzen.
::p_load(tidyverse, readxl, magrittr, janitor) pacman
An der Seite des Kapitels findest du den Link Quellcode anzeigen, über den du Zugang zum gesamten R-Code dieses Kapitels erhältst.
select()
Der Datensatz, den wir im Experiment erschaffen, ist meist riesig. Jetzt könnten wir natürlich eine Exceltabelle mit unterschiedlichen Sheets bzw. Reitern erstellen oder aber die Spalten die wir brauchen in R selektieren. Wir nutzen die Funktion select()
um Spalten zu wählen. In der folgenden Abbildung dann einmal die Analogie für select()
anhand des Kleiderschranks.
Im folgenden Codeblock wählen wir die Spalten animal
, jump_length
und flea_count
.
|>
flea_tbl select(animal, jump_length, flea_count)
# A tibble: 21 × 3
animal jump_length flea_count
<chr> <dbl> <dbl>
1 dog 5.7 18
2 dog 8.9 22
3 dog 11.8 17
4 dog 5.6 12
5 dog 9.1 23
6 dog 8.2 18
7 dog 7.6 21
8 cat 3.2 12
9 cat 2.2 13
10 cat 5.4 11
# ℹ 11 more rows
Mit einem -
vor einer Variable können wir auch Variablen entfernen. Meistens nutze ich die positive Auswahl, da ich dann weiß, was in den Datensatz selektiert wurde und ich mir selten merken kann, was noch drin ist. Manchmal aber nützlich um die ID
oder sonst was zu entfernen.
|>
flea_tbl select(-animal, -jump_length, -flea_count)
# A tibble: 21 × 3
weight grade infected
<dbl> <dbl> <dbl>
1 2.1 8 0
2 2.3 8 1
3 2.8 6 1
4 2.4 8 0
5 1.2 7 1
6 4.1 7 0
7 3.2 9 0
8 1.1 7 1
9 2.1 5 0
10 2.4 7 0
# ℹ 11 more rows
Wir können die Spalten beim Selektieren auch Umbenennen und in eine andere Reihenfolge bringen. Manchmal sehr praktisch, da wir dann nicht nochmal die Funktion rename()
nutzen müssen.
|>
flea_tbl select(Sprungweite = jump_length, flea_count, animal)
# A tibble: 21 × 3
Sprungweite flea_count animal
<dbl> <dbl> <chr>
1 5.7 18 dog
2 8.9 22 dog
3 11.8 17 dog
4 5.6 12 dog
5 9.1 23 dog
6 8.2 18 dog
7 7.6 21 dog
8 3.2 12 cat
9 2.2 13 cat
10 5.4 11 cat
# ℹ 11 more rows
Du findest auf der englischen Hilfeseite für select() noch weitere Beispiele für die Nutzung.
filter()
Während wir die Auswahl an Spalten gut und gerne auch in Excel durchführen können, so ist dies bei der Auswahl der Zeilen nicht so einfach. Wir können in R hier auf die Funktion filter()
zurückgreifen. Wir nutzen die Funktion filter()
um Zeilen nach Kriterien zu wählen. In der folgenden Abbildung dann einmal die Analogie für filter()
anhand des Kleiderschranks.
Im folgenden Codeblock wählen wir die Zeilen aus in denen die Worte dog
und fox
stehen. Wir nutzen dazu den Operator %in%
um auszudrücken, dass wir alle Einträge in der Spalte animal
wollen die in dem Vektor c("dog", "fox")
beschrieben sind.
|>
flea_tbl filter(animal %in% c("dog", "fox"))
# A tibble: 14 × 6
animal jump_length flea_count weight grade infected
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 dog 5.7 18 2.1 8 0
2 dog 8.9 22 2.3 8 1
3 dog 11.8 17 2.8 6 1
4 dog 5.6 12 2.4 8 0
5 dog 9.1 23 1.2 7 1
6 dog 8.2 18 4.1 7 0
7 dog 7.6 21 3.2 9 0
8 fox 7.7 21 3.1 5 1
9 fox 8.1 25 4.2 4 1
10 fox 9.1 31 5.1 4 1
11 fox 9.7 12 3.5 5 1
12 fox 10.6 28 3.2 4 0
13 fox 8.6 18 4.6 4 1
14 fox 10.3 19 3.7 3 0
Es stehen dir Folgende logische Operatoren zu Verfügung wie in Tabelle 12.2 gezeigt. Am Anfang ist es immer etwas schwer sich in den logischen Operatoren zurechtzufinden. Daher kann ich dir nur den Tipp geben einmal die Operatoren selber auszuprobieren und zu schauen, was du da so raus filterst.
Logischer Operator | Beschreibung |
---|---|
< | kleiner als (eng. less than) |
<= | kleiner als oder gleich (eng. less than or equal to) |
> | größer als (eng. greater than) |
>= | größer als oder gleich (eng. greater than or equal to) |
== | exact gleich (eng. exactly equal to) |
!= | nicht gleich (eng. not equal to) |
!x | nicht (eng. not x) |
x | y | oder (eng. x or y) |
x & y | und (eng. x and y) |
Hier ein paar Beispiele. Probiere gerne auch mal Operatoren selber aus. Im folgenden Codeblock wollen wir nur die Zeilen haben, die eine Anzahl an Flöhen größer von 15 haben.
|>
flea_tbl filter(flea_count > 15)
# A tibble: 13 × 6
animal jump_length flea_count weight grade infected
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 dog 5.7 18 2.1 8 0
2 dog 8.9 22 2.3 8 1
3 dog 11.8 17 2.8 6 1
4 dog 9.1 23 1.2 7 1
5 dog 8.2 18 4.1 7 0
6 dog 7.6 21 3.2 9 0
7 cat 4.3 16 1.5 6 1
8 fox 7.7 21 3.1 5 1
9 fox 8.1 25 4.2 4 1
10 fox 9.1 31 5.1 4 1
11 fox 10.6 28 3.2 4 0
12 fox 8.6 18 4.6 4 1
13 fox 10.3 19 3.7 3 0
Wir wollen nur die infizierten Tiere haben.
|>
flea_tbl filter(infected == TRUE)
# A tibble: 10 × 6
animal jump_length flea_count weight grade infected
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 dog 8.9 22 2.3 8 1
2 dog 11.8 17 2.8 6 1
3 dog 9.1 23 1.2 7 1
4 cat 3.2 12 1.1 7 1
5 cat 4.3 16 1.5 6 1
6 fox 7.7 21 3.1 5 1
7 fox 8.1 25 4.2 4 1
8 fox 9.1 31 5.1 4 1
9 fox 9.7 12 3.5 5 1
10 fox 8.6 18 4.6 4 1
Wir wollen nur die infizierten Tiere haben UND die Tiere mit einer Flohanzahl größer als 20.
|>
flea_tbl filter(infected == TRUE & flea_count > 20)
# A tibble: 5 × 6
animal jump_length flea_count weight grade infected
<chr> <dbl> <dbl> <dbl> <dbl> <dbl>
1 dog 8.9 22 2.3 8 1
2 dog 9.1 23 1.2 7 1
3 fox 7.7 21 3.1 5 1
4 fox 8.1 25 4.2 4 1
5 fox 9.1 31 5.1 4 1
Du findest auf der englischen Hilfeseite für filter() noch weitere Beispiele für die Nutzung.
mutate()
Nachdem wir die Spalten mit select()
und eventuell die Zeilen mit filter()
gewählt haben müssen wir jetzt noch die Eigenschaften der Spalten ändern. Das Ändern müssen wir nicht immer durchführen, aber häufig müssen wir noch einen Faktor erschaffen. Wir nutzen noch die Funktion pull()
um uns die Spalte animal
aus dem Datensatz zu ziehen. Nur so sehen wir die vollen Eigenschaften des Faktors. Später nutzen wir pull
seltener und nur um zu kontrollieren, was wir gemacht haben. In der folgenden Abbildung dann einmal die Analogie für filter()
anhand des Kleiderschranks.
Wir nutzen die Funktion mutate()
um die Eigenschaften von Spalten daher Variablen zu ändern. Die Reihenfolge der Funktionen ist wichtig um unliebsame Effekte zu vermeiden.
select()
filter()
mutate()
Im folgenden Codeblock verwandeln wir die Variable animal
in einen Faktor durch die Funktion as_factor
. Wir sehen, dass die Level des Faktors so sortiert sind, wie das Auftreten in der Spalte animal
.
|>
flea_tbl mutate(animal = as_factor(animal)) |>
pull(animal)
[1] dog dog dog dog dog dog dog cat cat cat cat cat cat cat fox fox fox fox fox
[20] fox fox
Levels: dog cat fox
Wollen wir die Sortierung der Level ändern, können wir die Funktion factor()
nutzen. Wir ändern die Sortierung des Faktors zu fox
, dog
und cat
.
|>
flea_tbl mutate(animal = factor(animal, levels = c("fox", "dog", "cat"))) |>
pull(animal)
[1] dog dog dog dog dog dog dog cat cat cat cat cat cat cat fox fox fox fox fox
[20] fox fox
Levels: fox dog cat
Wir können auch die Namen (eng. labels) der Level ändern. Hier musst du nur aufpassen wie du die alten Labels überschreibst. Wenn ich gleichzeitig die Level und die Labels ändere komme ich häufig durcheinander. Da muss du eventuell nochmal schauen, ob auch alles so geklappt hat wie du wolltest.
|>
flea_tbl mutate(animal = factor(animal, labels = c("Hund", "Katze", "Fuchs"))) |>
pull(animal)
[1] Katze Katze Katze Katze Katze Katze Katze Hund Hund Hund Hund Hund
[13] Hund Hund Fuchs Fuchs Fuchs Fuchs Fuchs Fuchs Fuchs
Levels: Hund Katze Fuchs
Du findest auf der englischen Hilfeseite für mutate() noch weitere Beispiele für die Nutzung. Insbesondere die Nutzung von mutate()
über mehrere Spalten gleichzeitig erlaubt sehr effiezientes Programmieren. Aber das ist für den Anfang etwas viel.
Bitte schaue dir auch die Hilfeseiten der Funktionen an. In diesem Skript kann ich nicht alle Funktionalitäten der Funktionen zeigen. Oder du kommst in das R Tutorium welches ich anbiete und fragst dort nach den Möglichkeiten Daten in R zu verändern.
group_by()
Sobald wir einen Faktor erschaffen haben, können wir die Daten in R auch nach dem Faktor gruppieren. Das heißt wir nutzen die Funktion group_by()
um R mitzuteilen, dass nun folgende Funktionen getrennt für die einzelen Gruppen erfolgen sollen. Im folgenden Codeblock siehst du die Anwendung.
|>
flea_tbl mutate(animal = as_factor(animal)) |>
group_by(animal)
# A tibble: 21 × 6
# Groups: animal [3]
animal jump_length flea_count weight grade infected
<fct> <dbl> <dbl> <dbl> <dbl> <dbl>
1 dog 5.7 18 2.1 8 0
2 dog 8.9 22 2.3 8 1
3 dog 11.8 17 2.8 6 1
4 dog 5.6 12 2.4 8 0
5 dog 9.1 23 1.2 7 1
6 dog 8.2 18 4.1 7 0
7 dog 7.6 21 3.2 9 0
8 cat 3.2 12 1.1 7 1
9 cat 2.2 13 2.1 5 0
10 cat 5.4 11 2.4 7 0
# ℹ 11 more rows
Auf den ersten Blick ändert sich nicht viel. Es entsteht aber die Zeile # Groups: animal [3]
. Wir wissen nun, dass wir nach der Variable animal
mit drei Gruppen die Datentabelle gruppiert haben.
glimpse()
und str()
Am Ende noch zwei Funktionen zur Kontrolle, was wir hier eigentlich gerade tun. Mit der Funktion glimpse()
können wir uns einen Einblick in die Daten geben lassen. Wir sehen dann nochmal kurz und knapp wieviel Zeieln und Spalten wir haben und welche Inhalte in den Spalten stehen. Die gleichen Informationen erhalten wir auch durch die Funktion str()
. Die Funktion str()
geht aber noch einen Schritt weiter und nennt uns auch Informationen zu dem Objekt. Daher wir wissen jetzt, dass es sich beim dem Objekt flea_tbl
um ein tibble()
handelt.
glimpse(flea_tbl)
Rows: 21
Columns: 6
$ animal <chr> "dog", "dog", "dog", "dog", "dog", "dog", "dog", "cat", "c…
$ jump_length <dbl> 5.7, 8.9, 11.8, 5.6, 9.1, 8.2, 7.6, 3.2, 2.2, 5.4, 4.1, 4.…
$ flea_count <dbl> 18, 22, 17, 12, 23, 18, 21, 12, 13, 11, 12, 16, 9, 7, 21, …
$ weight <dbl> 2.1, 2.3, 2.8, 2.4, 1.2, 4.1, 3.2, 1.1, 2.1, 2.4, 2.1, 1.5…
$ grade <dbl> 8, 8, 6, 8, 7, 7, 9, 7, 5, 7, 6, 6, 6, 5, 5, 4, 4, 5, 4, 4…
$ infected <dbl> 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1…
str(flea_tbl)
tibble [21 × 6] (S3: tbl_df/tbl/data.frame)
$ animal : chr [1:21] "dog" "dog" "dog" "dog" ...
$ jump_length: num [1:21] 5.7 8.9 11.8 5.6 9.1 8.2 7.6 3.2 2.2 5.4 ...
$ flea_count : num [1:21] 18 22 17 12 23 18 21 12 13 11 ...
$ weight : num [1:21] 2.1 2.3 2.8 2.4 1.2 4.1 3.2 1.1 2.1 2.4 ...
$ grade : num [1:21] 8 8 6 8 7 7 9 7 5 7 ...
$ infected : num [1:21] 0 1 1 0 1 0 0 1 0 0 ...