在R中使用Kolmogorov Smirnov检验

时间:2013-06-29 14:28:06

标签: r anova

我设计了3000个实验,因此在一个实验中有4组(治疗),每组有50个人(受试者)。对于每个实验,我做一个标准的单因子方差分析并证明他们的p值在零假设下是否具有单概率函数,但是ks.test拒绝这个假设,我不明白为什么?

subject<-50
treatment<-4
experiment<-list()
R<-3000
seed<-split(1:(R*subject),1:R)
for(i in 1:R){
  e<-c()
  for(j in 1:subject){
    set.seed(seed[[i]][j]) 
    e<-c(e,rmvnorm(mean=rep(0,treatment),sigma=diag(3,4),n=1,method="chol"))
   }
  experiment<-c(experiment,list(matrix(e,subject,treatment,byrow=T)))
 }

 p.values<-c()
for(e in experiment){
  d<-data.frame(response=c(e),treatment=factor(rep(1:treatment,each=subject)))
  p.values<-c(p.values,anova(lm(response~treatment,d))[1,"Pr(>F)"])
 }

 ks.test(p.values, punif,alternative = "two.sided")

1 个答案:

答案 0 :(得分:9)

我注释掉了代码中改变随机种子的行,得到的P值为.34。这是一个未知的种子,所以为了重现性,我做了set.seed(1)并再次运行它。这一次,我的P值为0.98。

至于为什么会有所不同,我不是PRNG的专家,但任何体面的发电机都会确保连续的抽奖在统计上与所有实际目的无关。最好的那些将确保相同的更大的滞后,例如Mersenne Twister是R的默认PRNG保证它滞后高达623(IIRC)。事实上,干涉种子可能会损害抽奖的统计特性。

您的代码也以非常低效的方式处理事务。您正在创建实验列表,并为每个实验添加一个项目。 每个实验中,您还可以创建一个矩阵,并为每个观察添加一行。然后你为P值做一些非常相似的事情。我会看看能不能解决这个问题。

这就是我替换代码的方式。严格来说,我可以通过避免公式,创建裸模型矩阵并直接调用lm.fit来使其更紧凑。但这意味着必须手动编写ANOVA测试代码,而不是简单地调用anova,这比它的价值更麻烦。

set.seed(1) # or any other number you like

x <- factor(rep(seq_len(treatment), each=subject))
p.values <- sapply(seq_len(R), function(r) {
    y <- rnorm(subject * treatment, s=3)
    anova(lm(y ~ x))[1,"Pr(>F)"]
})
ks.test(p.values, punif,alternative = "two.sided")


        One-sample Kolmogorov-Smirnov test

data:  p.values
D = 0.0121, p-value = 0.772
alternative hypothesis: two-sided