So wie es diesen beiden Füchsen geht, so kann es einem selbst mit seinem Datensatz gehen. Nach monatelangen Vorbereitungen hat man nun alle Anträge geschrieben, Beschlüsse eingeholt, Probanden rekrutiert, Daten gesammelt und von fleißigen HiWis in den PC eingeben lassen. Nun will man “mal eben” etwas damit rechnen und stellt fest, dass der Datensatz für die Analysen gar nicht richtig formatiert ist.

Wie bereits erwähnt, entstand das Tidyverse um die Idee “sauberer Daten” (tidy data). Das Konzept wurde von Wickham (2014) beschrieben und ist eigentlich recht simpel (siehe untere Abbildung).

Datensätze sollten so formatiert sein, dass jede Spalte eine Variable darstellt. Jede Zeile soll eine Beobachtung sein und jede Zelle schlielich ein einzelner Wert. Jeder SPSS-Nutzer wird sich nun wundern und denken “Was will der Typ eigentlich? Jede Zeile meines Datensatzes steht doch für einen Probanden, wie ich es im Statistik-Seminar gelernt habe. Das ist doch schon im richtigen Format (?)” Aber leider nein, denn für einen Probanden kann man mehrere Beobachtungen haben. Um im Tidyverse (und im Großteil von R) zu arbeiten, müssen die Daten jedoch tidy sein. Schauen wir uns einmal an, was ich damit meine.

Datensatz einlesen

Zu Beginn laden wir einige der bereits bekannten Pakete. haven gehört mit zum Tidyverse, wird automatisch installiert, wenn man das Tidyverse installiert, jedoch aber nicht automatisch geladen, weil es ein zu spezielles Paket ist. Mit haven können nämlich SAS-, Stata- und (jetzt kommt’s) SPSS-Datensätze eingelesen werden. Im Ordner data gibt es den Datensatz wrangling.sav. Wir laden ihn mit der passend benannten Funktion read_spss("<FILE-PATH>").

library(tidyverse)
library(haven)
library(janitor)
library(skimr)

read_spss("data/wrangling.sav")
## # A tibble: 43 x 8
##       ID   Age gender treatment BMI_1 BMI_2 BMI_3 BMI_4
##    <dbl> <dbl>  <dbl> <dbl+lbl> <dbl> <dbl> <dbl> <dbl>
##  1     1    54      1   0 [TAU]  26.8  27.2  27.8  28.7
##  2     2    52      0   1 [EG]   NA    NA    NA    NA  
##  3     3    54      1   1 [EG]   NA    NA    NA    NA  
##  4     4    35      1   1 [EG]   28.4  NA    NA    NA  
##  5     5    50      0   0 [TAU]  34.0  35.7  35.6  35.9
##  6     6    20      0   1 [EG]   20.7  20.7  20.9  20.7
##  7     7    45      1   0 [TAU]  26.2  26.1  25.7  25.5
##  8     8    37      1   1 [EG]   35.7  35.5  35.6  36.0
##  9     9    57      1   1 [EG]   34.2  33.9  33.4  33.7
## 10    10    61      0   1 [EG]   16.9  17.2  17.3  17.3
## # ... with 33 more rows

Nutzt man zum Datenimport Funktionen des Tidyverse, ist der Datensatz sofort als eine Tibble, ein optimierter data.frame, formatiert. Wir bekommen auch den Hinweis, dass es sich bei dem Objekt, das wir betrachten, um eine Tibble handelt, nämlich eine mit 43 Zeilen und 8 Spalten. Der eigentliche Datensatz wird daraufhin mit den Variablen und den ersten 10 Zeilen angezeigt. Direkt unter dem Namen findet sich der Datentyp der Variable, dbl steht für “double”, chr würde für “character” stehen, etc. Für die unterschiedlichen Datentypen, sei auf Wikipedia verwiesen. In der Variable treatment begegnet uns die Bezeichung <dbl + lbl>; hier sind die Wertelabels aus SPSS hinterlegt.

Wieso ist es nun schön, dass der Datensatz als Tibble und nicht als der R-Standard data.frame eingelesen wird? Gucken wir uns doch einfach mal denselben Datensatz als data.frame an:

as.data.frame(read_spss("data/wrangling.sav"))
##    ID Age gender treatment BMI_1 BMI_2 BMI_3 BMI_4
## 1   1  54      1         0 26.81 27.17 27.76 28.67
## 2   2  52      0         1    NA    NA    NA    NA
## 3   3  54      1         1    NA    NA    NA    NA
## 4   4  35      1         1 28.41    NA    NA    NA
## 5   5  50      0         0 34.05 35.68 35.61 35.89
## 6   6  20      0         1 20.70 20.66 20.94 20.68
## 7   7  45      1         0 26.19 26.09 25.71 25.50
## 8   8  37      1         1 35.74 35.52 35.61 35.97
## 9   9  57      1         1 34.19 33.93 33.45 33.67
## 10 10  61      0         1 16.94 17.22 17.33 17.29
## 11 11  34      0         0 23.23 23.26 23.32 22.93
## 12 12  57      1         1 37.70 37.91 38.05 39.15
## 13 13  55      0         0 41.34 41.31 40.49 39.23
## 14 14  29      0         1 22.51 23.15 22.83 23.55
## 15 15  36      0         1 20.56 20.23 20.86 20.64
## 16 16  49      0         1 26.25 25.66 25.55 25.86
## 17 17  37      1         1 25.00    NA    NA    NA
## 18 18  47      1         0 28.70 29.78 29.41 29.35
## 19 19  53      0         1 20.10 19.42 19.39 19.23
## 20 20  42      1         0 24.95 25.57 25.67 26.12
## 21 21  46      0         1 38.38 38.54 37.89 34.85
## 22 22  29      1         0 22.04 22.19 21.92 22.25
## 23 23  26      0         1 20.35 20.11 20.15 20.21
## 24 24  52      1         0 33.19 33.31 33.57 33.60
## 25 25  19      1         0 20.25 20.31 20.77 21.56
## 26 26  49      1         1 21.99 21.88 21.95 22.06
## 27 27  27      1         0    NA    NA    NA    NA
## 28 28  59      0         0 25.72 25.40 25.19 24.98
## 29 29  57      0         1 20.08 20.71 21.08 20.75
## 30 30  43      1         0 33.85 33.13    NA    NA
## 31 31  44      0         1 24.80 24.84 24.88 24.84
## 32 32  44      0         1 24.73 24.45 24.61 24.69
## 33 33  37      1         0 17.49 17.39 17.45 17.58
## 34 34  50      1         1 24.30 23.32 23.64 24.49
## 35 35  29      1         0 26.30 25.98 25.39 24.16
## 36 36  60      1         1 23.09 23.05 23.12 22.96
## 37 37  55      0         1 18.81 18.95 19.17 19.72
## 38 38  48      0         0 33.94 34.33 34.08 34.08
## 39 39  51      1         0 22.69 22.78 22.81 22.87
## 40 40  58      0         1 25.28 25.51 24.91 25.91
## 41 41  58      1         0 37.03 36.52 36.13 37.41
## 42 42  21      1         0 22.49 21.56 21.52 21.66
## 43 43  41      0         0    NA    NA    NA    NA

Im Prinzip sieht das sehr ähnlich aus, jedoch fällt sofort auf, dass der Output viel länger ist und alle 43 Zeilen umfasst. Meistens möchte man die alle gar nicht sehen. Hinzu kommt, dass auch alle Variablen angezeigt werden würden. In diesem Fall ist das kein Problem, weil ich nur acht habe, aber bei 200 ist das schon etwas anderes. Außerdem sind in der Variable treatment alle von mir mühsam in SPSS eingegebenen Wertelabels weg – welche eine Gemeinheit! Und dann habe ich noch nicht mal eine Ahnung davon, welchen Datentyp meine Variablen enthalten. Unerhört! Hier wird direkt deutlich, warum man Fan des Tidyverse werden könnte.

Alles in allem haben wir hier einen Datensatz mit 43 Probanden, deren Alter, Geschlecht und Behandlung wir erfasst haben, so wie den BMI für 4 konsekutive Messungen.

Variablennamen bereinigen

