Auf dieser Seite findest du Übungen zu üblichen statistischen Tests in R.

Der gesamte Code, den du hier findest, kann von dir 1:1 in R umgesetzt werden. Die größte Lernwirkung hat diese Einführung, wenn du möglichst alles einmal selbst in R durchführst.


01 Vorbereitungen

Bevor wir loslegen können, müssen wir die Packages laden, die wir für unser Vorhaben benötigen. Zunächst ist das nur das SfL Package. Falls du dieses noch nicht geladen hast, hole dies nun nach:

library(SfL)

Nun laden wir die Datensätze, die wir nutzen werden:

data(data_a)
data(data_c)
data(data_s)
data(data_t)
data(data_v)

02 Shapiro-Wilk Test

Mit einem Shapiro-Wilk Test kannst du bestimmen, ob Daten normalverteilt sind. Hier zeigen p-Werte über \(0.05\) an, dass die Daten normalverteilt sind.

shapiro.test(data_s$sDur)

    Shapiro-Wilk normality test

data:  data_s$sDur
W = 0.93622, p-value = 2.761e-06

Mit \(p=2.761e^{-6}\) liegt der p-Wert unter \(0.05\), d.h. die /s/-Dauern sind nicht normalverteilt.

Aufgaben

Bestimme nun analog zum Beispiel, ob folgende Variablen normalverteilt sind:

  • data_s$baseDur

  • data_s$age

  • data_s$speakingRate

  • data_v$duration

  • data_a$age

  • data_a$height

Lösung
shapiro.test(data_s$baseDur) # nicht normalverteilt
shapiro.test(data_s$age) # nicht normalverteilt
shapiro.test(data_s$speakingRate) # nicht normalverteilt

shapiro.test(data_v$duration) # nicht normalverteilt

shapiro.test(data_a$age) # nicht normalverteilt
shapiro.test(data_a$height) # normalverteilt

Extra: Logarithmieren

Daten, die nicht normalverteilt sind, können durch verschiedene Transformationen “normalverteilter” werden. Die wohl meist genutzte Transformation hierfür ist das Logarithmieren.

shapiro.test(data_s$baseDur) # nicht normalverteilt

    Shapiro-Wilk normality test

data:  data_s$baseDur
W = 0.90932, p-value = 4.606e-08
shapiro.test(log(data_s$baseDur)) # normalverteilt(er)

    Shapiro-Wilk normality test

data:  log(data_s$baseDur)
W = 0.98401, p-value = 0.07966

In R können numerische Daten ganz einfach mit dem log() Befehl logarithmiert werden. Um aus solchen Zahlen wieder die ursprünglichen zu erhalten, kann der exp() Befehl genutzt werden.

# Beispielvektor
beispiel <- c(10, 15, 20, 333)

log(beispiel)
[1] 2.302585 2.708050 2.995732 5.808142
exp(log(beispiel))
[1]  10  15  20 333

Ein Blick auf die verschiedenen Vektoren des data_s-Dataframes zeigt, dass hier auch zwei logarithmierte Variablen enthalten sind:

head(data_s$sDurLog)
[1] -1.891469 -1.797878 -1.574505 -1.796129 -1.866009 -2.190239
head(data_s$baseDurLog)
[1] -1.1643035 -1.7150762 -1.2397036 -1.1616479 -1.2627679 -0.8748609

Diese entsprechen der logarithmierten Version der entsprechenden Variablen sDur und baseDur:

data_s$sDurLog[1:3]
[1] -1.891469 -1.797878 -1.574505
log(data_s$sDur)[1:3]
[1] -1.891469 -1.797878 -1.574505

03 t-Test

Abhängig, Einseitig

Für den abhängigen einseitigen t-Test erstellen wir zunächst Beispieldaten.

placebo <- c(168, 184, 172, 173, 150, 155, 163, 164, 151, 146)
medikament <- c(176, 145, 150, 163, 136, 168, 164, 139, 145, 112)

Nun führen wir den passenden t-Test durch.

t.test(medikament, placebo, alternative="less", paired=TRUE, conf.level=0.95)

    Paired t-test

data:  medikament and placebo
t = -2.3311, df = 9, p-value = 0.02233
alternative hypothesis: true difference in means is less than 0
95 percent confidence interval:
      -Inf -2.734372
sample estimates:
mean of the differences 
                  -12.8 

