Chapter 2 Base System und Tidyverse
2.1 Unterschied R-Base-Package und Tidyverse
Die Idee hinter Tidyverse: “The tidyverse is an opinionated collection of R packages designed for data science. All packages share an underlying design philosophy, grammar, and data structures” Quelle.
Das betrifft vor allem die konzeptuelle Klarheit und auch die Lesbarkeit.
Auch einige Schwächen von Base-R werden ausgeglichen, beispielsweise durch Tibbles, eine Erweiterung von Data-Frames für konsistenteres Verhalten.
read.table()
interpretiert gerne Spalten mit Text als factor()
, leider aber nicht konsistent.
Transformationen mit dem Base-Package von R sind oft knapper, mächtiger aber auch kryptischer, schwerer zu verstehen, unübersichtlicher und fehleranfälliger.
Tidyverse und hier insbesondere die library(dplyr)
sind eher modular.
Ein paar einfache Grundbefehle, verbs, werden über Pipes %>%
hintereinandergehängt.
Die Transformationen werden lesbarer und verständlicher.
2.1.1 Ein Beispiel mit Base Package
# read data in data object dd
require(tidyverse)
## Lade nötiges Paket: tidyverse
## ── Attaching packages ──────────────────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──
## ✔ ggplot2 3.3.5 ✔ purrr 0.3.4
## ✔ tibble 3.1.6 ✔ dplyr 1.0.8
## ✔ tidyr 1.2.0 ✔ stringr 1.4.0
## ✔ readr 2.1.2 ✔ forcats 0.5.1
## ── Conflicts ─────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
<- readr::read_tsv("https://md.psych.bio.uni-goettingen.de/mv/data/div/df_dplyr.txt") dd
## Rows: 12 Columns: 7
## ── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (1): gender
## dbl (6): subj, age, grp, v1, v2, v3
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# find v-values of all women aged 25 or more
$gender == "f" & dd$age >= 25, c('v1', 'v2', 'v3')] dd[dd
## # A tibble: 3 × 3
## v1 v2 v3
## <dbl> <dbl> <dbl>
## 1 67 73 66
## 2 86 87 91
## 3 26 34 28
# mean of the above values per subject
apply(dd[dd$gender == "f" & dd$age >= 25, c('v1', 'v2', 'v3')], 2, mean)
## v1 v2 v3
## 59.66667 64.66667 61.66667
# make all the above to a small table, means attached at the right
cbind(dd[dd$gender == "f" & dd$age >= 25, c('v1', 'v2', 'v3')], apply(dd[dd$gender == "f" & dd$age >= 25, c('v1', 'v2', 'v3')], 1, mean))
## v1 v2 v3 apply(dd[dd$gender == "f" & dd$age >= 25, c("v1", "v2", "v3")],
## 1 67 73 66 68.66667
## 2 86 87 91 88.00000
## 3 26 34 28 29.33333
2.1.2 Das Gleiche mit dplyr
aus dem tidyverse
# read data in data object dd
require(tidyverse)
<- readr::read_tsv("https://md.psych.bio.uni-goettingen.de/mv/data/div/df_dplyr.txt") dd
## Rows: 12 Columns: 7
## ── Column specification ─────────────────────────────────────────────────────────────────────────────────────────────
## Delimiter: "\t"
## chr (1): gender
## dbl (6): subj, age, grp, v1, v2, v3
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
# we make the same as above using dplyr and piping
%>%
dd ::filter(gender == "f" & age >= 25) %>%
dplyr::rowwise() %>%
dplyr::mutate(v_mean = mean(c(v1, v2, v3))) %>%
dplyr::select(v1, v2, v3, v_mean) dplyr
## # A tibble: 3 × 4
## # Rowwise:
## v1 v2 v3 v_mean
## <dbl> <dbl> <dbl> <dbl>
## 1 67 73 66 68.7
## 2 86 87 91 88
## 3 26 34 28 29.3
Das Tidyverse ist Ergebnis einer Entwicklung der letzten Jahre. Es überzeugt in vielerlei Hinsicht. Allerdings ist sehr viel R-Code, der im Web zu finden ist, in Base-R. Daher ist derzeit ein gewisses Maß an Verständnis für beide Ansätze nötig.
Wir stellen hier inhaltliche Ansätze jeweils möglichst parallel dar.