Uff, ist das hässlich! Nach allem, was wir über stilsichere Objektnamen gelernt haben, sind wir über die Benennung der Variablen überhaupt nicht glücklich. Das müssen wir ändern, gut, dass wir das Paket janitor haben. Zunächst speichern wir den Datensatz als ein Objekt (in diesem Falle wrangling_data), damit wir es nicht dauern neu einlesen müssen und wenden dann die Funktion clean_names() an.

wrangling_data <- clean_names(read_spss("data/wrangling.sav"))

wrangling_data
## # A tibble: 43 x 8
##       id   age gender treatment bmi_1 bmi_2 bmi_3 bmi_4
##    <dbl> <dbl>  <dbl> <dbl+lbl> <dbl> <dbl> <dbl> <dbl>
##  1     1    54      1   0 [TAU]  26.8  27.2  27.8  28.7
##  2     2    52      0   1 [EG]   NA    NA    NA    NA  
##  3     3    54      1   1 [EG]   NA    NA    NA    NA  
##  4     4    35      1   1 [EG]   28.4  NA    NA    NA  
##  5     5    50      0   0 [TAU]  34.0  35.7  35.6  35.9
##  6     6    20      0   1 [EG]   20.7  20.7  20.9  20.7
##  7     7    45      1   0 [TAU]  26.2  26.1  25.7  25.5
##  8     8    37      1   1 [EG]   35.7  35.5  35.6  36.0
##  9     9    57      1   1 [EG]   34.2  33.9  33.4  33.7
## 10    10    61      0   1 [EG]   16.9  17.2  17.3  17.3
## # ... with 33 more rows

Das sieht doch schon gleich ganz anders aus, alle Variablen sind einheitlich als “snake case” gesetzt. So lässt es sich arbeiten!

Faktoren

Faktoren sind in R eine ganz besondere Angelegenheit. Wenn wir Abbildungen erstellen möchten, die nach Gruppen aufgeteilt sind (z.B. nach Geschlecht oder Experimentalbedingung), oder wenn wir Gruppenunterschiede statistisch untersuchen wollen, dann müssen diese Gruppen als Faktor definiert sein. In unserem Datensatz betrifft das die Variablen gender und treatment, also das Geschlecht der Probanden und die erhaltene Behandlung.

Selbst definieren

Um Faktoren zu definieren, gibt es mehrere Möglichkeiten. Meistens bekommt man Daten, in denen nur Zahlen hinterlegt sind, wir aber wollen, dass diese Zahlen für etwas stehen. Die Variable gender ist ein gutes Beispiel dafür. Die Probanden wurden hier einem von zwei Geschlechtern zugeordnet, weiblich und männlich. Wenn man in R mit Faktoren arbeitet, arbeitet man nicht mit reinen Zahlen. Faktoren sind immer Zeichenfolgen, die als spezieller Datantyp “Faktor” gespeichert werden. In anderen Statistikumgebungen, wie etwa SPSS, wurde das anders gelöst. Hier werden Faktoren als verschiedene nummerische Ausprägungen (= Levels) einer Variablen verstanden, die mit Beschriftungen (= Labels) verknüpft sind. So können die Frauen in einem Datensatz mal die 0, mal die 4 sein, oder die Männer, oder die Experimentalgruppe, oder die… Im Sinne der Einheitlichkeit und der Minimierung von Fehlern, empfiehlt es sich übrigens in solchen Umgebungen, Geschlecht anatomisch zu codieren, also Frauen als 0 und Männer als 1.

In R arbeiten wir mit “richtigen” Faktoren. In der Variable gender soll also die Bezeichnung “weiblich” oder “männlich” direkt hinterlegt werden. Wie kommen wir nun von unseren Zahlen zu den Faktoren? Mit der Funktion factor(), die nativer Bestandteil von R ist. Die Funktion benötigt von uns die Ausgangsvariable, die Levels und die Labels, die wir gerne vergeben würden. Die generelle Syntax ist

factor(<VARIABLE>, levels = c("<LEVEL1>", "<LEVEL2>"), labels = c("<LABEL1>", "<LABEL2>"))