Da \(p=0.02233<0.5\) beträgt, ist die Wirkung des Medikaments nachgewiesen.

Hinweis:

  • alternative bestimmt darüber, ob es sich um einen ein- oder zweiseitigen t-Test handelt
  • paired bestimmt darüber, ob es sich um einen abhängigen oder unabhängigen t-Test handelt
  • conf.level gibt an, welches Signifikanzniveau man annimmt; standardmäßig ist dieses als \(0.95\) eingestellt, d.h. \(\alpha=0.05\)

Unabhängig, Zweiseitig

Für den unabhängigen zweiseitigen t-Test erstellen wir zunächst Beispieldaten.

gruppe1 <- c(55, 69, 64, 70, 75, 70, 83, 69, 75, 69)
gruppe2 <- c(61, 60, 62, 58, 75, 63, 52, 66, 59)

Nun führen wir den passenden t-Test durch.

t.test(gruppe1, gruppe2, alternative="two.sided", paired=FALSE, conf.level=0.95)

    Welch Two Sample t-test

data:  gruppe1 and gruppe2
t = 2.6014, df = 16.97, p-value = 0.01864
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
  1.534021 14.710424
sample estimates:
mean of x mean of y 
 69.90000  61.77778 

Aufgaben

In den allermeisten Fällen werden t-Tests heute nicht mehr als finales Kriterium genutzt. Viel eher werden sie zur ersten Orientierung eingesetzt, d.h. um eine Idee davon zu erhalten, ob Unterschiede eher zufällig vorliegen oder eben nicht. Daher setzen wir im Folgenden auch nur eine abgekürzte Version des Befehls ein:

t.test(var1, var2)

Finde nun heraus, ob die Unterschiede zwischen den folgenden Variablen signifikant sind. Checke vorher, ob die Daten normalverteilt sind. Sind sie nicht normalverteilt, musst du zusätzlich eine Logarithmierung für beide einbauen.

  • data_s$sDur[data_s$typeOfS=="nm"] & data_s$sDur[data_s$typeOfS=="pl"]
  • data_s$baseDur[data_s$typeOfS=="nm"] & data_s$baseDur[data_s$typeOfS=="pl"]
  • data_s$speakingRate[data_s$typeOfS=="nm"] & data_s$speakingRate[data_s$typeOfS=="pl"]
  • data_v$duration[data_v$vowel=="a"] & data_v$duration[data_v$vowel=="i"]
Lösung
shapiro.test(data_s$sDur[data_s$typeOfS=="nm"]) # normalverteilt
shapiro.test(data_s$sDur[data_s$typeOfS=="pl"]) # nicht normalverteilt

t.test(log(data_s$sDur[data_s$typeOfS=="nm"]), log(data_s$sDur[data_s$typeOfS=="pl"])) # p < 0.05

shapiro.test(data_s$baseDur[data_s$typeOfS=="nm"]) # normalverteilt
shapiro.test(data_s$baseDur[data_s$typeOfS=="pl"]) # nicht normalverteilt

t.test(log(data_s$baseDur[data_s$typeOfS=="nm"]), log(data_s$baseDur[data_s$typeOfS=="pl"])) # p = 0.35

shapiro.test(data_s$speakingRate[data_s$typeOfS=="nm"]) # nicht normalverteilt
shapiro.test(data_s$speakingRate[data_s$typeOfS=="pl"]) # normalverteilt

t.test(log(data_s$speakingRate[data_s$typeOfS=="nm"]), log(data_s$speakingRate[data_s$typeOfS=="pl"])) # p = 0.30

shapiro.test(data_v$duration[data_v$vowel=="a"]) # nicht normalverteilt
shapiro.test(data_v$duration[data_v$vowel=="i"]) # nicht normalverteilt

t.test(log(data_v$duration[data_v$vowel=="a"]), log(data_v$duration[data_v$vowel=="i"])) # p < 0.001

04 Chi-Quadrat-Test

Mit einem Chi-Quadrat-Test (\(\chi^2\), engl. Chi-square(d) test) kannst du bestimmen, ob zwei kategorische Variablen miteinander zusammenhängen.

Als Beispiel nutzen wir die Daten zu hair und eyes aus data_a. Zunächst erstellen wir eine Kreuztabelle, um eine Übersicht über die Daten zu erlangen:

table(data_a$hair, data_a$eyes)
          
           blue brown green
  blonde      3     7     3
  brunette    5    15     2
  red         1     3     1

Nun führen wir den Chi-Quadrat-Test durch:

chisq.test(data_a$hair, data_a$eyes)

    Pearson's Chi-squared test

data:  data_a$hair and data_a$eyes
X-squared = 1.4516, df = 4, p-value = 0.8352

Da \(p=0.84>0.05\) ist, hängen Haar- und Augenfarbe in unseren Daten nicht zusammen.

Aufgaben

Bestimme nun, ob andere Variablenkombinationen zusammenhängen:

  • data_s$folSeg & data_s$folType
  • data_a$gender & data_a$hair
  • data_a$glasses & data_a$eyes
  • data_a$hair & data_a$glasses
  • data_v$vowel & data_v$structure
Lösung
chisq.test(data_s$folSeg, data_s$folType) # p < 0.001

chisq.test(data_a$gender, data_a$hair) # p = 0.36
chisq.test(data_a$glasses, data_a$eyes) # p = 0.38
chisq.test(data_a$hair, data_a$glasses) # p = 0.92

chisq.test(data_v$vowel, data_v$structure) # p = 1

05 Wilcoxon-Mann-Whitney Test

Anders als t-Tests setzen Wilcoxon-Mann-Whitney Tests keine Normalverteilung der Daten voraus. In vielen Situationen ist diese Art des statistischen Tests also einfacher anwendbar als der t-Test.

Für ein Beispiel nutzen wir die Daten aus dem data.vokal-Dataframe.

shapiro.test(data_v$duration[data_v$vowel=="a"]) # nicht normalverteilt

    Shapiro-Wilk normality test

data:  data_v$duration[data_v$vowel == "a"]
W = 0.92143, p-value = 5.117e-05
shapiro.test(data_v$duration[data_v$vowel=="i"]) # nicht normalverteilt

    Shapiro-Wilk normality test

data:  data_v$duration[data_v$vowel == "i"]
W = 0.89247, p-value = 1.894e-06

Die Daten sind nicht normalverteilt, d.h. ein Wilcoxon-Mann-Whitney Test ist angebracht.

wilcox.test(data_v$duration[data_v$vowel=="a"], data_v$duration[data_v$vowel=="i"])

    Wilcoxon rank sum test with continuity correction

data:  data_v$duration[data_v$vowel == "a"] and data_v$duration[data_v$vowel == "i"]
W = 5649.5, p-value = 8.912e-07
alternative hypothesis: true location shift is not equal to 0

Da \(p<0.001<0.5\) beträgt, ist ein signifikanter Dauerunterschied für /a/ und /i/ nachgewiesen.

Aufgaben

Finde nun heraus, ob die Unterschiede zwischen den folgenden Variablen signifikant sind:

  • data_s$sDur[data_s$typeOfS=="nm"] & data_s$sDur[data_s$typeOfS=="pl"]
  • data_s$baseDur[data_s$typeOfS=="nm"] & data_s$baseDur[data_s$typeOfS=="pl"]
  • data_s$speakingRate[data_s$typeOfS=="nm"] & data_s$speakingRate[data_s$typeOfS=="pl"]
  • data_v$duration[data_v$vowel=="a"] & data_v$duration[data_v$vowel=="e"]
Lösung
wilcox.test(data_s$sDur[data_s$typeOfS=="nm"], data_s$sDur[data_s$typeOfS=="pl"]) # p < 0.05
wilcox.test(data_s$baseDur[data_s$typeOfS=="nm"], data_s$baseDur[data_s$typeOfS=="pl"]) # p = 0.68
wilcox.test(data_s$speakingRate[data_s$typeOfS=="nm"], data_s$speakingRate[data_s$typeOfS=="pl"]) # p = 0.18
wilcox.test(data_v$duration[data_v$vowel=="a"], data_v$duration[data_v$vowel=="e"]) # p < 0.001

06 AN(C)OVA

Mit einer analysis of variance können wir testen, ob sich die Level einer Variable abhängig von einer anderen Variable voneinander unterscheiden.

Im Beispiel testen wir nun, ob sich die Dauer verschiedener Vokale im Datenset data_v signifikant unterscheidet:

summary(aov(duration ~ vowel, data_v))
             Df Sum Sq Mean Sq F value   Pr(>F)    
