Tag 4 Statistische Tests und Power
4.1 Lösung für Tag 3
4.2 Der zentrale Grenzwertsatz (CLT)
Von Verteilungen zu Verteilungen von Mittelwerten
Was wäre, wenn Johanna als Master Studentin nicht ganz so fleißig gewesen wäre, und statt 300 je Zell Typ nur je 30 mal gezählt hätte?
Der Einfachheit nehmen wir an, dass die 300 Zellen komplett repräsentativ für alle WT bzw. KO Zellen sind, also die Gesamtpopulation darstellen.
- Nun ziehen wir zufällig daraus je 30 Zellen.
- Das machen wir nun 1000 mal.
- Wie sieht nun die Verteilung der Mittelwerte aus?
4.2.1 Daten einlesen
Zunächst laden wir das Tidyverse und unsere Daten:
# load tidyverse
library(tidyverse)
# import data
<- read_csv("data/03_inclusion_bodies.csv")
data
# attach data, handle with CARE!
attach(data)
attach
macht die Spalten des Datensets (in unserem Fall ko and wt)
global verfügbar. Daher können wir im Folgenden
wt
statt data$wt
oder data["wt"]
schreiben.
Verwende
attach
mit Vorsicht! Denn die Reihenfolge der beiden Vektoren ist nun unabhängig voneinander. Operationen, die Du mit den Vektorenwt
undko
ausführst, beeinflussen nicht den jeweils anderen Vektor oder den zugrundeliegenden Data.framedata
.
4.2.2 Der einfache Fall
Für den einfachen Fall ziehen wir 30 Punkte aus einem der beiden Vektoren und berechnen den Mittelwert.
# sample n = 30 points from a vector
<- sample(wt, 30)
subset
# calculate mean
mean(subset)
## [1] 2.133333
4.2.3 Abstraktion für viele Fälle
Da wir diese Zeilen nicht 1000 mal tippen wollen schreiben wir eine Funktion,
die genau das tut. Sie nimmt einen Vektor (x
) und zieht n
Punkte daraus.
<- function(n, x) {
get_subset_mean <- sample(x, n)
subset mean(subset)
}
Die Funktion funktioniert:
get_subset_mean(2, wt)
## [1] 6
Mit der map
Funktion aus dem purrr
-Package rufen wir diese
Funktion nun 1000 mal auf uns speichern das Ergebnis in einem
Vektor, bestehend aus Kommazahlen (daher map_dbl
für
map double).
<- 1000
N <- map_dbl(1:N, ~ get_subset_mean(30, wt) ) Ms
4.2.4 Exkurs: Lambda-Funktionen
Das ~
-Symbol (Tilde) erstellt eine sogenannte lambda Funktion, also
eine Funktion, der wir keinen Namen geben, da wir sie nur einmal
brauchen. Im Kontext der Familie von map
Funktionen wird ~
übersetzt:
add_one <- function(x) x + 1
Ist equivalent zu
~ .x + 1
.
Hierbei heißt das Argument der Funktion immer .x
.
Die
lambda Funktion ~ get_subset_mean(30, wt)
nimmt nacheinander
die Zahlen in 1:N
als Eingabe, nennt sie .x
, aber verwendet
das Argument .x
überhaubt nicht. In unserem Fall bedeutet das also,
dass die Funktion get_subset_mean
bloß 1000 mal aufgerufen wird mit den Argumenten 30
und wt
.
4.2.5 Populationsverteilung vs. Verteilung der Mittelwerte
Mit großem n wird die Verteilung der Mittelwerte symmetrisch, obwohl die Populationsverteilung unsymmetrisch ist.
hist(Ms)
hist(wt)
Nach dem Central Limit Theorem folgen die Mittelwerte einer Normalverteilung. Dies lässt sich zeigen:
# show qqnorm of Ms
qqnorm(Ms)
qqline(Ms, col = "red")
4.2.6 Exkurs: Quantiles
Am Beispiel einer Normalverteilung zeigt
dnorm
die Wahrscheinlichkeitsdichteverteilung
(Im Englischen Probability Density Function, PDF).
curve(dnorm, -3, 3)
Abb. 4.1: Die Wahrscheinlichkeit, einen Wert zwischen z.B. -1 und 1 zu ziehen, entspricht dem Integral der Funktion in diesem Bereich.
Wenn wir nun das Integral von \(-\infty\) bis \(x\) berechnen erhalten wir
die kumulative Wahrscheinlichkeitsfunktion pnorm
.
curve(pnorm, -3, 3)
Abb. 4.2: pnorm von x ist also die Wahrscheinlichkeit, einen Wert kleiner oder gleich x aus dnorm zu ziehen.
qnomr
, die Quantil-Funktion,
ist nun die Inverse dieser Funkion, hat also die Achsen vertauscht.
curve(qnorm, 0, 1)
4.3 Die T-Verteilung
Der zentrale Grenzwertsatz gilt erst bei großen sample sizes. Darunter ist die Verteilung der Mittelwerte an den Rändern dicker, als eine Normalverteilung.
Daher verwenden wir (sicherheitshalber) für die meisten Daten und statistischen Tests die T-Verteilung, nicht die Normalverteilung.
Für 3 Freiheitsgrade:
curve(dnorm, -3, 3)
<- function(x) dt(x, df = 3)
tdist curve(tdist, -3, 3, add = TRUE, col = "red")
Abb. 4.3: T-Verteilung in Rot
Für 30 Freiheitsgrade
curve(dnorm, -3, 3)
<- function(x) dt(x, df = 30)
tdist curve(tdist, -3, 3, add = TRUE, col = "red")
4.3.1 Konfidenz Intervalle (CI)
Gleichermaßen können wir mit der t-Verteilung 95% Konfidenzintervalle berechnen.
Das 95% Konfidenzintervall eines Sample-Mittelwerts umschließt den wahren Mittelwert (den Mittelwert der Gesamtpopulation) in 95% der Fälle (wenn Du das Experiment unendlich oft wiederholen würdest).
# show hist of Ms
hist(Ms)
# add line for true mean of wt
abline(v = mean(wt), col = "red", lwd = 3)
Abb. 4.4: Wahrer Mittelwert in Rot
# use t.test for conf.int
<- sample(wt, 30)
subset mean(subset)
## [1] 3.166667
<- t.test(subset)$conf.int
lims
hist(subset, breaks = 20)
abline(v = lims[1], col = "red")
abline(v = lims[2], col = "red")
4.4 Signifikanztests
Signifikanztests beantworten die Frage:
Unter der Annahme, dass es zwischen zwei (oder mehr) Gruppen keinen Unterschied gibt (also sie aus der gleichen Verteilung stammen), wie wahrscheinlich ist es dann, einen so großen, oder größeren, Unterschied, wie beobachtet, zu finden?
4.4.1 Students T-Test
Für normalverteilte Daten verwenden wir den Students T-Test.
t.test(wt, ko)
##
## Welch Two Sample t-test
##
## data: wt and ko
## t = -26.929, df = 476.21, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -13.19393 -11.39940
## sample estimates:
## mean of x mean of y
## 3.043333 15.340000
<- sample(wt, 3)
subset_wt <- sample(ko, 3)
subset_ko t.test(subset_wt, subset_ko)
##
## Welch Two Sample t-test
##
## data: subset_wt and subset_ko
## t = -6.8224, df = 2.6162, p-value = 0.009833
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -16.081856 -5.251477
## sample estimates:
## mean of x mean of y
## 1.00000 11.66667
4.4.2 Wilcoxon Rank Sum Test
Sind unsere Daten nicht normalverteilt, wie es hier der Fall ist, ist ein sogenannter nicht-parametrischer Test angebracht. Diese Tests machen nicht die Annahme der Normalität.
Der Wilcoxon Rank Sum Test (Auch Mann-Whitney U Test genannt) wandelt die eigentlichen Werte der Datenpunkte zunächst in Ränge um. Also:
“Der wievieltniedrigste Punkt ist es?”
Beispiel:
<- c(1, 2, 20, 1239132, 3, 5)
x rank(x)
## [1] 1 2 5 6 3 4
Und an unseren Daten:
wilcox.test(wt, ko)
##
## Wilcoxon rank sum test with continuity
## correction
##
## data: wt and ko
## W = 4707.5, p-value < 2.2e-16
## alternative hypothesis: true location shift is not equal to 0
4.5 Type I und Type II Errors
- Type I: False Positives (rejection of a true null hypothesis)
- Type II: False Negatives (non-rejection of false null hypothesis)
4.5.1 Type I: False Positives
Ein Typ I Fehler würde bedeuten, dass wir sagen, ein Unterschied zwischen den Gruppen existiere, obwohl alle Werte aus der gleichen Verteilung stammen und daher kein Unterschied besteht.
Bei einem P-Value von \(\leq\) 0.05 (= 5 %) wird typischerweise gesagt, dass ein “statistisch signifikanter” Unterschied besteht. Mit diesem typischen Cutoff von 0.05 akzeptieren wir also, allein durch unsere Definition, bereits (mindestens) 5 % falsch Positive.
Dieser Cutoff, das Signifikanzlevel, wird auch \(\alpha\) genannt.
\[\alpha=\text{Type I error rate}\]
curve(dnorm, -3 , 3)
# define n
<- 3
n
# draw twice from the same normal distributions
<- rnorm(n)
draw1 <- rnorm(n)
draw2
# do the t.test
t.test(draw1, draw2)
##
## Welch Two Sample t-test
##
## data: draw1 and draw2
## t = -0.31189, df = 3.0148, p-value = 0.7754
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -3.651341 2.997886
## sample estimates:
## mean of x mean of y
## -0.1263381 0.2003894
# do the rank sum test
wilcox.test(draw1, draw2)
##
## Wilcoxon rank sum exact test
##
## data: draw1 and draw2
## W = 4, p-value = 1
## alternative hypothesis: true location shift is not equal to 0
Teste diesen Code mit unterschiedlichen Werten für n
.
4.5.2 Type II errors
Wenn zwischen zwei Gruppen ein tatsächlicher Unterschied besteht, wir aber bei unserem Test ein nicht signifikantes Ergebnis erhalten, begehen wir einen Fehler vom Typ II.
Ein Typ II Fehler ist also ein falsch negatives Ergebnis.
\[\beta=\text{Type II error rate}\]
# define n
<- 15
n
# draw from different normal distributions
<- rnorm(n, 0, 1)
draw1 <- rnorm(n, 1, 1)
draw2
# convert to tibble, pivot_longer, plot points
tibble(draw1, draw2) %>%
pivot_longer(c(1,2)) %>%
ggplot(aes(name, value, group = 1)) +
geom_jitter(width = 0.2) +
stat_summary(geom = "line", fun.y = mean, lwd = 1, lty = 2) +
stat_summary(geom = "point", fun.y = mean, color = "red", size = 2)
# do the t.test
t.test(draw1, draw2)
##
## Welch Two Sample t-test
##
## data: draw1 and draw2
## t = -2.5888, df = 27.319, p-value = 0.01525
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## -1.9133144 -0.2219188
## sample estimates:
## mean of x mean of y
## 0.06255136 1.13016800
# do the rank sum test
wilcox.test(draw1, draw2)
##
## Wilcoxon rank sum exact test
##
## data: draw1 and draw2
## W = 57, p-value = 0.0209
## alternative hypothesis: true location shift is not equal to 0
4.5.3 Statistical Power
Als statistische Power bezeichnen wir die Wahrscheinlichkeit eines Tests, einen wahren Unterschied zwischen Gruppen bei dem gewählten \(\alpha\) auch tatsächlich als statistisch signifikant zu kennzeichnen und damit ein wahr positives Ergebnis zu produzieren.
\[Power = 1-\beta\]
Für den T-Test können wir in R die folgende Funktion verwenden, die uns hier beispielsweise die Frage beantwortet: “Wie viele Proben muss ich pro Gruppe (mindestens) nehmen, um einen erwarteten Unterschied der Mittelwerte von 1 mit einer Standardabweichung von 1 in 80% der Fälle auch tatsächlich als solchen zu erkennen?”
# show power.t.test
power.t.test(delta = 1, sd = 1, power = 0.8)
##
## Two-sample t test power calculation
##
## n = 16.71477
## delta = 1
## sd = 1
## sig.level = 0.05
## power = 0.8
## alternative = two.sided
##
## NOTE: n is number in *each* group
4.6 Probleme
4.6.1 The Jelly Bean Problem (Multiple Testing)
Die False Discovery Rate (FDA) kontrollieren:
- Bonferroni Korrektur
# show p.adjust
p.adjust(c(0.05, 0.0001, 0.003323, 0.7), method = "bonferroni")
## [1] 0.200000 0.000400 0.013292 1.000000
Jeder P-Value wird mutipliziert mit der Zahl der Tests
- Benjamini-Hochberg Prozedur
- Ordne alle p-values in aufsteigender Reihenfolge
- Wähle eine FDR (\(q\)) und nenne die Anzahl deiner Tests \(m\)
- Finde den größten p-value für den gilt: \(p \leq iq/m\) mit dem Index des p-values \(i\).
# show p.adjust for BH
p.adjust(c(0.05, 0.0001, 0.003323, 0.7), method = "BH")
## [1] 0.06666667 0.00040000 0.00664600 0.70000000
4.6.2 The Base Rate Fallacy
Beispiel: Mammogramm
- Sensitivity = Power = true positive rate
- Specificity = true negative rate = \(1-\alpha\)
# calculate
<- 1000
total <- 10
positives <- total - positives
negatives <- 0.9
sensitivity <- 1 - 0.08
specificity <- sensitivity * positives
true_positives <- (1 - specificity) * negatives
false_positives <- true_positives / (true_positives + false_positives)
p_positive p_positive
## [1] 0.1020408
4.6.3 Resourcen
- Statistics Done Wrong: https://www.statisticsdonewrong.com/
- Intuitive Biostatistics, auch in der Uni-Bib: https://katalog.ub.uni-heidelberg.de/cgi-bin/titel.cgi?katkey=68260114&sess=050a1316767b181982c9bce94283e9ae&query=Intuitive%20Biostatistics
- https://www.graphpad.com/guides/prism/8/statistics/index.htm
4.7 Übungen
4.7.1 Zeige die folgenden Statements anhand von Simulationen in R
4.7.1.1 Wenn Du die Sample Size n erhöhst, verringert sich der Standard Error of the Mean mit der Wurzel von n.
- Ziehe 10 Zellen aus dem wt (oder ko) Vektor
- Berechne den Mittelwert
- Wiederhole das Ganze 1000 mal
- Berechne die SD der 1000 Mittelwerte
- Ziehe nun 40 statt 10 Zellen und wiederhole die Schritte
- Schreibe eine Funktion, die n Zellen zieht, die Schritte ausführt und die SD ausgibt
- Füttere die Zahlen von 1 bis 100 in die Funktion (mit map_dbl) und plotte das Ergebnis
4.7.1.2 Lösung
library(tidyverse)
read_csv("data/03_inclusion_bodies.csv") %>% attach()
<- sample(wt, 10)
draw mean(draw)
## [1] 3.5
<- function(x, n) {
get_sample_mean <- sample(x, n, replace = TRUE)
draw mean(draw)
}
get_sample_mean(wt, 10)
## [1] 3.9
<- 1000
N <- map_dbl(1:N, ~ get_sample_mean(wt, 10) )
many_means sd(many_means)
## [1] 1.245121
<- map_dbl(1:N, ~get_sample_mean(wt, 40))
many_means sd(many_means)
## [1] 0.6121342
# explain default arguments and scoping
<- function(n, x, N = 1000) {
get_sd_of_many_means <- map_dbl(1:N, ~get_sample_mean(x, n))
many_means sd(many_means)
}
<- 100
n_max <- map_dbl(1:n_max, get_sd_of_many_means, x = wt) sds_by_n
plot(x = 1:n_max,
y = sds_by_n, type = "p")
curve(sd(wt)/sqrt(x), add = TRUE, col = "red")
# talk about difference between sample sd and population sd
4.7.1.3 Ein 95% Konfidenzintervall eines Samples enthält den Populationsmittelwert mit einer Wahrscheinlichkeit von 95%.
- Ziehe 30 Zellen aus dem wt (oder ko) Vektor
- Berechne die Limits des CI (Confidence Interval)
- Schreibe eine Funktion, oben genanntes tut und führe sie 1000 mal aus.
- Schreibe eine Funktion, die testet, ob ein Set an Limits den wahren Mittelwert einschließt
- Wende sie auf die 1000 Sets der Limits an
- Wie oft (prozentual) erhältst du TRUE?
4.7.1.4 Lösung
<- sample(wt, 30) draw
<- t.test(draw) test_results
test_results
##
## One Sample t-test
##
## data: draw
## t = 3.9747, df = 29, p-value = 0.0004285
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 1.165051 3.634949
## sample estimates:
## mean of x
## 2.4
summary(test_results)
## Length Class Mode
## statistic 1 -none- numeric
## parameter 1 -none- numeric
## p.value 1 -none- numeric
## conf.int 2 -none- numeric
## estimate 1 -none- numeric
## null.value 1 -none- numeric
## stderr 1 -none- numeric
## alternative 1 -none- character
## method 1 -none- character
## data.name 1 -none- character
str(test_results)
## List of 10
## $ statistic : Named num 3.97
## ..- attr(*, "names")= chr "t"
## $ parameter : Named num 29
## ..- attr(*, "names")= chr "df"
## $ p.value : num 0.000428
## $ conf.int : num [1:2] 1.17 3.63
## ..- attr(*, "conf.level")= num 0.95
## $ estimate : Named num 2.4
## ..- attr(*, "names")= chr "mean of x"
## $ null.value : Named num 0
## ..- attr(*, "names")= chr "mean"
## $ stderr : num 0.604
## $ alternative: chr "two.sided"
## $ method : chr "One Sample t-test"
## $ data.name : chr "draw"
## - attr(*, "class")= chr "htest"
$conf.int test_results
## [1] 1.165051 3.634949
## attr(,"conf.level")
## [1] 0.95
<- function(x, n) {
get_sample_ci <- sample(x, n, replace = TRUE)
draw t.test(draw)$conf.int
}
get_sample_ci(wt, 30)
## [1] 1.272275 3.727725
## attr(,"conf.level")
## [1] 0.95
<- map(1:1000, ~get_sample_ci(wt, 30)) CIs
head(CIs)
## [[1]]
## [1] 1.319300 4.147366
## attr(,"conf.level")
## [1] 0.95
##
## [[2]]
## [1] 1.55864 5.24136
## attr(,"conf.level")
## [1] 0.95
##
## [[3]]
## [1] 1.564104 4.502562
## attr(,"conf.level")
## [1] 0.95
##
## [[4]]
## [1] 1.402216 3.997784
## attr(,"conf.level")
## [1] 0.95
##
## [[5]]
## [1] 1.211124 2.588876
## attr(,"conf.level")
## [1] 0.95
##
## [[6]]
## [1] 2.414082 6.319252
## attr(,"conf.level")
## [1] 0.95
# explain list subsetting
1] CIs[
## [[1]]
## [1] 1.319300 4.147366
## attr(,"conf.level")
## [1] 0.95
1]] CIs[[
## [1] 1.319300 4.147366
## attr(,"conf.level")
## [1] 0.95
1]][1] CIs[[
## [1] 1.3193
<- function(limits, true_mean) {
test_ci 1] < true_mean & limits[2] > true_mean
limits[ }
# sidenote
# note difference between & and &&
c(TRUE, TRUE) & c(FALSE, TRUE)
## [1] FALSE TRUE
c(TRUE, TRUE) && c(FALSE, TRUE)
## [1] FALSE
<- map_lgl(CIs, test_ci, true_mean = mean(wt))
results head(results)
## [1] TRUE TRUE TRUE TRUE FALSE TRUE
mean(results)
## [1] 0.936
# talk about organisation of code
# source("test.R")
4.7.1.5 Weitere Hinweise
# check out
?map# for the subtle differences between:
map(1:100, ~ .x + 1)
## [[1]]
## [1] 2
##
## [[2]]
## [1] 3
##
## [[3]]
## [1] 4
##
## [[4]]
## [1] 5
##
## [[5]]
## [1] 6
##
## [[6]]
## [1] 7
##
## [[7]]
## [1] 8
##
## [[8]]
## [1] 9
##
## [[9]]
## [1] 10
##
## [[10]]
## [1] 11
##
## [[11]]
## [1] 12
##
## [[12]]
## [1] 13
##
## [[13]]
## [1] 14
##
## [[14]]
## [1] 15
##
## [[15]]
## [1] 16
##
## [[16]]
## [1] 17
##
## [[17]]
## [1] 18
##
## [[18]]
## [1] 19
##
## [[19]]
## [1] 20
##
## [[20]]
## [1] 21
##
## [[21]]
## [1] 22
##
## [[22]]
## [1] 23
##
## [[23]]
## [1] 24
##
## [[24]]
## [1] 25
##
## [[25]]
## [1] 26
##
## [[26]]
## [1] 27
##
## [[27]]
## [1] 28
##
## [[28]]
## [1] 29
##
## [[29]]
## [1] 30
##
## [[30]]
## [1] 31
##
## [[31]]
## [1] 32
##
## [[32]]
## [1] 33
##
## [[33]]
## [1] 34
##
## [[34]]
## [1] 35
##
## [[35]]
## [1] 36
##
## [[36]]
## [1] 37
##
## [[37]]
## [1] 38
##
## [[38]]
## [1] 39
##
## [[39]]
## [1] 40
##
## [[40]]
## [1] 41
##
## [[41]]
## [1] 42
##
## [[42]]
## [1] 43
##
## [[43]]
## [1] 44
##
## [[44]]
## [1] 45
##
## [[45]]
## [1] 46
##
## [[46]]
## [1] 47
##
## [[47]]
## [1] 48
##
## [[48]]
## [1] 49
##
## [[49]]
## [1] 50
##
## [[50]]
## [1] 51
##
## [[51]]
## [1] 52
##
## [[52]]
## [1] 53
##
## [[53]]
## [1] 54
##
## [[54]]
## [1] 55
##
## [[55]]
## [1] 56
##
## [[56]]
## [1] 57
##
## [[57]]
## [1] 58
##
## [[58]]
## [1] 59
##
## [[59]]
## [1] 60
##
## [[60]]
## [1] 61
##
## [[61]]
## [1] 62
##
## [[62]]
## [1] 63
##
## [[63]]
## [1] 64
##
## [[64]]
## [1] 65
##
## [[65]]
## [1] 66
##
## [[66]]
## [1] 67
##
## [[67]]
## [1] 68
##
## [[68]]
## [1] 69
##
## [[69]]
## [1] 70
##
## [[70]]
## [1] 71
##
## [[71]]
## [1] 72
##
## [[72]]
## [1] 73
##
## [[73]]
## [1] 74
##
## [[74]]
## [1] 75
##
## [[75]]
## [1] 76
##
## [[76]]
## [1] 77
##
## [[77]]
## [1] 78
##
## [[78]]
## [1] 79
##
## [[79]]
## [1] 80
##
## [[80]]
## [1] 81
##
## [[81]]
## [1] 82
##
## [[82]]
## [1] 83
##
## [[83]]
## [1] 84
##
## [[84]]
## [1] 85
##
## [[85]]
## [1] 86
##
## [[86]]
## [1] 87
##
## [[87]]
## [1] 88
##
## [[88]]
## [1] 89
##
## [[89]]
## [1] 90
##
## [[90]]
## [1] 91
##
## [[91]]
## [1] 92
##
## [[92]]
## [1] 93
##
## [[93]]
## [1] 94
##
## [[94]]
## [1] 95
##
## [[95]]
## [1] 96
##
## [[96]]
## [1] 97
##
## [[97]]
## [1] 98
##
## [[98]]
## [1] 99
##
## [[99]]
## [1] 100
##
## [[100]]
## [1] 101
# and
<- function(x) x + 1
add_one map(1:100, add_one)
## [[1]]
## [1] 2
##
## [[2]]
## [1] 3
##
## [[3]]
## [1] 4
##
## [[4]]
## [1] 5
##
## [[5]]
## [1] 6
##
## [[6]]
## [1] 7
##
## [[7]]
## [1] 8
##
## [[8]]
## [1] 9
##
## [[9]]
## [1] 10
##
## [[10]]
## [1] 11
##
## [[11]]
## [1] 12
##
## [[12]]
## [1] 13
##
## [[13]]
## [1] 14
##
## [[14]]
## [1] 15
##
## [[15]]
## [1] 16
##
## [[16]]
## [1] 17
##
## [[17]]
## [1] 18
##
## [[18]]
## [1] 19
##
## [[19]]
## [1] 20
##
## [[20]]
## [1] 21
##
## [[21]]
## [1] 22
##
## [[22]]
## [1] 23
##
## [[23]]
## [1] 24
##
## [[24]]
## [1] 25
##
## [[25]]
## [1] 26
##
## [[26]]
## [1] 27
##
## [[27]]
## [1] 28
##
## [[28]]
## [1] 29
##
## [[29]]
## [1] 30
##
## [[30]]
## [1] 31
##
## [[31]]
## [1] 32
##
## [[32]]
## [1] 33
##
## [[33]]
## [1] 34
##
## [[34]]
## [1] 35
##
## [[35]]
## [1] 36
##
## [[36]]
## [1] 37
##
## [[37]]
## [1] 38
##
## [[38]]
## [1] 39
##
## [[39]]
## [1] 40
##
## [[40]]
## [1] 41
##
## [[41]]
## [1] 42
##
## [[42]]
## [1] 43
##
## [[43]]
## [1] 44
##
## [[44]]
## [1] 45
##
## [[45]]
## [1] 46
##
## [[46]]
## [1] 47
##
## [[47]]
## [1] 48
##
## [[48]]
## [1] 49
##
## [[49]]
## [1] 50
##
## [[50]]
## [1] 51
##
## [[51]]
## [1] 52
##
## [[52]]
## [1] 53
##
## [[53]]
## [1] 54
##
## [[54]]
## [1] 55
##
## [[55]]
## [1] 56
##
## [[56]]
## [1] 57
##
## [[57]]
## [1] 58
##
## [[58]]
## [1] 59
##
## [[59]]
## [1] 60
##
## [[60]]
## [1] 61
##
## [[61]]
## [1] 62
##
## [[62]]
## [1] 63
##
## [[63]]
## [1] 64
##
## [[64]]
## [1] 65
##
## [[65]]
## [1] 66
##
## [[66]]
## [1] 67
##
## [[67]]
## [1] 68
##
## [[68]]
## [1] 69
##
## [[69]]
## [1] 70
##
## [[70]]
## [1] 71
##
## [[71]]
## [1] 72
##
## [[72]]
## [1] 73
##
## [[73]]
## [1] 74
##
## [[74]]
## [1] 75
##
## [[75]]
## [1] 76
##
## [[76]]
## [1] 77
##
## [[77]]
## [1] 78
##
## [[78]]
## [1] 79
##
## [[79]]
## [1] 80
##
## [[80]]
## [1] 81
##
## [[81]]
## [1] 82
##
## [[82]]
## [1] 83
##
## [[83]]
## [1] 84
##
## [[84]]
## [1] 85
##
## [[85]]
## [1] 86
##
## [[86]]
## [1] 87
##
## [[87]]
## [1] 88
##
## [[88]]
## [1] 89
##
## [[89]]
## [1] 90
##
## [[90]]
## [1] 91
##
## [[91]]
## [1] 92
##
## [[92]]
## [1] 93
##
## [[93]]
## [1] 94
##
## [[94]]
## [1] 95
##
## [[95]]
## [1] 96
##
## [[96]]
## [1] 97
##
## [[97]]
## [1] 98
##
## [[98]]
## [1] 99
##
## [[99]]
## [1] 100
##
## [[100]]
## [1] 101
# and
map_dbl(1:100, add_one)
## [1] 2 3 4 5 6 7 8 9 10 11 12 13
## [13] 14 15 16 17 18 19 20 21 22 23 24 25
## [25] 26 27 28 29 30 31 32 33 34 35 36 37
## [37] 38 39 40 41 42 43 44 45 46 47 48 49
## [49] 50 51 52 53 54 55 56 57 58 59 60 61
## [61] 62 63 64 65 66 67 68 69 70 71 72 73
## [73] 74 75 76 77 78 79 80 81 82 83 84 85
## [85] 86 87 88 89 90 91 92 93 94 95 96 97
## [97] 98 99 100 101
# especially the meaning of ~ (speak: lambda)
map(1:5, ~ print("hi"))
## [1] "hi"
## [1] "hi"
## [1] "hi"
## [1] "hi"
## [1] "hi"
## [[1]]
## [1] "hi"
##
## [[2]]
## [1] "hi"
##
## [[3]]
## [1] "hi"
##
## [[4]]
## [1] "hi"
##
## [[5]]
## [1] "hi"
# more examples
map(1:10, paste, "hi")
## [[1]]
## [1] "1 hi"
##
## [[2]]
## [1] "2 hi"
##
## [[3]]
## [1] "3 hi"
##
## [[4]]
## [1] "4 hi"
##
## [[5]]
## [1] "5 hi"
##
## [[6]]
## [1] "6 hi"
##
## [[7]]
## [1] "7 hi"
##
## [[8]]
## [1] "8 hi"
##
## [[9]]
## [1] "9 hi"
##
## [[10]]
## [1] "10 hi"
<- function(x) x %% 2 == 0
is_even map_lgl(1:10, is_even)
## [1] FALSE TRUE FALSE TRUE FALSE TRUE FALSE TRUE
## [9] FALSE TRUE
# Note: Often, you don't need a map function
# Because many functions in R are vectorised by default:
<- 1:10
x <- 1:10
y # thus, just write
+ y x
## [1] 2 4 6 8 10 12 14 16 18 20
# instead of
map2_dbl(x,y, `+`)
## [1] 2 4 6 8 10 12 14 16 18 20
4.7.2 Veranschauliche die folgenden Konzepte anhand von Simulationen auf den vorliegenden Daten
4.7.2.1 Sensitivity: Wie groß ist die Wahrscheinlichkeit abhängig von der Sample Size n mit einem Wilcoxon Rank Sum Test tatsächlich einen p-value <= 0.05 zu erhalten, wenn ein Unterschied existiert?
- Ziehe 1000 mal ein Sample von 30 je aus wt und ko und teste auf Signifikanz
- Wie viele der 1000 Versuche sind statistisch signifikant?
- Wie verändert sich diese Zahl, wenn 10 statt 30 gezogen werden?
4.7.2.2 Lösung
<- function(n) {
test_samle_wilcox <- sample(wt, n, replace = TRUE)
draw_wt <- sample(ko, n, replace = TRUE)
draw_ko wilcox.test(draw_wt, draw_ko, exact = FALSE)$p.value
}
<- map_dbl(1:1000, ~test_samle_wilcox(30)) many_p_values
hist(many_p_values)
<- map_dbl(1:1000, ~test_samle_wilcox(10)) many_p_values
hist(many_p_values)
<- map_dbl(1:1000, ~test_samle_wilcox(4)) many_p_values
hist(many_p_values)
= 0.05
alpha mean(many_p_values <= alpha)
## [1] 0.642
# talk about power, effect size, difference between wilcox and t-test
4.7.2.3 Specificity: Unter der Voraussetzung, dass kein Unterschied zwischen den Bedingungen vorliegt, wie groß ist die Wahrscheinlichkeit, dennoch ein statistisch signifikantes Ergebnis zu erhalten?
- Stell dir vor, alle Zellen seien wie wt-Zellen
- Ziehe zwei mal 30 aus den wt-Zellen und lasse einen Wilcoxon Rank Sum Test laufen
- Widerhole das das Prozedere 1000 mal
- Wie oft ist das Ergebnis statistisch signifikant?
4.7.2.4 Lösung
<- function(n) {
test_same_wilcox <- sample(wt, n, replace = TRUE)
draw_wt <- sample(wt, n, replace = TRUE)
draw_ko wilcox.test(draw_wt, draw_ko, exact = FALSE)$p.value
}
<- map_dbl(1:1000, ~test_same_wilcox(30)) many_p_values
hist(many_p_values)
= 0.05
alpha mean(many_p_values <= alpha)
## [1] 0.065
# this is what we would expect from p-values!
4.7.2.5 Resource zu p-value Histogrammen
http://varianceexplained.org/statistics/interpreting-pvalue-histogram/