写在前面
R语言在进行统计分析和数据处理方面具有多种优势,在R语言中进行功效分析(power analysis)同样很方便,R环境中有pwr、powerAnalysis、simr等包可支持功效分析,结合其可视化能力及与其它方法整合的灵活性,为R语言中的功效分析提供了良好的生态。
更多R语言教程和测试数据可见:R语言基础学习手册
什么是功效分析
当不知道一个研究需要多少个受试者(样本量)或不清楚当一个研究有n个样本量时值不值得做时,功效分析可以解决问题。
功效分析的主要功能:
1.在给定置信度的情况下,判断检测到给定效应值所需的样本量。
2.在给定置信度的情况下,计算在某样本量内能检测到给定效应值的概率,若概率过小则需要修改或放弃研究。
10.1 假设检验
10.1.1 基本概念
1)样本量:实验设计中每组中的观测值数量;
2)显著性水平:一般设置为0.05,当小于0.05,拒绝原假设;
3)功效:通过I型减去II型错误的概率来定义,一般使用90%或95%(即0.9或0.95)。可以理解为真实效应发生的概率;
4)效应值:指在备择或研究假设下效应的量。效应值的表达依赖于假设检验中使用的方法。
这四个统计量紧密相关,得知其中的3个即可推算出第4个。
关于假设检验的理解见P229.
10.2 用pwr包做功效分析
10.2.1 t检验
10.2.1.1 语法
pwr.t.test(n=,d=,sig.level=,power=,alternative=)
n:样本大小(可选),如果未指定,则需要通过其他参数计算得出。
d:效应值,即标准化的均值之差,公式为(mean1-mean2)/公共误差的标准差。
sig.level:显著性水平,默认为0.05,即5%。
power:功效水平,一般用0.9或0.95。
alternative:指统计检验是双侧检验("two.sided")还是单侧检验("less"和"greater"),默认为双侧检验。
10.2.1.2 举例
随机招募若干受试者,随机分为2组,一组为受试者边打手机边驾驶,二组为相同的驾驶但不打手机。评估每个受试者的总体反应时间。
1)已知:反应时间有1.25s的标准差,1s的反应时间是差值是巨大的,则d=1/1.25=0.8.设置sig.level=0.05,power=0.9。求需要多少样本量?
library(pwr)
## Warning: 程辑包'pwr'是用R版本4.3.2 来建造的
pwr.t.test(d=0.8,sig.level=0.05,power=0.9,alternative="two.sided")
##
## Two-sample t test power calculation
##
## n = 33.82555
## d = 0.8
## sig.level = 0.05
## power = 0.9
## alternative = two.sided
##
## NOTE: n is number in *each* group
结果可知:至少每组需要34个样本量即34人参加该试验。
2)我们想检测到总体均值0.5个标准差的差异,并将误报差异的概率限制在1%内,此外只有40名受试者,在该研究中,能检测到这么大总体均值差异的概率是多少?(置信区间)
library(pwr)
pwr.t.test(d=0.5,sig.level=0.01,n=20,alternative="two.sided")
##
## Two-sample t test power calculation
##
## n = 20
## d = 0.5
## sig.level = 0.01
## power = 0.1439551
## alternative = two.sided
##
## NOTE: n is number in *each* group
结果表明:14%,即有86%的可能会错过要寻找的效应值。
注:这里默认不同组的n相等,若n不相等则:
library(pwr)
pwr.t2n.test(n1=,n2=,d=,sig.level=,alternative=)
n1和n2分别是两组的样本量,其他参数含义与pwr.t.test()相同。
10.2.2 方差分析
10.2.2.1 语法
library(pwr)
pwr.anova.test(k=,n=,f=,sig.level=,power = )
k:组的个数,几个组
n:各组样本量
f:效应值
10.2.2.2 举例
对5个组做单因素方差分析,要达到0.8的功效,效应值为0.25,选择0.05的显著性水平,计算各组需要的样本量:
library(pwr)
pwr.anova.test(k=5,f=0.25,sig.level=0.05,power =0.8 )
##
## Balanced one-way analysis of variance power calculation
##
## k = 5
## n = 39.1534
## f = 0.25
## sig.level = 0.05
## power = 0.8
##
## NOTE: n is number in each group
需要的样本量为:5x39=195.
10.2.3 相关性
pwr.r.test()函数可以对相关系数检验进行功效分析。
10.2.3.1 语法
library(pwr)
pwr.r.test(n=,r=,sig.level=,power =,alternative = )
n:观测值数目
r:效应值(通过线性相关系数衡量),也可以理解为相关性值
power:功效水平
alternative:指定显著性检验是双侧检验("two.sided")还是单侧检测("less"或"greater")。
"two.sided"(默认值):双侧检验。在双侧检验中,备择假设是相关性不等于零。例如,备择假设可以是相关性大于零或小于零。
"less":左侧检验。在左侧检验中,备择假设是相关性小于零。
"greater":右侧检验。在右侧检验中,备择假设是相关性大于零。
10.2.3.2 举例
假设正在研究抑郁与孤独的关系,我们的零假设和研究假设为:
H0:P<0.25和H1:P>0.25
P是两个心理变量的总体相关性大小,设置显著水平为0.05,而且如果H0是错误的,我们想有90%的信心拒绝H0,那么研究需要多少观测值?
library(pwr)
pwr.r.test(r=0.25,sig.level=0.05,power =0.9,alternative = "greater")
##
## approximate correlation power calculation (arctangh transformation)
##
## n = 133.2803
## r = 0.25
## sig.level = 0.05
## power = 0.9
## alternative = greater
结果显示需要134个受试者来评价抑郁和孤独的关系,以便在零假设为假的情况下有90%的信息拒绝它。
10.2.4 线性模型
线性模型(例如多元回归),用pwr.f2.test()函数分析功效分析
10.2.4.1 语法
library(pwr)
pwr.f2.test(u=,v=,f2=,sig.level=,power =)
u:分子自由度,u=总自变量数-集合B中的自变量数
v:分母自由度,v=N-k-1,N总观测值数目,k:总自变量数目
f2:效应值,有2种算法:
算法1:当要评价一组预测变量对结果的影响程度时,f2=多重相关性的总体平方值/(1-多重相关性的总体平方值)
算法2:当评价一组预测变量(集合B)对结果的影响超过第2组变量(协变量,(集合A))多少时适用:f2=(集合A和B中变量对总体方差的解释率-集合A中变量对总体方差的解释率)/(1-集合A和B中变量对总体方差的解释率)
10.2.4.2 举例(这个例子中我认为u=4)
想研究老板的领导风格对员工满意度的影响是否超过薪水和福利待遇对员工满意度的影响?已知:领导风格用4个变量评估,薪水和福利待遇与3个变量有关。薪水和福利待遇能解释30%的员工满意度的方差,从现实出发(即集合A和集合B),领导风格能解释35%的员工满意度的方差。显著性水平设置为0.05,在90%的置信度情况下,需要多少受试者才能得到这样的方差贡献率。
已知:
u=3+4-3=4
f2=(0.35-0.3)/(1-0.35)=0.0769
k=7
library(pwr)
pwr.f2.test(u=4,f2=0.0769,sig.level=0.05,power =0.9)
因此:v=N-7-1=200,N=200+7+1=208
10.2.5 比例检验
10.2.5.1 语法
library(pwr)
pwr.2p.test(h=,n=,sig.level=,power =,alternative = )
h:效应值,可以用ES.h(p1,p2)函数计算;
n:各组的相同的样本量;当n不同时,使用:
library(pwr)
pwr.2p.test(h=,n1=,n2=,sig.level=,power =,alternative = )
alternative =:跟前面一样,可以选择双侧还是单侧检验,其中单侧检验:
greater:表示备择假设是效应大于给定值。这通常用于验证某个因素是否具有积极影响或增加了某个指标。
less:表示备择假设是效应小于给定值。这通常用于验证某个因素是否具有负面影响或降低了某个指标。
10.2.5.2 举例
对某流行药物能缓解60%的使用者症状感到怀疑。而一种更贵的新药如果能缓解65%的使用者症状则会被投放到市场上。因此,我们研究需要多少受试者才能检测到这两种药物存在者一特定差异?
假设我们想有90%的的把我得出新药更有效的结论,并希望有95%的把握不会误得结论(P<0.05),且我们只对评价新药是否比标准药物更好感兴趣,因此使用greater单侧检验:
library(pwr)
pwr.2p.test(h=ES.h(0.65,0.6),sig.level=0.05,power =0.9,alternative ="greater" )
##
## Difference of proportion power calculation for binomial distribution (arcsine transformation)
##
## h = 0.1033347
## n = 1604.007
## sig.level = 0.05
## power = 0.9
## alternative = greater
##
## NOTE: same sample sizes
结果显示:为满足以上要求,需要1605受试者试用新药,1605人受试者用已有药物。
10.2.6 卡方检验
pwr.chisq.test(),卡方检验通常用来评价两个分类变量的关系。零假设(H0):变量之间独立,备择假设(H1)为不独立。
10.2.6.1 语法
library(pwr)
pwr.chisq.test(w=,N=,df=,sig.level=,power =,alternative = )
w:效应值;可以使用函数ES.w2(P)计算双因素列联表中的备择假设的效应值。P为一个假设的双因素概率表。
N:总样本量;
df:自由度,df=(r-1)(c-1),r是行数,c是列数。
10.2.6.2 举例
假设我们想研究专业与工作晋升的关系,我们预期样本中70%是金融专业,10%是计算机专业,20%是销售专业。且,我们认为相比30%的计算机专业和50%的销售专业,60%的学金融专业的人更容易晋升。研究假设的晋升概率如下表:
专业 | 晋升占比 | 未晋升占比 |
---|---|---|
金融 | 0.42 | 0.28 |
计算机 | 0.03 | 0.07 |
销售 | 0.10 | 0.10 |
取0.05的显著性水平和0.9的预期功效水平:
prop <- matrix(c(.42,.28,0.03,0.07,0.10,0.10),byrow = TRUE,nrow = 3)
ES.w2(prop)#计算效应值
## [1] 0.1853198
library(pwr)
pwr.chisq.test(w=0.1853198,df=2,sig.level=0.05,power =0.9)
##
## Chi squared power calculation
##
## w = 0.1853198
## N = 368.4529
## df = 2
## sig.level = 0.05
## power = 0.9
##
## NOTE: N is the number of observations
结果表明,既定的效应值、功效水平和显著性水平下,需要369个受试者才能检验专业和工作晋升的关系。
10.2.7 在新情况中选择合适的效应值
当没有过去的研究数据来计算效应值时,可以利用Cohen提出的基准值实验:
统计方法 | 效应值测量 | 建议的效应值基(小) | (中) | (大) |
---|---|---|---|---|
t检验 | d | 0.20 | 0.5 | 0.8 |
方差分析 | f | 0.1 | 0.25 | 0.4 |
线性模型 | f2 | 0.02 | 0.15 | 0.35 |
比例检验 | h | 0.2 | 0.5 | 0.8 |
卡方检验 | w | 0.1 | 0.3 | 0.5 |
举例:
想在0.05显著性下,对5个组,每组25个受试者的设计进行单因素方差分析,那么拒绝零假设的概率是多大?
library(pwr)
pwr.anova.test(k=5,n=25,sig.level=0.05,f=c(0.10,0.25,0.4))
##
## Balanced one-way analysis of variance power calculation
##
## k = 5
## n = 25
## f = 0.10, 0.25, 0.40
## sig.level = 0.05
## power = 0.1180955, 0.5738000, 0.9569163
##
## NOTE: n is number in each group
结果显示其中大效应值的功效水平为0.957,因此我们在大效应值时才能发现要研究的效应。
10.3 绘制功效分析图
假设对于相关系数统计显著性的检验,想计算一系列效应值和功效水平下所需的样本量。pwr.r.test()和for():
library(pwr)
r <- seq(0.1,0.5,0.01)#设置一系列效应值,H1时的相关系数
p <- seq(0.4,0.9,0.1)#设置一系列功效水平
df <- expand.grid(r,p)
df
## Var1 Var2
## 1 0.10 0.4
## 2 0.11 0.4
## 3 0.12 0.4
## 4 0.13 0.4
## 5 0.14 0.4
## 6 0.15 0.4
## 7 0.16 0.4
## 8 0.17 0.4
## 9 0.18 0.4
## 10 0.19 0.4
## 11 0.20 0.4
## 12 0.21 0.4
## 13 0.22 0.4
## 14 0.23 0.4
## 15 0.24 0.4
## 16 0.25 0.4
## 17 0.26 0.4
## 18 0.27 0.4
## 19 0.28 0.4
## 20 0.29 0.4
## 21 0.30 0.4
## 22 0.31 0.4
## 23 0.32 0.4
## 24 0.33 0.4
## 25 0.34 0.4
## 26 0.35 0.4
## 27 0.36 0.4
## 28 0.37 0.4
## 29 0.38 0.4
## 30 0.39 0.4
## 31 0.40 0.4
## 32 0.41 0.4
## 33 0.42 0.4
## 34 0.43 0.4
## 35 0.44 0.4
## 36 0.45 0.4
## 37 0.46 0.4
## 38 0.47 0.4
## 39 0.48 0.4
## 40 0.49 0.4
## 41 0.50 0.4
## 42 0.10 0.5
## 43 0.11 0.5
## 44 0.12 0.5
## 45 0.13 0.5
## 46 0.14 0.5
## 47 0.15 0.5
## 48 0.16 0.5
## 49 0.17 0.5
## 50 0.18 0.5
## 51 0.19 0.5
## 52 0.20 0.5
## 53 0.21 0.5
## 54 0.22 0.5
## 55 0.23 0.5
## 56 0.24 0.5
## 57 0.25 0.5
## 58 0.26 0.5
## 59 0.27 0.5
## 60 0.28 0.5
## 61 0.29 0.5
## 62 0.30 0.5
## 63 0.31 0.5
## 64 0.32 0.5
## 65 0.33 0.5
## 66 0.34 0.5
## 67 0.35 0.5
## 68 0.36 0.5
## 69 0.37 0.5
## 70 0.38 0.5
## 71 0.39 0.5
## 72 0.40 0.5
## 73 0.41 0.5
## 74 0.42 0.5
## 75 0.43 0.5
## 76 0.44 0.5
## 77 0.45 0.5
## 78 0.46 0.5
## 79 0.47 0.5
## 80 0.48 0.5
## 81 0.49 0.5
## 82 0.50 0.5
## 83 0.10 0.6
## 84 0.11 0.6
## 85 0.12 0.6
## 86 0.13 0.6
## 87 0.14 0.6
## 88 0.15 0.6
## 89 0.16 0.6
## 90 0.17 0.6
## 91 0.18 0.6
## 92 0.19 0.6
## 93 0.20 0.6
## 94 0.21 0.6
## 95 0.22 0.6
## 96 0.23 0.6
## 97 0.24 0.6
## 98 0.25 0.6
## 99 0.26 0.6
## 100 0.27 0.6
## 101 0.28 0.6
## 102 0.29 0.6
## 103 0.30 0.6
## 104 0.31 0.6
## 105 0.32 0.6
## 106 0.33 0.6
## 107 0.34 0.6
## 108 0.35 0.6
## 109 0.36 0.6
## 110 0.37 0.6
## 111 0.38 0.6
## 112 0.39 0.6
## 113 0.40 0.6
## 114 0.41 0.6
## 115 0.42 0.6
## 116 0.43 0.6
## 117 0.44 0.6
## 118 0.45 0.6
## 119 0.46 0.6
## 120 0.47 0.6
## 121 0.48 0.6
## 122 0.49 0.6
## 123 0.50 0.6
## 124 0.10 0.7
## 125 0.11 0.7
## 126 0.12 0.7
## 127 0.13 0.7
## 128 0.14 0.7
## 129 0.15 0.7
## 130 0.16 0.7
## 131 0.17 0.7
## 132 0.18 0.7
## 133 0.19 0.7
## 134 0.20 0.7
## 135 0.21 0.7
## 136 0.22 0.7
## 137 0.23 0.7
## 138 0.24 0.7
## 139 0.25 0.7
## 140 0.26 0.7
## 141 0.27 0.7
## 142 0.28 0.7
## 143 0.29 0.7
## 144 0.30 0.7
## 145 0.31 0.7
## 146 0.32 0.7
## 147 0.33 0.7
## 148 0.34 0.7
## 149 0.35 0.7
## 150 0.36 0.7
## 151 0.37 0.7
## 152 0.38 0.7
## 153 0.39 0.7
## 154 0.40 0.7
## 155 0.41 0.7
## 156 0.42 0.7
## 157 0.43 0.7
## 158 0.44 0.7
## 159 0.45 0.7
## 160 0.46 0.7
## 161 0.47 0.7
## 162 0.48 0.7
## 163 0.49 0.7
## 164 0.50 0.7
## 165 0.10 0.8
## 166 0.11 0.8
## 167 0.12 0.8
## 168 0.13 0.8
## 169 0.14 0.8
## 170 0.15 0.8
## 171 0.16 0.8
## 172 0.17 0.8
## 173 0.18 0.8
## 174 0.19 0.8
## 175 0.20 0.8
## 176 0.21 0.8
## 177 0.22 0.8
## 178 0.23 0.8
## 179 0.24 0.8
## 180 0.25 0.8
## 181 0.26 0.8
## 182 0.27 0.8
## 183 0.28 0.8
## 184 0.29 0.8
## 185 0.30 0.8
## 186 0.31 0.8
## 187 0.32 0.8
## 188 0.33 0.8
## 189 0.34 0.8
## 190 0.35 0.8
## 191 0.36 0.8
## 192 0.37 0.8
## 193 0.38 0.8
## 194 0.39 0.8
## 195 0.40 0.8
## 196 0.41 0.8
## 197 0.42 0.8
## 198 0.43 0.8
## 199 0.44 0.8
## 200 0.45 0.8
## 201 0.46 0.8
## 202 0.47 0.8
## 203 0.48 0.8
## 204 0.49 0.8
## 205 0.50 0.8
## 206 0.10 0.9
## 207 0.11 0.9
## 208 0.12 0.9
## 209 0.13 0.9
## 210 0.14 0.9
## 211 0.15 0.9
## 212 0.16 0.9
## 213 0.17 0.9
## 214 0.18 0.9
## 215 0.19 0.9
## 216 0.20 0.9
## 217 0.21 0.9
## 218 0.22 0.9
## 219 0.23 0.9
## 220 0.24 0.9
## 221 0.25 0.9
## 222 0.26 0.9
## 223 0.27 0.9
## 224 0.28 0.9
## 225 0.29 0.9
## 226 0.30 0.9
## 227 0.31 0.9
## 228 0.32 0.9
## 229 0.33 0.9
## 230 0.34 0.9
## 231 0.35 0.9
## 232 0.36 0.9
## 233 0.37 0.9
## 234 0.38 0.9
## 235 0.39 0.9
## 236 0.40 0.9
## 237 0.41 0.9
## 238 0.42 0.9
## 239 0.43 0.9
## 240 0.44 0.9
## 241 0.45 0.9
## 242 0.46 0.9
## 243 0.47 0.9
## 244 0.48 0.9
## 245 0.49 0.9
## 246 0.50 0.9
colnames(df) <- c("r","p")
for(i in 1:nrow(df)){
result <- pwr.r.test(r=df$r[i],
sig.level=0.05,power = df$p[i],
alternative = "two.sided")
df$n[i] <- ceiling(result$n)#result$n的值向上取整,并将结果赋给df数据框的n列的第i个元素。
}
library(ggplot2)
ggplot(data=df,aes(x=r,y=n,color=factor(p)))+
geom_line(size=1)+
theme_bw()+
labs(color="Power")
完整教程请查看