vowel         4 0.0854 0.02135   5.998 0.000105 ***
Residuals   443 1.5771 0.00356                     
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Hierbei wird spezifiziert, dass duration abhängig von den Leveln des Faktors vowel analysiert werden soll. Der p-Wert gibt hierbei an, ob es Unterschiede in Dauer aufgrund der verschiedenen Vowel-Level gibt. Da \(p<0.001\) ist, gibt es in diesem Fall einen signifikanten Unterschied.

Hinweis: ANOVA und ANCOVA nutzen die gleiche aov Funktion in R.

Aufgaben

Finde nun heraus, ob es signifikante Unterschiede der ersten Variable in Abhängigkeit von der zweiten Variable gibt:

  • sDur ~ typeOfS (data_s)
  • sDur ~ folType (data_s)
  • duration ~ structure (data_v)
  • height ~ glasses (data_a)
  • height ~ eyes (data_a)
Lösung
summary(aov(sDur ~ typeOfS, data_s)) # p < 0.001

summary(aov(sDur ~ folType, data_s)) # p = 0.57


summary(aov(duration ~ structure, data_v)) # p < 0.001


summary(aov(height ~ glasses, data_a)) # p = 0.16

summary(aov(height ~ eyes, data_a)) # p = 0.40

07 Korrelation

Mit einer Korrelationsanalyse können wir bestimmen, ob die Verteilung zweier Variablen zusammenhängt. Hierbei muss unbedingt beachtet werden, dass Korrelation nicht mit Kausalität gleichzusetzen ist.

Für einfache Korrelationsmessungen nutzen wir in R den cor() Befehl. Wir nutzen das data_s-Datenset für ein Beispiel:

cor(data_s$sDur, data_s$baseDur)
[1] 0.4738338

Das Ergebnis dieses Korrelationstests ist \(\rho=0.47\), d.h. eine mittelstarke Korrelation liegt zwischen den Variablen vor.

Hinweis: Der Korrelationskoeffizient rho \(\rho\) wird oftmals durch den Buchstabend r angegeben.

Aufgaben

Finde nun heraus, ob es die folgenden Variablen miteinander korrelieren:

  • sDur ~ speakingRate (data_s)
  • sDur ~ googleFreq (data_s)
  • duration ~ rate (data_v)
  • age ~ height (data_a)
Lösung
cor(data_s$sDur, data_s$speakingRate) # r = -0.26
cor(data_s$sDur, data_s$googleFreq) # r = -0.12

cor(data_v$duration, data_v$rate) # r = -0.10

cor(data_a$age, data_a$height) # r = -0.21

Extra: Korrelation

Möchte man eine Vielzahl verschiedener Variablen auf Korrelation hin überprüfen, wird der oben vorgestellte Weg schnell mühselig. Daher kann man in diesem Fall folgenden Befehl nutzen, welcher auch die Korrelation von Faktoren berücksichtigen kann:

correlation_matrix(data = data_s, variables = c("sDur", "baseDur", "typeOfS", "speakingRate", "folType", "preC"))

Der correlation_matrix Befehl stammt aus dem SfL Package. Der obere Wert r gibt jeweils den Korrelationskoeffizienten an, den man für zwei numerische Variablen nutzen sollte. Ist mindestens eine der beiden Variablen nicht numerisch, nutzt man den unteren Korrelationskoeffizienten rs.

Aufgaben

Lies die Korrelationen für alle Variablen mit sDur vom Plot ab.

Lösung

Korrelation von sDur mit:

  • baseDur; \(\rho=0.47\)
  • typeOfS; \(\rho=0.21\)
  • speakingRate; \(\rho=-0.26\)
  • folType; \(\rho=-0.13\)
  • preC; \(\rho=-0.02\)

08 Weitere Übungen

Falls du noch Zeit hast oder einfach mehr üben möchtest, kannst du weitere Tests rechnen, z.B.:

  • Shapiro-Wilk Tests für kontinuierliche Variablen
  • t-Tests für kontinuierliche Variablen
  • Chi-Quadrat-Tests für kategorische Variablen
  • Wilcoxon-Mann-Whitney Test für kontinuierliche Variablen
  • ANOVA für kontiuierliche und kategorische Variablen
  • Korrelation für kontinuierliche Variablen

Die Erklärungen zu den einzelnen Variablen der Datensätze bringen dich sicherlich auf die eine oder andere Idee.