Um eine bestehende Variable zu modifizieren, oder zu mutieren, benutzen wir die Funktion mutate, der wir als erstes Argument unseren Datensatz nennen und dann die Variable, die wir verändern wollen.

mutate(wrangling_data, gender = factor(gender, levels = c(0, 1), labels = c("Female", "Male")))
## # A tibble: 43 x 8
##       id   age gender treatment bmi_1 bmi_2 bmi_3 bmi_4
##    <dbl> <dbl> <fct>  <dbl+lbl> <dbl> <dbl> <dbl> <dbl>
##  1     1    54 Male     0 [TAU]  26.8  27.2  27.8  28.7
##  2     2    52 Female   1 [EG]   NA    NA    NA    NA  
##  3     3    54 Male     1 [EG]   NA    NA    NA    NA  
##  4     4    35 Male     1 [EG]   28.4  NA    NA    NA  
##  5     5    50 Female   0 [TAU]  34.0  35.7  35.6  35.9
##  6     6    20 Female   1 [EG]   20.7  20.7  20.9  20.7
##  7     7    45 Male     0 [TAU]  26.2  26.1  25.7  25.5
##  8     8    37 Male     1 [EG]   35.7  35.5  35.6  36.0
##  9     9    57 Male     1 [EG]   34.2  33.9  33.4  33.7
## 10    10    61 Female   1 [EG]   16.9  17.2  17.3  17.3
## # ... with 33 more rows

Die Variable gender ist nun als ordentlicher Faktor definiert worden, was wir auch anhand des Datentyps fct erkennen können. Im Sinne der besseren Lasbarkeit, können wir den obigen Code etwas einfach aufschreiben. Wir nutzen dazu den “Pipe”-Operator (%>%). Im obigen Befehl wird dir auffallen, dass wir die Funktion mutate verwenden und dann als erstes sofort den Datensatz als Funktionsargument nennen. Das können wir etwas abkürzen, und zwar mit dem Pipe. Er nimmt das Objekt, das vor ihm steht und fügt es als erster Funktionsargument in die Funktion, die nach ihm steht ein.

# Der Befehl
f(x)

# ist identisch mit
x %>% 
  f()

Wo ist nun der Nutzen dabei? Der Befehl wird länger und enthält diesen grausam schreibbaren Pipe-Operator! Der Vorteil liegt darin, dass wir die Syntax besser verstehen, indem wir den Pipe als “dann” lesen können. Im obigen Beispiel kann man den Befehl lesen als “Nimm x und dann mache Funktion f()”. Der Vorteil wird noch deutlicher, wenn wir uns unserem Datensatz zuwenden. Wir wollten in dem Datensatz die Variable gender als Faktor definieren. Wenden wir nun den Pipe (%>%) an, ergibt sich dieser Befehl:

wrangling_data %>% 
  mutate(gender = factor(gender,
                         levels = c(0,1),
                         labels = c("Female", "Male")))
## # A tibble: 43 x 8
##       id   age gender treatment bmi_1 bmi_2 bmi_3 bmi_4
##    <dbl> <dbl> <fct>  <dbl+lbl> <dbl> <dbl> <dbl> <dbl>
##  1     1    54 Male     0 [TAU]  26.8  27.2  27.8  28.7
##  2     2    52 Female   1 [EG]   NA    NA    NA    NA  
##  3     3    54 Male     1 [EG]   NA    NA    NA    NA  
##  4     4    35 Male     1 [EG]   28.4  NA    NA    NA  
##  5     5    50 Female   0 [TAU]  34.0  35.7  35.6  35.9
##  6     6    20 Female   1 [EG]   20.7  20.7  20.9  20.7
##  7     7    45 Male     0 [TAU]  26.2  26.1  25.7  25.5
##  8     8    37 Male     1 [EG]   35.7  35.5  35.6  36.0
##  9     9    57 Male     1 [EG]   34.2  33.9  33.4  33.7
## 10    10    61 Female   1 [EG]   16.9  17.2  17.3  17.3
## # ... with 33 more rows

