1. Erste Schritte in R

Einführung - Was ist R-Studio?

R ist eine freie Umgebung bzw. Programmiersprache für statistische Berechnungen und Grafiken. Es erlaubt eine effektive Speicherung, Wiederholung und Modifikation von Arbeitsschritten. Dabei hält es eine Vielzahl statistischer Analysemethoden vor. R wird von einer engagierten Community stetig weiterentwickelt, vor allem durch die Verbesserungen und Erweiterungen von Bibliotheken (Packages). Die populärste integrierte Entwicklungsumgebung (IDE) und grafische Benutzeroberfläche (GUI) ist R-Studio. Der Aufbau der Programmiersprache beinhaltet Funktionen (=Verben) und Objekte (=Substantive). Mit diesen können Daten erkundet, zusammengefasst, modelliert und visualisiert werden.

Dieses erste Tutorial zielt darauf ab, grundlegende Konzepte von R vorzustellen. Obwohl es auf viele Datentypen übertragbar ist, werden die meisten Funktionalitäten anhand von Geodaten angewendet. Inspiriert wurde es von Robert J. Hijman’s Introduction to R (2019) dem an dieser Stelle unser Dank gilt!

In diesem Tutorial wird hauptsächlich das “base” Paket benötigt. Es stellt die Kernfunktionalitäten von R bereit und wird von einer Vielzahl von Paketen erweitert, die zur Beliebtheit und Vielseitigkeit von R beitragen. Weitere Pakete müssen zuerst installiert (install.packages("tidyverse")) und geladen (library(tidyverse)) werden, wenn Ihre Funktionen genutzt werden möchten.

Alle Pakete lassen sich unter der CRAN website finden. Derzeit sind >13k Pakete verfügbar, deren Anzahl stetig weiter wächst. Sie sind 18 verschiedenen Themen zugeordnet, wie beispielsweise Statistik, Geodaten, maschinelles Lernen etc. Darüber hinaus werden weitere, inoffizielle Pakete von einer überaus engagierten community, z.B. über GitHub, zur Verfügung gestellt.

Hello R-World

Einfache Anweisungen werden folgendermaßen vorgenommen (Ausführung mit Enter):

# Addition 
1 + 1
## [1] 2

# Mittelwert 
mean(c(1,6,8,3,6,9,2,5,10))
## [1] 5.555556

# Texten
"Hallo! Wie ist das Wetter?"
## [1] "Hallo! Wie ist das Wetter?"

R ist eine objektbasierte Sprache, d.h. eine Programmiersprache, die Zustände und Operationen innerhalb von “Objekten” zusammenfasst. Alle R-Anweisungen, in denen Sie Objekte anlegen bzw. eine eine Zuweisung vornehmen haben diese Form: objectName <- value

# Zuweisung vornehmen 
x <- 3 * 4
x
## [1] 12

Nutzen Sie Konventionen für die Benennung von Objekten

i_use_snake_case <- 1 
other.people.use.periods <- 2 
evenOthersUseCamelCase <- 3 

Probieren Sie die Autovervollständigung von RStudio aus. Geben Sie die ersten Zeichen ein und drücken Sie anschließend die Tab-Taste. Dies kann Ihre Arbeit deutlich erleichtern.

R hat viele eingebaute Funktionen, auf die so zugegriffen wird: functionName(arg1 = val1, arg2 = val2, usw.). Für weitere Hilfestellungen können Sie die zugehörigen Erklärungen bzw. jeweiligen Hilfsseite folgendermaßen aufrufen:

?functionName
??functionName

Abschließend gilt der folgende Staz:

There are only two hard things in Computer Science: cache invalidation and naming things. (Phil Karlton).

