-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathExp_design_fast_1_sol.Rmd
267 lines (201 loc) · 7.91 KB
/
Exp_design_fast_1_sol.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
---
title: "Experimental Design II: replication and power exercise 1"
author: "Lieven Clement & Alexandre Segers"
date: "statOmics, Ghent University (https://statomics.github.io)"
output:
html_document:
code_download: yes
theme: cosmo
toc: yes
toc_float: yes
highlight: tango
number_sections: yes
pdf_document:
toc: true
number_sections: true
latex_engine: xelatex
---
<a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a>
```{r}
library(tidyverse)
```
# Power
The power of a test is defined as:
$$P(p <
\alpha | H_1)$$
This is the probability to reject the nulhypothesis at the significance level $\alpha$ given that the alternative hypothesis is true.
The power depends on:
- the real effect size in the population $\mathbf{L}^T\boldsymbol{\beta}$.
- the number of observations: SE and df.
- Choice of designpoints
- Choice of significance-level $\alpha$.
We will evaluate the power using simulation.
# Rodents
A biologist examined the effect of a fungal infection on the eating behavior of rodents.
Infected apples were offered to a group of eight rodents, and sterile apples were offered to a group of 4 rodents. The amount of grams of apples consumed per kg body weight are given in the dataset below.
```{r}
rodents <- data.frame(weight=c(11,33,48,34,112,369,64,44,177,80,141,332),group=as.factor(c(rep("treat",8),rep("ctrl",4))))
rodents
```
## Data exploratie
```{r}
rodents %>%
ggplot(aes(x=group,y=weight)) +
geom_boxplot(outlier.shape = NA) +
geom_jitter()
rodents %>%
ggplot(aes(sample = weight)) +
geom_qq() +
geom_qq_line() +
facet_wrap(~ group)
```
In the data exploration we do not have enough data to evaluate the assumptions.
Suppose that the assumptions are valid and that standard deviation in the population would be equal to the ones you observed in the experiment.
1. What is the power of the experiment if the effect size and standard deviation in the population would be equal to the ones you observed in the experiment
2. What would the power by if number of rodents would balanced in both groups
3. How many observations would you need to pick up the treatment effect with a power of 80%?
4. How many observations would you need to pick up the treatment effect of 60 g/kg with a power of 80%?
# Analyse of the data
We will model the data using a linear model with one dummy variable.
$$
y_i = \beta_0 + \beta_1 x_{t,i} +
\epsilon_i
$$
with $x_{p,i} = 0$ if the rodent is subjected the control treatment with sterile apples and $x_{t,i} = 1$ if rodent receives the treatment with infected apples.
- Estimated effect size?
The average difference amount of apples eaten in g/kg body weight between infected and sterile apples is:
$$
\hat \beta_1 = \bar y_t - \bar y_c
$$
- $H_0$: rodents eat consume on average the same amount of apples per kg body weight when they are fed with sterile or with infected apples.
- $H_1$: the average amount of apples in g/kg body weight is different when rodents are fed with sterile then as when they are fed with infected apples.
```{r}
lm1 <- lm(weight ~ group, rodents)
summary(lm1)
```
With the current study and under when we assume that the assumptions of the model hold, we conclude that the amount of apples that rodents on average consume does not differ significantly between the group that was fed with sterile apples and the group that was fed with infected apples.
# Power of the test to detect the same effect size as observed in our dataset with our experimental design?
## Simulation function
Function to simulate data similar to that of our experiment under our model assumptions.
```{r}
simFast <- function(form, data, betas, sd, contrasts, alpha = .05, nSim = 10000)
{
ySim <- rnorm(nrow(data)*nSim,sd=sd)
dim(ySim) <-c(nrow(data),nSim)
design <- model.matrix(form, data)
ySim <- ySim + c(design %*%betas)
ySim <- t(ySim)
### Fitting
fitAll <- limma::lmFit(ySim,design)
### Inference
varUnscaled <- c(t(contrasts)%*%fitAll$cov.coefficients%*%contrasts)
contrasts <- fitAll$coefficients %*%contrasts
seContrasts <- varUnscaled^.5*fitAll$sigma
tstats <- contrasts/seContrasts
pvals <- pt(abs(tstats),fitAll$df.residual,lower.tail = FALSE)*2
return(mean(pvals < alpha))
}
```
## Simulation
```{r}
betas <- lm1$coefficients
nSim <- 10000
form <- ~ group
sd <- sigma(lm1)
contrast <- limma::makeContrasts("grouptreat",levels = names(lm1$coefficients))
contrast
#contrast <- matrix(c(0,1),ncol=1)
#rownames(contrast) <- names(mod1$coefficients)
alpha <- 0.05
power <- simFast(form, rodents, betas, sd, contrasts = contrast, alpha = alpha, nSim = nSim)
power
```
We observe that the experiment is severly underpowered. We only have a power of `r round(power*100,1)`% to pick up the treatment effect.
# Power for a balanced design
```{r}
betas <- lm1$coefficients
nSim <- 10000
form <- ~ group
sd <- sigma(lm1)
contrast <- limma::makeContrasts("grouptreat",levels = names(lm1$coefficients))
n1 <- n2 <- nrow(rodents)/2
predictorData <- data.frame(group = rep(c("ctrl","treat"),c(n1,n2)) %>% as.factor)
powerBalanced <- simFast(form, predictorData, betas, sd, contrasts = contrast, alpha = alpha, nSim = nSim)
powerBalanced
```
We observe that the power is larger for the balanced design.
We could also have known this from formula of the standard error from the two-sample t-test.
$$
SE = \hat \sigma \sqrt{1/n1 + 1/n2}
$$
Indeed,
```{r}
sqrt(1/sum(rodents$group=="treat") + 1/sum(rodents$group=="ctrl"))
sqrt(1/n1 + 1/n1)
```
So the SE is larger when the design is not balanced.
# Required sample size to obtain a power of 90 %?
```{r}
set.seed(1400)
betas <- lm1$coefficients
nSim <- 10000
form <- ~ group
sd <- sigma(lm1)
alpha <- 0.05
contrast <- limma::makeContrasts("grouptreat",levels = names(lm1$coefficients))
power <- data.frame(n=seq(5,50,5),power=NA)
for (i in 1:nrow(power))
{
n1 <- n2 <- power$n[i]
predictorData <- data.frame(group = rep(c("ctrl","treat"),c(n1,n2)) %>% as.factor)
power$power[i] <- simFast(form, predictorData, betas, sd, contrasts = contrast, alpha = alpha, nSim = nSim)
}
power
```
```{r}
power %>%
ggplot(aes(x=n,y=power)) +
geom_line()
```
Through simulations we show that we need about 32-33 observations to obtain a power of about 90%.
This is similar to what we would obtain with the close form formula that can be applied for a two group design
```{r}
power.t.test(delta = lm1$coef[2], sd = sigma(lm1),power=.9)
```
# Impact of effect size
Suppose that we would like to pick up an effect size of $\beta_1 = 60 g/kg$.
how many samples would be required in each group to obtain a power of 90%?
Note, that
- we do a two-sided test so the sign of the effect size is arbitrary.
- the intercept in the power analysis is also arbitrary so we could also set it at 0.
```{r}
set.seed(1400)
betas <- c(0,60)
nSim <- 10000
form <- ~ group
sd <- sigma(lm1)
power2 <- data.frame(n=seq(5,100,5),power=NA)
alpha <- 0.05
contrast <- limma::makeContrasts("grouptreat",levels = names(lm1$coefficients))
for (i in 1:nrow(power2))
{
n1 <- n2 <- power2$n[i]
predictorData <- data.frame(group = rep(c("ctrl","treat"),c(n1,n2)) %>% as.factor)
power2$power[i] <- simFast(form, predictorData, betas, sd, contrasts = contrast, alpha = alpha, nSim = nSim)
}
power2
```
```{r}
power2 %>%
ggplot(aes(x=n,y=power)) +
geom_line() +
geom_hline(yintercept = .9, lty=2)
```
We observe that we need between 75-80 observations to obtain a power of 90%.
This is confirmed with the power functions for the two sample t-test.
```{r}
b1 = - 60
power = .9
power.t.test(d = b1, sd = sigma(lm1), type='two.sample',power = power)
```
Note, that we would require a much larger sample size. This is because the desired effect size that we would like to pick up is small compared to the variability (standard deviation) in the population.