Das Ergebnis ist dasselbe wie in der ersten Version dieses Befehls, jedoch kann man ihn so besser lesen und verstehen: “Nimm den Datensatz wrangling_data und wende die Funktion mutate an.” Von nun an, werde ich den Pipe-Operator immer verwenden.

Wichtig zu beachten ist, dass die Änderung noch nirgendwo gespeichert wurde. Wir sehen unseren Erfolg zwar in der Konsole, doch wenn wir den Datensatz noch einmal aufrufen stellen wir fest, dass gender immer noch als 0 und 1 kodiert sind.

wrangling_data
## # A tibble: 43 x 8
##       id   age gender treatment bmi_1 bmi_2 bmi_3 bmi_4
##    <dbl> <dbl>  <dbl> <dbl+lbl> <dbl> <dbl> <dbl> <dbl>
##  1     1    54      1   0 [TAU]  26.8  27.2  27.8  28.7
##  2     2    52      0   1 [EG]   NA    NA    NA    NA  
##  3     3    54      1   1 [EG]   NA    NA    NA    NA  
##  4     4    35      1   1 [EG]   28.4  NA    NA    NA  
##  5     5    50      0   0 [TAU]  34.0  35.7  35.6  35.9
##  6     6    20      0   1 [EG]   20.7  20.7  20.9  20.7
##  7     7    45      1   0 [TAU]  26.2  26.1  25.7  25.5
##  8     8    37      1   1 [EG]   35.7  35.5  35.6  36.0
##  9     9    57      1   1 [EG]   34.2  33.9  33.4  33.7
## 10    10    61      0   1 [EG]   16.9  17.2  17.3  17.3
## # ... with 33 more rows

Um Änderungen in R dauerhaft zu speichern, müssen wir sie einem Objekt zuweisen. Weil wir den Datensatz verbessert haben, spricht nichts dagegen, den alten Datensatz mit dem neuen zu überschreiben. Wir können unsere Änderung also mit <- den Namen wrangling_data zuweisen. Rufen wir die Daten nun erneut auf, ist die erfolgreiche Änderung gespeichert.

wrangling_data <- wrangling_data %>% 
  mutate(gender = factor(gender, 
                         levels = c(0, 1),
                         labels = c("Female", "Male")))

wrangling_data
## # A tibble: 43 x 8
##       id   age gender treatment bmi_1 bmi_2 bmi_3 bmi_4
##    <dbl> <dbl> <fct>  <dbl+lbl> <dbl> <dbl> <dbl> <dbl>
##  1     1    54 Male     0 [TAU]  26.8  27.2  27.8  28.7
##  2     2    52 Female   1 [EG]   NA    NA    NA    NA  
##  3     3    54 Male     1 [EG]   NA    NA    NA    NA  
##  4     4    35 Male     1 [EG]   28.4  NA    NA    NA  
##  5     5    50 Female   0 [TAU]  34.0  35.7  35.6  35.9
##  6     6    20 Female   1 [EG]   20.7  20.7  20.9  20.7
##  7     7    45 Male     0 [TAU]  26.2  26.1  25.7  25.5
##  8     8    37 Male     1 [EG]   35.7  35.5  35.6  36.0
##  9     9    57 Male     1 [EG]   34.2  33.9  33.4  33.7
## 10    10    61 Female   1 [EG]   16.9  17.2  17.3  17.3
## # ... with 33 more rows

Automatisch definieren

Wurden in SPSS bereits die richtigen Wertelabels vergeben, wie für die Variable treatment, können wir uns den Weg etwas abkürzen. Im Datensatz ist zu sehen, dass sowohl Levels als auch Label des Faktors bereits hinterlegt sind (daher der komische Datentyp <dbl + lbl>). Mit der Funktion as_factor() wird die Variable automatisch als Faktor definiert.

wrangling_data <- wrangling_data %>% 
  mutate(treatment = as_factor(treatment))

