Das Paket dplyr aus dem tidyverse stellt Funktionen vor, die einige der häufigsten Operationen bei der Arbeit mit Datenrahmen durchführen, und verwendet für diese Funktionen Namen, die relativ leicht zu merken sind. Um zum Beispiel die Datentabelle durch Hinzufügen einer neuen Spalte zu verändern, verwenden wir mutate. Um die Datentabelle auf eine Teilmenge von Zeilen zu filtern, verwenden wir filter. Um schließlich die Daten durch die Auswahl bestimmter Spalten zu unterteilen, verwenden wir select.
Hinzufügen einer Spalte mit mutate
Wir möchten, dass alle für unsere Analyse erforderlichen Informationen in die Datentabelle aufgenommen werden. Die erste Aufgabe besteht also darin, die Mordraten zu unserem Datenrahmen für Morde hinzuzufügen. Die Funktion mutate nimmt den Datenrahmen als erstes Argument und den Namen und die Werte der Variablen als zweites Argument unter Verwendung der Konvention name = values. Um also die Mordraten hinzuzufügen, verwenden wir:
library(dslabs)
data("murders")
murders <- mutate(murders, rate = total / population * 100000)
Beachten Sie, dass wir in der Funktion total und population verwendet haben, also Objekte, die in unserem Arbeitsbereich nicht definiert sind. Aber warum erhalten wir keine Fehlermeldung?
Dies ist eine der Hauptfunktionen von dplyr. Funktionen in diesem Paket, wie mutate, wissen, dass sie nach Variablen in dem im ersten Argument angegebenen Datenrahmen suchen müssen. In dem obigen Aufruf von mutate hat total die Werte in murders$total. Dieser Ansatz macht den Code viel lesbarer.
Wir können sehen, dass die neue Spalte hinzugefügt wird:
head(murders)
#> state abb region population total rate
#> 1 Alabama AL South 4779736 135 2.82
#> 2 Alaska AK West 710231 19 2.68
#> 3 Arizona AZ West 6392017 232 3.63
#> 4 Arkansas AR South 2915918 93 3.19
#> 5 California CA West 37253956 1257 3.37
#> 6 Colorado CO West 5029196 65 1.29
Obwohl wir das ursprüngliche murders Objekt überschrieben haben, wird das Objekt, das mit den data(murders) geladen wurde, dadurch nicht verändert. Wenn wir die murders Daten erneut laden, wird das Original unsere veränderte Version überschreiben.
Unterteilung mit filter-Befehl
Nehmen wir nun an, dass wir die Datentabelle so filtern wollen, dass nur die Einträge angezeigt werden, bei denen die Mordrate kleiner als 0,71 ist. Dazu verwenden wir die filter() Funktion, die als erstes Argument die Datentabelle und als zweites Argument die bedingte Anweisung erhält. Wie bei mutate können wir die nicht in Anführungszeichen gesetzten Variablennamen von murders innerhalb der Funktion verwenden, und sie weiß, dass wir die Spalten und nicht die Objekte im Arbeitsbereich meinen.
filter(murders, rate <= 0.71)
#> state abb region population total rate
#> 1 Hawaii HI West 1360301 7 0.515
#> 2 Iowa IA North Central 3046355 21 0.689
#> 3 New Hampshire NH Northeast 1316470 5 0.380
#> 4 North Dakota ND North Central 672591 4 0.595
#> 5 Vermont VT Northeast 625741 2 0.320
Auswählen von Spalten mit select
Obwohl unsere Datentabelle nur sechs Spalten hat, enthalten manche Datentabellen Hunderte. Wenn wir nur einige wenige anzeigen möchten, können wir die dplyr select()-Funktion verwenden. Im folgenden Code wählen wir drei Spalten aus, weisen diese einem neuen Objekt zu und filtern dann das neue Objekt:
new_table <- select(murders, state, region, rate)
filter(new_table, rate <= 0.71)
#> state region rate
#> 1 Hawaii West 0.515
#> 2 Iowa North Central 0.689
#> 3 New Hampshire Northeast 0.380
#> 4 North Dakota North Central 0.595
#> 5 Vermont Northeast 0.320
Beim Aufruf von select ist das erste Argument murders ein Objekt, aber state, region und rate sind Variablennamen.
Expertentrick: Pipe %>%
In R können wir eine Reihe von Operationen durchführen, z. B. auswählen und dann filtern, indem wir die Ergebnisse einer Funktion an eine andere senden, indem wir den sogenannten Pipe-Operator verwenden: %>%. Seit R Version 4.1.0 können Sie auch |> verwenden. Einige Details sind unten aufgeführt.
Wir haben den obigen Code geschrieben, um drei Variablen (Staat, Region, Rate) für Staaten anzuzeigen, deren Mordrate unter 0,71 liegt. Zu diesem Zweck haben wir das Zwischenobjekt new_table definiert. In dplyr können wir Code schreiben, der eher wie eine Beschreibung dessen aussieht, was wir ohne Zwischenobjekte tun wollen:
original data → select → filter
Für eine solche Operation können wir die Pipe %>% verwenden. Der Code sieht wie folgt aus:
murders %>% select(state, region, rate) %>% filter(rate <= 0.71)
#> state region rate
#> 1 Hawaii West 0.515
#> 2 Iowa North Central 0.689
#> 3 New Hampshire Northeast 0.380
#> 4 North Dakota North Central 0.595
#> 5 Vermont Northeast 0.320
Diese Codezeile entspricht den beiden obigen Codezeilen. Was geht hier vor?
Im Allgemeinen sendet die Pipe das Ergebnis der linken Seite der Pipe an das erste Argument der Funktion auf der rechten Seite der Pipe. Hier ist ein sehr einfaches Beispiel:
16 %>% sqrt()
#> [1] 4
Wenn wir also die Pipe mit Datenrahmen und dplyr verwenden, müssen wir das erforderliche erste Argument nicht mehr angeben, da die von uns beschriebenen dplyr-Funktionen alle die Daten als erstes Argument annehmen. In dem Code, den wir geschrieben haben:
murders %>% select(state, region, rate) %>% filter(rate <= 0.71)
murders ist das erste Argument der Funktion select, und der neue Datenrahmen (früher new_table) ist das erste Argument der Funktion filter.
Beachten Sie, dass die Pipe gut mit Funktionen funktioniert, bei denen das erste Argument die Eingabedaten sind. Funktionen in Tidyverse-Paketen wie dplyr haben dieses Format und können problemlos mit der Pipe verwendet werden.
Übungen
Übung 1
# Loading data
library(dslabs)
data(murders)
# Loading dplyr
library(dplyr)
# Redefine murders so that it includes a column named rate with the per 100,000 murder rates
murders <- mutate(murders, rate= total/population*100000)
Übung 2 mutate
# Note that if you want ranks from highest to lowest you can take the negative and then compute the ranks
x <- c(88, 100, 83, 92, 94)
rank(-x)
# Defining rate
rate <- murders$total/ murders$population * 100000
# Redefine murders to include a column named rank
# with the ranks of rate from highest to lowest
murders <- mutate(murders, rank(-rate))
Übung 3 select
# Load dplyr
library(dplyr)
str(murders)
# Use select to only show state names and abbreviations from murders
select(murders, state, abb)
Übung 4 filter
# Add the necessary columns
murders <- mutate(murders, rate = total/population * 100000, rank = rank(-rate))
# Filter to show the top 5 states with the highest murder rates
filter(murders, rank <6)
## Übung mit Filter with !=
# Use filter to create a new data frame no_south
no_south <- filter(murders, region != "South")
# Use nrow() to calculate the number of rows
nrow(no_south)
##Übung mit Filter 5in%
# Create a new data frame called murders_nw with only the states from the northeast and the west
murders_nw <- filter(murders, region %in% c("Northeast", "West"))
# Number of states (rows) in this category
nrow(murders_nw)
## Zwei Bedinungen Filtern
# add the rate column
murders <- mutate(murders, rate = total / population * 100000, rank = rank(-rate))
# Create a table, call it my_states, that satisfies both the conditions
my_states <- (filter(murders, rate < 1 & region %in% c("Northeast", "West")))
# Use select to show only the state name, the murder rate and the rank
select(my_states, state, rate, rank)
Übung 5 Pipe
# Load library
library(dplyr)
## Define the rate column
murders <- mutate(murders, rate = total / population * 100000, rank = rank(-rate))
# show the result and only include the state, rate, and rank columns, all in one line, in that order
murders %>% filter(rate < 1, region%in% c("Northeast", "West")) %>% select(state, rate, rank)
Übung 6 Alles in einem Befehl
# Loading the libraries
library(dplyr)
data(murders)
# Create new data frame called my_states (with specifications in the instructions)
#my_states <- murders %>% mutate(rate = total / population *1000000, rank = rank(-rate)) %>% filter(rate < 1 #& region %in% c("Northeast", "West")) %>% select(state, rate, rank)
my_states <- murders %>%
mutate(rate = total / population * 100000, rank = rank(-rate)) %>%
filter(region %in% c("Northeast", "West") & rate < 1) %>%
select(state, rate, rank)