杰罗姆·康菲尔德(Jerome Cornfield)写道:
渔业革命的最好成果之一就是随机化的想法,而在其他几件事上达成共识的统计学家至少对此达成了共识。但是尽管达成了这一协议,并且尽管在临床和其他形式的实验中广泛使用了随机分配程序,但其逻辑状态(即其执行的确切功能)仍然不清楚。
杰罗姆·康菲尔德(1976)。“对临床试验的最新方法论贡献”。美国流行病学杂志104(4):408–421。
在整个站点以及各种文献中,我始终看到关于随机化能力的自信主张。诸如“它消除了混杂变量的问题”之类的强大术语很常见。例如,请参见此处。但是,出于实际/伦理的原因,很多时候都使用小样本(每组3-10个样本)进行实验。这在使用动物和细胞培养物进行临床前研究中非常普遍,研究人员通常报告p值以支持其结论。
这让我想知道,随机化在平衡混淆方面有多好。对于这个图,我模拟了一个比较治疗组和对照组的情况,其中一个混杂物可能以50/50的机会出现两个值(例如,type1 / type2,male / female)。它显示了用于研究各种小样本数量的“不平衡百分比”(处理样本与对照样本之间的type1#的差异除以样本数量)的分布。红线和右侧轴显示ecdf。
小样本量下,随机化下各种程度的平衡概率:
从这个情节可以清楚地看出两件事(除非我在某个地方搞砸了)。
1)随着样本数量的增加,获得完全平衡样本的可能性降低。
2)随着样本数量的增加,获得非常不平衡的样本的可能性降低。
3)在两组中n = 3的情况下,有3%的机会获得一组完全不平衡的组(对照组中的所有type1,治疗中的所有type2)。N = 3在分子生物学实验中很常见(例如,通过PCR测量mRNA或通过蛋白质印迹法测量蛋白质)
当我进一步检查n = 3的情况时,我观察到在这些条件下p值的奇怪行为。左侧显示类型2子组在不同均值条件下使用t检验计算的p值的总体分布。类型1的平均值为0,两组的sd = 1。右侧面板显示了从0.05到0.0001的名义“显着性临界值”的相应假阳性率。
通过t检验比较时,n = 3的p值在n = 3时具有两个子组和第二子组的平均值不同(10000个蒙特卡洛分析):
这是两组的n = 4的结果:
两个组的n = 5:
两组的n = 10:
从上面的图表可以看出,样本量和子组之间的差异之间似乎存在相互作用,这导致在原假设下不一致的各种p值分布。
因此,我们可以得出结论:对于小样本量的适当随机化和受控实验,p值不可靠吗?
第一图的R代码
require(gtools)
#pdf("sim.pdf")
par(mfrow=c(4,2))
for(n in c(3,4,5,6,7,8,9,10)){
#n<-3
p<-permutations(2, n, repeats.allowed=T)
#a<-p[-which(duplicated(rowSums(p))==T),]
#b<-p[-which(duplicated(rowSums(p))==T),]
a<-p
b<-p
cnts=matrix(nrow=nrow(a))
for(i in 1:nrow(a)){
cnts[i]<-length(which(a[i,]==1))
}
d=matrix(nrow=nrow(cnts)^2)
c<-1
for(j in 1:nrow(cnts)){
for(i in 1:nrow(cnts)){
d[c]<-cnts[j]-cnts[i]
c<-c+1
}
}
d<-100*abs(d)/n
perc<-round(100*length(which(d<=50))/length(d),2)
hist(d, freq=F, col="Grey", breaks=seq(0,100,by=1), xlab="% Unbalanced",
ylim=c(0,.4), main=c(paste("n=",n))
)
axis(side=4, at=seq(0,.4,by=.4*.25),labels=seq(0,1,,by=.25), pos=101)
segments(0,seq(0,.4,by=.1),100,seq(0,.4,by=.1))
lines(seq(1,100,by=1),.4*cumsum(hist(d, plot=F, breaks=seq(0,100,by=1))$density),
col="Red", lwd=2)
}
情节2-5的R代码
for(samp.size in c(6,8,10,20)){
dev.new()
par(mfrow=c(4,2))
for(mean2 in c(2,3,10,100)){
p.out=matrix(nrow=10000)
for(i in 1:10000){
d=NULL
#samp.size<-20
for(n in 1:samp.size){
s<-rbinom(1,1,.5)
if(s==1){
d<-rbind(d,rnorm(1,0,1))
}else{
d<-rbind(d,rnorm(1,mean2,1))
}
}
p<-t.test(d[1:(samp.size/2)],d[(1+ samp.size/2):samp.size], var.equal=T)$p.value
p.out[i]<-p
}
hist(p.out, main=c(paste("Sample Size=",samp.size/2),
paste( "% <0.05 =", round(100*length(which(p.out<0.05))/length(p.out),2)),
paste("Mean2=",mean2)
), breaks=seq(0,1,by=.05), col="Grey", freq=F
)
out=NULL
alpha<-.05
while(alpha >.0001){
out<-rbind(out,cbind(alpha,length(which(p.out<alpha))/length(p.out)))
alpha<-alpha-.0001
}
par(mar=c(5.1,4.1,1.1,2.1))
plot(out, ylim=c(0,max(.05,out[,2])),
xlab="Nominal alpha", ylab="False Postive Rate"
)
par(mar=c(5.1,4.1,4.1,2.1))
}
}
#dev.off()