wrangling_data
## # A tibble: 43 x 8
##       id   age gender treatment bmi_1 bmi_2 bmi_3 bmi_4
##    <dbl> <dbl> <fct>  <fct>     <dbl> <dbl> <dbl> <dbl>
##  1     1    54 Male   TAU        26.8  27.2  27.8  28.7
##  2     2    52 Female EG         NA    NA    NA    NA  
##  3     3    54 Male   EG         NA    NA    NA    NA  
##  4     4    35 Male   EG         28.4  NA    NA    NA  
##  5     5    50 Female TAU        34.0  35.7  35.6  35.9
##  6     6    20 Female EG         20.7  20.7  20.9  20.7
##  7     7    45 Male   TAU        26.2  26.1  25.7  25.5
##  8     8    37 Male   EG         35.7  35.5  35.6  36.0
##  9     9    57 Male   EG         34.2  33.9  33.4  33.7
## 10    10    61 Female EG         16.9  17.2  17.3  17.3
## # ... with 33 more rows

Super, das sieht schön aus, alle Faktoren sind als richtige faktoren definiert worden. Aber was ist das? Die Bezeichnungen für die Variable treatment sind “TAU” und “EG”, die für “Treatment as Usual” und “Experimental Group” stehen. Mmh, eigentlich hätte ich gerne “CG” für “Control Group” anstatt “TAU”. Auch da können wir etwas machen. Wir wollen einen Faktor umkodieren und bedienen uns deshalb der Funktion fct_recode(). Da wir eine Variable verändern wollen, müssen wir sie wieder “mutieren”.

wrangling_data <-  wrangling_data %>% 
  mutate(treatment = fct_recode(treatment,
                                "CG" = "TAU"))

wrangling_data
## # A tibble: 43 x 8
##       id   age gender treatment bmi_1 bmi_2 bmi_3 bmi_4
##    <dbl> <dbl> <fct>  <fct>     <dbl> <dbl> <dbl> <dbl>
##  1     1    54 Male   CG         26.8  27.2  27.8  28.7
##  2     2    52 Female EG         NA    NA    NA    NA  
##  3     3    54 Male   EG         NA    NA    NA    NA  
##  4     4    35 Male   EG         28.4  NA    NA    NA  
##  5     5    50 Female CG         34.0  35.7  35.6  35.9
##  6     6    20 Female EG         20.7  20.7  20.9  20.7
##  7     7    45 Male   CG         26.2  26.1  25.7  25.5
##  8     8    37 Male   EG         35.7  35.5  35.6  36.0
##  9     9    57 Male   EG         34.2  33.9  33.4  33.7
## 10    10    61 Female EG         16.9  17.2  17.3  17.3
## # ... with 33 more rows

Das hat wunderbar funktioniert, nun sind auch die Bezeichnungen meiner Experimentalbedingung einheitlich.

Wide vs. Long

An dieser Stelle machen wir noch einmal den Sprung zum Anfang der Seite. Wir haben von “tidy data” gelesen, also der Ansicht, dass eine Variable in eine Spalte, eine Beobachtung in eine Zeile und ein Wert in eine Zelle gehört. Ich habe bereits gespoilert, dass diese Daten nicht tidy sind – warum? Weil ich für die Messung des BMI ganze vier Beobachtungen pro Proband habe, also vier Beobachtungen pro Zeile. Was uns allerdings vorschwebt ist ein Datensatz, in dem jede Beobachtung auch tatsächlich nur eine Zeile ist, somit hätten wir konsequenterweise vier Zeilen pro Proband. Dem gewohnten SPSS-Nutzer pfeifen mittlerweile bestimmt die Ohren, aber nur so ergibt die Datenstruktur eigentlich Sinn. Denn weche Variable taucht im Datensatz nirgendwo auf? Wir haben eindeutig longitudinale Daten, aber nirgendwo die Zeit hinterlegt! Obwohl, eigentlich ist die hinterlegt, aber an einer Stelle, an die wir nicht drankommen, nämlich im Variablennamen selbst (als _1, _2, usw.).

