RStudio Datensätze manipulieren mit dplyr

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)