Deshalb empfiehlt es sich bei der Erstellung von Code bzw. Skripten auf eine einheitliche Schreibweise zu achten (s. http://adv-r.had.co.nz/Style.html)

Grundlegende Funktionen

Die folgenden Funktionen, hier am Beipiel simpler deskriptiver Statistik, sollen die Verwendung grundlegender Funktionen aufzeigen. Wenn Sie Zweifel haben, was die Funktion berechnet, verwenden Sie die Hilfeseiten (z.B. ?mean), um mehr darüber zu erfahren. Zunächst wird ein Objekt mit den Werten 1 bis 10 angelegt, danach verschiedene Funktionenen verwendet.

a <- 1:10
min(a)
## [1] 1
max(a)
## [1] 10
range(a)
## [1]  1 10
mean(a)
## [1] 5.5
median(a)
## [1] 5.5
prod(a)
## [1] 3628800
sd(a)
## [1] 3.02765

# eine praktische Funktion fasst einige der oben genannten Funktionen zusammen
summary(a)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.00    3.25    5.50    5.50    7.75   10.00

Operatoren

Die folgende Liste der Operatoren ähnelt anderen Programmiersprachen. Durch die Verwendung eines Operators weisen Sie R an, eine bestimmte Aufgabe auszuführen. Die Operatoren von R (eine Funktion, die ein oder zwei Argumente benötigt und ohne Klammern geschrieben werden kann) sind entweder arithmetisch oder logisch.

Arithmetische Operatoren

Operator Description
+ addition
- subtraction
* multiplication
/ division
^ exponentiation

Logische Operatoren

Operator Description
< less than
<= less than or equal to
> greater than
>= greater than or equal to
== exactly equal to
!= not equal to
!x Not x
x y
x & y x AND y
isTRUE(x) test if X is TRUE
$ component
[ indexing
: sequence operator
~ as in formulae
<- assignment (right to left)
? help (unary and binary)

Hilfestellungen

Um die integrierte Hilfe für Pakete und Funktionen zu erhalten, verwenden Sie das Fragezeichen ? in der Konsole und stellen Sie es einer Funktion oder einem Paket voran. Um alle R Ressourcen zu durchsuchen, verwenden Sie ein doppeltes Fragezeichen ??.

#   ? help (unary and binary)
?base
?sf
# only loaded packages are searched 
#To search all of R use ??
??sf

Die meisten Probleme können mit ein wenig Erfahrung gelöst werden. Diese Website dient als hervorragender Ausgangspunkt zur Lösung Ihrer Probleme. Spaß beiseite, hier sind einige nützliche Hilfeseiten.

Darüber hinaus gibt es eine Vielzahl an Literatur, beipielsweise:

Das Erlernen einer Programmiersprache benötigt Zeit. Manchmal ist es frustrierend, manchmal versteht man nicht genau warum Operationen funktionieren (oder eben auch nicht). Das betrifft im Übrigen auch erfahrene Programmierer. Beißen Sie sich durch und nutzen Sie die Zahlreichen Hilfsangebote. Mit der Zeit werden sich dann immer mehr Probleme lösen lassen und die erzielten Ergebnisse stehen im Vordergrund.

Rohdaten einlesen

Exkurs zu working directory, Daten und Packages

Die Daten für dieses Tutorial werden über Github zur Verfügung gestellt. Wenn Sie den Code mit eigenen Daten reproduzieren wollten, ersetzen Sie die URL mit ihrem lokalen Dateipfad.

Definieren Sie in diesem Fall Ihren “working directory”, d.h. Ihr persönliches Arbeitsverzeichnis.

setwd("YOUR/FILEPATH") 
# this will not work. if you want to use it, define a path on your computer

Dabei handelt es sich um den Dateispeicherort, wo Ihre Daten und Skripte gespeichert sind. Weitere Infos finden Sie hier.

Der Code für das Speichern von Daten und Ergebnissen ist in diesen Tutorials deaktiviert. Ersetzen Sie zum Speichern “YOUR/FILEPATH” mit ihrem gewünschten Dateipfad.

Wir haben den Code zum Laden von packages so geschrieben, dass diese installiert werden, sofern dies noch nicht auf Ihrem PC abgespeichert sind. Anschließend werden diese direkt geladen. Sofern nicht anderweitig spezifiziert werden die packages in ein Standardverzeichnis auf Ihrem Computer abgespeichert.

Daten einlesen

Nun wird es praktisch. Üblicherweise werden zur Datenanalyse bereits vorhandene Datensätze eingelesen. Je nach Komplexität des Dateiformats kann das Lesen von Dateien mehr oder weniger kompliziert sein. Das Lesen von tabellenartigen Datenstrukturen ist jedoch recht einfach (tabellenartige Daten in unserem Fall sind die Formate .csv und.txt). Hier lesen wir eine csv Tabelle ein (comma seperated value).

# load data from Github
# tutorial unter https://rpubs.com/lokraj/github_csv
if (!require(readr)){install.packages("readr"); library(readr)}

urlfile <- "https://raw.githubusercontent.com/RafHo/teaching/master/geodaten_kommunizieren/datasource/basic.csv" # get url from github repositury
# use "urlfile" to read data
d2<-read.csv(url(urlfile), stringsAsFactors = FALSE)

# Head gibt einen kurzen Überblick über die ersten Zeilen einer Tabelle
head(d2)
##   id name value
## 1  1    a    10
## 2  2    b    12
## 3  3    c    14
## 4  4    d    16
## 5  5    e    18
## 6  6    f    20

#Bei txt Dateien verwenden wir folgende Funktion:
#d2 <- read.table("test.txt", header = TRUE, stringsAsFactors = FALSE)

Datenstrukturen

R kennt und versteht eine viele Datenstrukturen, von einfachen Tabellen bis hin zu mehrdimensionalen Raum-Zeit-Dateiformaten. Im Rahmen dieses Tutorials kratzen wir lediglich an der Oberfläche und schauen uns zwei einfache Datenstrukturen an: die Matrix und den Dataframe.

Der Aufbau einer Matrix wie auch eines Dataframes kann folgendermaßen visualisiert werden:

Ein strukturierter Datensatz (Grolemund & Wickham, 2019)

Beide bestehen aus Variablen (columns), Beobachtungen (rows) und einzelnen Werten.

Matrizen

Stellen Sie sich eine Matrix als eine primitive Kalkulationstabelle ähnlich der in Excel vor. Dabei beinhaltet eine Matrix jedoch nur einen einzigen Datentyp (z.B. einen numerischen Werte oder einen Text).

Erstellen Sie eine (zweidimensionale) Matrix aus den Werten 1-6 mit 3 Spalten und 2 Zeilen.

matrix(1:6, ncol = 3, nrow = 2)
##      [,1] [,2] [,3]
## [1,]    1    3    5
## [2,]    2    4    6

Um die Anzahl der Spalten und Zeilen zu tauschen, verwenden Sie die Funktion transpose t().

m <- matrix(1:6, ncol = 3, nrow = 2)
t(m)
##      [,1] [,2]
## [1,]    1    2
## [2,]    3    4
## [3,]    5    6

Meistens werden Matrizen durch zeilen- und/oder spaltenbindende Vektoren erzeugt. Beispielsweise können über die Funktion c mehrere Argumente miteinander verkettet (concatenated) werden. Können Sie den Unterschied zwischen den beiden Optionen rbind und cbind erkennen?

#create 2 vectors
a <-c(1,2,3)
b <- 5:7

#bind columns a nd b
m1 <- cbind(a, b)

# bind rows a and b
m2 <- rbind(a,b)

Mit rbind und cbind kann man auch Matrizen kombinieren, solange die Anzahl der Zeilen und Spalten gleich ist.

#create 2 vectors
m3 <- cbind(b,b,a)
m <- cbind(m1, m3)
m
##      a b b b a
## [1,] 1 5 5 5 1
## [2,] 2 6 6 6 2
## [3,] 3 7 7 7 3

Um die Struktur einer Matrix anzusehen, verwenden Sie die folgenden Funktionen:

#number of rows or columns?
nrow(m)
## [1] 3
ncol(m)
## [1] 5
# dimensions (number of cells)
dim(m)
## [1] 3 5
#length of 
length(m)
## [1] 15

Spalten haben Variablennamen, die geändert werden können. Das gleiche gilt für Zeilen.

#get column names
colnames(m)
## [1] "a" "b" "b" "b" "a"
#define column names
colnames(m) <- c('ID', 'X', 'Y', 'v1', 'v2')
rownames(m) <- paste0('row', 1:nrow(m))
m
##      ID X Y v1 v2
## row1  1 5 5  5  1
## row2  2 6 6  6  2
## row3  3 7 7  7  3

Dataframes

Meistens werden Dataframes in R verwendet. Sie sehen aus wie eine Matrix, aber im Gegensatz zu einer Matrix sind Dataframes in der Lage, Spalten (Variablen) verschiedener Datentypen zu speichern. Datenrahmen sind das, was Sie erhalten, wenn Sie Spreadsheets (wie Excel oder csv) über die Funktionen read.table oder read.csv importieren. Sie können aber auch von Grund auf neu erstellt werden.

# four vectors
ID <-as.integer(1:4)
name <-c('Ana', 'Rob', 'Liu', 'Veronica')
sex <-as.factor(c('F','M','M','F'))
score <-c(10.2, 9, 13.5, 18)
d <-data.frame(ID, name, sex, score, stringsAsFactors=FALSE)

d
##   ID     name sex score
## 1  1      Ana   F  10.2
## 2  2      Rob   M   9.0
## 3  3      Liu   M  13.5
## 4  4 Veronica   F  18.0

EXKURS: Daten exportieren

Genauso wie Daten geladen werden können, kann man diese auch wieder aus R exportieren um eigene Ergebnisse zuspeichern.

Exemplarisch erstellen wir nun einen Dataframe und speichern ihn im Arbeitsverzeichnis als CSV-Datei (comma seperated values) und als TXT-Datei (text).

# create data frame with three named columns
d <- data.frame(id=1:10, name = letters[1:10], value=seq(10,28,2))
d
# since we defined the working directory, the files will be saved there
# in order to write the file we need to at least provide the data frame and the name und which we want to save the file
write.csv(d, "YOUR/FILEPATH", row.names = FALSE)
#and the same for the .txt
write.table(d, "YOUR/FILEPATH/test.txt", row.names = FALSE)

Datentypen

Die zwei grundlegenden Datentypen, die in R verwendet werden, sind numerische Werte und textuelle Zeichenketten (character values) (weitere Infos gibt es hier). Das Tutorial zeigt hauptsächlich wie Datentypen erstellt oder geändert werden. In der Regel sind die Datentypen eines Datensatzes bereits definiert, aber müssen z.T. für die weitere Analyse manipuliert werden. Deshalb ist die Kenntnis der grundlegenden Datentypen eminent wichtig.

Numerische Datentypen

Numerisch bedeutet, dass ein erstelltes Objekt a für eine reelle (dezimale) Zahl steht. Entsprechend wird eine 7 von einem PC als 7.000000 interpretiert. In einigen wenigen Fällen kann es sinnvoll oder sogar notwendig sein, ganzzahlige Werte (integer) zu verwenden. Die Verwendung von ganzen Zahlen kann die Verarbeitungszeit verkürzen, insbesondere bei großen Datensätzen. Verwenden Sie as.integer, um die numerische Variable zu konvertieren.

a  <- as.integer(7)
class(a)
## [1] "integer"

Um einen Vektor von Zahlen zu erstellen, verwenden Sie die Funktion c (concatenate/verketten), um alle Zahlen anzuhängen. Das Trennzeichen innerhalb der Zahlen ist ., um zwischen den Zahlen zu trennen, verwenden Sie ,:

b <- c(1.35, 7.5, 3.0)
print(b)
## [1] 1.35 7.50 3.00

Character values

Zeichenwerte, die oft als “Zeichenketten” bzw. “strings” bezeichnet werden, sind Buchstaben oder Wörter. Zeichenwerte sind von Variablennamen durch Anführungszeichen ' oder doppelte Anführungszeichen " zu unterscheiden. R ist case-sensitive: a ist nicht dasselbe wie A. In den meisten Computerzusammenhängen sind a und A völlig unterschiedlich und in den meisten Absichten und Zwecken nicht verwandte Symbole.

x <- "jkl"
y  <- "hello world"
class(x)
## [1] "character"

Erstellen wir nun die Variable Länder, die einen Zeichenvektor von fünf Elementen enthalten.

countries <-c('China', 'China', 'Japan', 'South Korea', 'Japan')
class(countries)
## [1] "character"
print(countries)
## [1] "China"       "China"       "Japan"       "South Korea" "Japan"
length(countries)
## [1] 5
nchar(countries)
## [1]  5  5  5 11  5

Datenaufbereitung mit dplyr und spdplyr

Das Paket “dplyr” bringt für die Datenaufbereitung eine Reihe nützlicher Funktionen mit, um Daten umzuformen, zu prüfen, zu bereinigen, zu gruppieren oder zusammenzufassen. Es bietet somit sinnvolle Funktionen als Voraussetzung für die eigentliche Datenanalyse. Typische Probleme die im Rahmen der Datenaufbereitung adressiert werden:

  • Fehlende Werte, z.B. keine Angabe NA
  • Unerwartete Daten, z.B. falscher Datentyp
  • Umformung der Daten, z.B. Zusammenführung von zwei Tabellen oder Transposition einer Tabelle
  • Neue Variablen (Spalten) berechnen, z.B. die Summe von Werten aus anderen Spalten

Das Paket “dyplr” (das Cheatsheet zu den Funktionen findet sich hier) ist im Paket “tidyverse” enthalten, das noch eine Reihe weiterer Pakete, wie z.B. ggplot2 oder “lubridate”, mitbringt (s. tidyverse_packages()).

if (!require(tidyverse)){install.packages("tidyverse"); library(tidyverse)}

Zur Veranschaulichung des dplyr Pakets laden wir zunächst den folgenden Datensatz über Säugetiere:

urlfile2 <- "https://raw.githubusercontent.com/RafHo/teaching/master/geodaten_kommunizieren/datasource/mammals.txt"
mammals <- read.csv(urlfile2, sep="")

Zeilen filtern

Die Funktion filter() ermöglicht es, nach Zeilen eine eine Teilmenge zu filtern. Alle gültigen logischen Operatoren können verwendet werden:

filter(mammals, adult_body_mass_g > 1e7)[ , 1:3] # zeigt Spalte 1-3
##      order                species adult_body_mass_g
## 1  Cetacea      Caperea marginata          32000000
## 2  Cetacea  Balaenoptera musculus         154321305
## 3  Cetacea  Balaenoptera physalus          47506008
## 4  Cetacea     Balaena mysticetus          79691179
## 5  Cetacea  Balaenoptera borealis          22106252
## 6  Cetacea     Balaenoptera edeni          20000000
## 7  Cetacea      Berardius bairdii          11380000
## 8  Cetacea  Eschrichtius robustus          27324024
## 9  Cetacea    Eubalaena australis          23000000
## 10 Cetacea    Eubalaena glacialis          23000000
## 11 Cetacea Megaptera novaeangliae          30000000
## 12 Cetacea       Physeter catodon          14540960

filter(mammals, species == "Balaena mysticetus")
##     order            species adult_body_mass_g adult_head_body_len_mm
## 1 Cetacea Balaena mysticetus          79691179               12187.12
##   home_range_km2 litter_size
## 1             NA           1

filter(mammals, order == "Carnivora" & adult_body_mass_g < 200)
##       order         species adult_body_mass_g adult_head_body_len_mm
## 1 Carnivora Mustela altaica            180.24                 243.52
## 2 Carnivora Mustela frenata            190.03                 229.31
## 3 Carnivora Mustela nivalis             78.45                 188.18
##   home_range_km2 litter_size
## 1             NA        5.44
## 2           0.21        6.50
## 3           0.07        5.07

Zeilen anordnen

Mit der Funktion arrange() können Zeilen nach einer oder mehreren Spalten in aufsteigender oder absteigender Reihenfolge sortiert werden. Aus Gründen der besseren Lesbarkeit werden nur die ersten drei Spalten (1:3) und ersten zehn Reihen (1:10) ausgewählt:

arrange(mammals, adult_body_mass_g)[1:10 , 1:3]
##           order                     species adult_body_mass_g
## 1    Chiroptera Craseonycteris thonglongyai              1.96
## 2    Chiroptera            Kerivoula minuta              2.03
## 3  Soricomorpha             Suncus etruscus              2.26
## 4  Soricomorpha          Sorex minutissimus              2.46
## 5  Soricomorpha     Suncus madagascariensis              2.47
## 6  Soricomorpha         Crocidura lusitania              2.48
## 7  Soricomorpha         Crocidura planiceps              2.50
## 8    Chiroptera        Pipistrellus nanulus              2.51
## 9  Soricomorpha                 Sorex nanus              2.57
## 10 Soricomorpha              Sorex arizonae              2.70

arrange(mammals, desc(adult_body_mass_g))[1:10 , 1:3]
##      order                species adult_body_mass_g
## 1  Cetacea  Balaenoptera musculus         154321305
## 2  Cetacea     Balaena mysticetus          79691179
## 3  Cetacea  Balaenoptera physalus          47506008
## 4  Cetacea      Caperea marginata          32000000
## 5  Cetacea Megaptera novaeangliae          30000000
## 6  Cetacea  Eschrichtius robustus          27324024
## 7  Cetacea    Eubalaena australis          23000000
## 8  Cetacea    Eubalaena glacialis          23000000
## 9  Cetacea  Balaenoptera borealis          22106252
## 10 Cetacea     Balaenoptera edeni          20000000

Spalten erstellen

Mit der Funktion mutate() können neue Spalten (Variablen) hinzufügt werden. Neu erstellte Spalten können auf der Grundlage schon bestehender Spalten erstellt bzw. errechnet werden. Zur besseren Sichtbarmachunug werden die erstellten Spalten mit glimpse() ausgeführt:

glimpse(mutate(mammals, adult_body_mass_kg = adult_body_mass_g / 1000))
## Rows: 5,416
## Columns: 7
## $ order                  <chr> "Artiodactyla", "Carnivora", "Carnivora", "Carn~
## $ species                <chr> "Camelus dromedarius", "Canis adustus", "Canis ~
## $ adult_body_mass_g      <dbl> 492714.47, 10392.49, 9658.70, 11989.10, 31756.5~
## $ adult_head_body_len_mm <dbl> NA, 745.32, 827.53, 872.39, 1055.00, 2700.00, N~
## $ home_range_km2         <dbl> 1.963200e+02, 1.010000e+00, 2.950000e+00, 1.888~
## $ litter_size            <dbl> 0.98, 4.50, 3.74, 5.72, 4.98, 1.22, 1.00, 1.22,~
## $ adult_body_mass_kg     <dbl> 492.71447, 10.39249, 9.65870, 11.98910, 31.7565~

glimpse(mutate(mammals, g_per_mm = adult_body_mass_g / adult_head_body_len_mm))
## Rows: 5,416
## Columns: 7
## $ order                  <chr> "Artiodactyla", "Carnivora", "Carnivora", "Carn~
## $ species                <chr> "Camelus dromedarius", "Canis adustus", "Canis ~
## $ adult_body_mass_g      <dbl> 492714.47, 10392.49, 9658.70, 11989.10, 31756.5~
## $ adult_head_body_len_mm <dbl> NA, 745.32, 827.53, 872.39, 1055.00, 2700.00, N~
## $ home_range_km2         <dbl> 1.963200e+02, 1.010000e+00, 2.950000e+00, 1.888~
## $ litter_size            <dbl> 0.98, 4.50, 3.74, 5.72, 4.98, 1.22, 1.00, 1.22,~
## $ g_per_mm               <dbl> NA, 13.9436618, 11.6717219, 13.7428214, 30.1009~

glimpse(mutate(mammals, g_per_mm = adult_body_mass_g / adult_head_body_len_mm, kg_per_mm = g_per_mm / 1000))
## Rows: 5,416
## Columns: 8
## $ order                  <chr> "Artiodactyla", "Carnivora", "Carnivora", "Carn~
## $ species                <chr> "Camelus dromedarius", "Canis adustus", "Canis ~
## $ adult_body_mass_g      <dbl> 492714.47, 10392.49, 9658.70, 11989.10, 31756.5~
## $ adult_head_body_len_mm <dbl> NA, 745.32, 827.53, 872.39, 1055.00, 2700.00, N~
## $ home_range_km2         <dbl> 1.963200e+02, 1.010000e+00, 2.950000e+00, 1.888~
## $ litter_size            <dbl> 0.98, 4.50, 3.74, 5.72, 4.98, 1.22, 1.00, 1.22,~
## $ g_per_mm               <dbl> NA, 13.9436618, 11.6717219, 13.7428214, 30.1009~
## $ kg_per_mm              <dbl> NA, 0.0139436618, 0.0116717219, 0.0137428214, 0~

Spalten zusammenfassen und Datensätze gruppieren

Mit der Funktion summarise() können zusammenfassende Statistiken aus Spalten berechnet werden. Die alleinige Verwendung von summarise() ist nicht sehr nützlich, aber in Kombination mit group_by() können Datenblöcke sinnvoll zusammengefasst bzw. gruppiert werden.

summarise(mammals, mean_mass = mean(adult_body_mass_g, na.rm = TRUE))
##   mean_mass
## 1  177810.2

head(summarise(group_by(mammals, order), mean_mass = mean(adult_body_mass_g, na.rm = TRUE)))
## # A tibble: 6 x 2
##   order        mean_mass
##   <chr>            <dbl>
## 1 Afrosoricida      94.8
## 2 Artiodactyla  121329. 
## 3 Carnivora      47386. 
## 4 Cetacea      7373065. 
## 5 Chiroptera        57.7
## 6 Cingulata       4699.

Die Ablauflogik kontrollieren mittels “pipen”

Die Grundidee von “dyplyr” basiert darauf, dass komplexe Datenanalysen nach dem Lego-Prinzip in einzelne einfache Bausteine zerlegt werden. Darüber hinaus ist ein Grundprinzip des Paketes, dass alle Operationen einen Dataframe (oder einene s.g. tibble) erwarten (andere Datenstrukturen werden nicht akzeptiert) und wiederum ein solches weiterreichen. Somit können Dataframes entlang einer “Arbeitskette”, ähnlich einem Fließband, mit spezifischen Operationen bearbeitet werden. Für die lineare Aneinanderreihung der einzelnen Operationen kann mit dem Pipe-Befehl %>% schließlich eine Sequenz von auf die Dataframes angewandte Befehle konstruiert werden.

a %>% mean()
## [1] 7

#Das gleiche Resultat liefert:
mean(a)
## [1] 7

Nun wird der “mammals” Dataframe an das erste Argument der Funktion arrange übergeben und die Anordnung über die Spalte adult_body_mass_g gewählt:

mammals %>% arrange(adult_body_mass_g) %>%
  head() # sonst sehr lange liste
##          order                     species adult_body_mass_g
## 1   Chiroptera Craseonycteris thonglongyai              1.96
## 2   Chiroptera            Kerivoula minuta              2.03
## 3 Soricomorpha             Suncus etruscus              2.26
## 4 Soricomorpha          Sorex minutissimus              2.46
## 5 Soricomorpha     Suncus madagascariensis              2.47
## 6 Soricomorpha         Crocidura lusitania              2.48
##   adult_head_body_len_mm home_range_km2 litter_size
## 1                  30.99             NA        1.00
## 2                     NA             NA          NA
## 3                     NA             NA        4.00
## 4                  52.04             NA        8.99
## 5                     NA             NA          NA
## 6                  30.99             NA          NA

### without pipe
head(arrange(mammals, adult_body_mass_g)) 
##          order                     species adult_body_mass_g
## 1   Chiroptera Craseonycteris thonglongyai              1.96
## 2   Chiroptera            Kerivoula minuta              2.03
## 3 Soricomorpha             Suncus etruscus              2.26
## 4 Soricomorpha          Sorex minutissimus              2.46
## 5 Soricomorpha     Suncus madagascariensis              2.47
## 6 Soricomorpha         Crocidura lusitania              2.48
##   adult_head_body_len_mm home_range_km2 litter_size
## 1                  30.99             NA        1.00
## 2                     NA             NA          NA
## 3                     NA             NA        4.00
## 4                  52.04             NA        8.99
## 5                     NA             NA          NA
## 6                  30.99             NA          NA

Angenommen, die Säugetierart mit dem höchsten Verhältnis von Körpergewicht zu Länge wird gesucht:

# mit Pipe
mammals %>%
  mutate(mass_to_length = adult_body_mass_g / adult_head_body_len_mm) %>%
  arrange(desc(mass_to_length)) %>%
  select(species, mass_to_length) %>%
  head() # sonst sehr lange liste
##                  species mass_to_length
## 1     Balaena mysticetus       6538.967
## 2  Balaenoptera musculus       5063.035
## 3 Megaptera novaeangliae       2333.503
## 4  Eschrichtius robustus       2309.354
## 5  Balaenoptera physalus       2301.529
## 6        Elephas maximus       1703.728

#Das gleiche Resultat liefert (Matrjoschka) / without pipe:
head(
select(
 arrange(
   mutate(mammals, mass_to_length = adult_body_mass_g / adult_head_body_len_mm),
   desc(mass_to_length)),
  species, mass_to_length)
  )
##                  species mass_to_length
## 1     Balaena mysticetus       6538.967
## 2  Balaenoptera musculus       5063.035
## 3 Megaptera novaeangliae       2333.503
## 4  Eschrichtius robustus       2309.354
## 5  Balaenoptera physalus       2301.529
## 6        Elephas maximus       1703.728
Next