Diese Datenstruktur nennt man wide format, weil sie breit ist. Wir hätten gerne mehrere Zeilen pro Proband, die Daten werden also länger, und die entstehende längere und tidy Datenstruktur nennt man long format. Um diese zu bekommen, müssen wir die Daten “länger machen”, am besten mit der Funktion pivot_longer(). Dieser müssen wir angeben, welche Variablen wir als eine lange haben wollen, welchen Namen wir für die neu erstellte Variable verwenden möchten und unter welchem Namen die Werte abgespeichert werden sollen. Die neu erstellte Variable ist in unserem Fall die Zeit, wir könnten sie “measurement” nennen, und die Variable, in der die Werte stehen “bmi”. Dank unserer einheitlichen Benennung, können wir angeben, dass unsere Variable “measurement” ein nerviges Präfix enthält, nämlich “bmi_”, welches automatisch gelöscht werden kann.

wrangling_data <- wrangling_data %>% 
  pivot_longer(
    cols = bmi_1:bmi_4,
    names_to = "measurement",
    names_prefix = "bmi_",
    values_to = "bmi"
  )

wrangling_data
## # A tibble: 172 x 6
##       id   age gender treatment measurement   bmi
##    <dbl> <dbl> <fct>  <fct>     <chr>       <dbl>
##  1     1    54 Male   CG        1            26.8
##  2     1    54 Male   CG        2            27.2
##  3     1    54 Male   CG        3            27.8
##  4     1    54 Male   CG        4            28.7
##  5     2    52 Female EG        1            NA  
##  6     2    52 Female EG        2            NA  
##  7     2    52 Female EG        3            NA  
##  8     2    52 Female EG        4            NA  
##  9     3    54 Male   EG        1            NA  
## 10     3    54 Male   EG        2            NA  
## # ... with 162 more rows

Leider ist die Variable measurement jetzt noch als Zeichenfolge (“chr”) abgespeichert, wir hätten sie aber gerne nummerisch. Das lässt sich schnell mit einem mutate lösen.

wrangling_data <- wrangling_data %>% 
  mutate(measurement = as.numeric(measurement))

wrangling_data
## # A tibble: 172 x 6
##       id   age gender treatment measurement   bmi
##    <dbl> <dbl> <fct>  <fct>           <dbl> <dbl>
##  1     1    54 Male   CG                  1  26.8
##  2     1    54 Male   CG                  2  27.2
##  3     1    54 Male   CG                  3  27.8
##  4     1    54 Male   CG                  4  28.7
##  5     2    52 Female EG                  1  NA  
##  6     2    52 Female EG                  2  NA  
##  7     2    52 Female EG                  3  NA  
##  8     2    52 Female EG                  4  NA  
##  9     3    54 Male   EG                  1  NA  
## 10     3    54 Male   EG                  2  NA  
## # ... with 162 more rows

Und schon ist der Datensatz fertig formatiert. Da es aber ziemlich aufwendig ist, jedes Mal ein neues Objekt zu definieren, sobald man eine Änderung durchgeführt hat, kann man auch alle Änderungen in einem Befehl ausführen.

wrangling_complete <- read_spss("data/wrangling.sav") %>% 
  clean_names() %>% 
  mutate(gender = factor(gender,
                         levels = c(0, 1),
                         labels = c("Female", "Male")),
         treatment = as_factor(treatment),
         treatment = fct_recode(treatment,
                                "CG" = "TAU")) %>% 
  pivot_longer(
    cols = bmi_1:bmi_4,
    names_to = "measurement",
    names_prefix = "bmi_",
    values_to = "bmi"
  ) %>% 
  mutate(measurement = as.numeric(measurement))

wrangling_complete
## # A tibble: 172 x 6
##       id   age gender treatment measurement   bmi
##    <dbl> <dbl> <fct>  <fct>           <dbl> <dbl>
##  1     1    54 Male   CG                  1  26.8
##  2     1    54 Male   CG                  2  27.2
##  3     1    54 Male   CG                  3  27.8
##  4     1    54 Male   CG                  4  28.7
##  5     2    52 Female EG                  1  NA  
##  6     2    52 Female EG                  2  NA  
##  7     2    52 Female EG                  3  NA  
##  8     2    52 Female EG                  4  NA  
##  9     3    54 Male   EG                  1  NA  
## 10     3    54 Male   EG                  2  NA  
## # ... with 162 more rows

Literatur

Wickham, H. (2014). Tidy Data. Journal of Statistical Software, 59(10). https://doi.org/10.18637/jss.v059.i10