Fisher 精确检验的模拟低估了功效

机器算法验证 r 统计能力 渔民精确测试
2022-04-10 01:54:19

摘要:我的模拟与我的功率计算不符。

(这个问题已经变得相当长,所以你可能没有读到底部。我认为这是一个样本量问题。)

我正在运行一些模拟来帮助设计一项研究,但我遇到了一些让我感到困惑的事情。

有两组,治疗组和未治疗组,结果是崩溃的。

我们估计未治疗组的崩溃率为 0.1,并且认为我们可以将其降低到 0.08。小样本(且不可行)为每组 100 个样本。

所以我跑去power.prop.test()估计功率。

    power.prop.test(p1=0.1, p2=0.08, n=100)

    power.prop.test(p1=0.1, p2=0.08, n=100)                                                        
    
         Two-sample comparison of proportions power calculation 
    
                  n = 100
                 p1 = 0.1
                 p2 = 0.08
          sig.level = 0.05
              power = 0.07122973
        alternative = two.sided
 NOTE: `n` is number in *each* group 

然后我进行了模拟,因为我想探索我们在最佳治疗方面做出错误决定的频率。

    library(Exact)

    #Create a data frame called d, populate it with the numbers 
    #above.
    set.seed(12345)
    nTreated <- 100
    nUntreated <- 100
    probTreated <- 0.1
    probUntreated <- 0.08
    
    d <- data.frame(id = 1:10000)
    d$nTreated <- nTreated
d$nUntreated <- nUntreated
    d$probTreated <- probTreated 
d$probUntreated <- probUntreated

    #Generate some random results using rbinom()
    d$treatedCrashes <- apply(cbind(d$nTreated, d$probTreated), 
    1,  function(x)  sum(rbinom(x[1], 1, x[2])))

    d$untreatedCrashes <- apply(cbind(d$nUntreated, 
    d$probUntreated), 1, function(x)  sum(rbinom(x[1], 1, 
                                                  x[2])))

    #Do fisher's exact test on each replication:
    d$fisher <- apply(cbind(d$nTreated - d$treatedCrashes, 
                    d$treatedCrashes,
                            d$nUntreated - d$untreatedCrashes, 
                            d$untreatedCrashes), 1, 
                      function(x)  fisher.test(matrix(x,  
nrow=2))$p.value)
    #test power
    mean(d$fisher < 0.05)

我得到了 4.8% 的功率,低于power.prop.test函数所说的,并且小于 0.05 - 这似乎有点错误。

        mean(d$fisher < 0.05)
    [1] 0.0478

这是关于小样本近似吗?这是一个愚蠢的编码错误吗?(我不认为是这样,但我以前经常犯错)。这是我没有想到的吗?

为了回应这是因为 Fisher 的精确检验以边际为条件的建议,我用 Barnard 的检验(在 Exact 库中)重新运行了模型。(但我减少到 1000 次复制,因为这需要 40 分钟)。

    d$exact <- apply(cbind(d$nTreated - d$treatedCrashes, 
                     d$treatedCrashes,
                             d$nUntreated - d$untreatedCrashes, 
                             d$untreatedCrashes), 1, 
                   function(x)  exact.test(matrix(x, nrow=2), 
to.plot=F, cond.row=T)$p.value)
    d$exact <- lapply(d$exact, function(x) x[1][[1]])
    
    mean(d$exact < 0.05)      

    mean(d$exact < 0.05)                      
    [1] 0.049                

我有几乎相同的力量。

但是,我还使用该power.exact.test()函数对功率进行了精确测试,也在 Exact 库中,它提供了非常相似的功率水平:

    power.exact.test(p1=0.1, p2=0.08, n1=100, 
         n2=100,simulation=T, nsim=1000, method="Boschloo")
    $power
    [1] 0.045
    
    $alternative
    [1] "two.sided"
    
    $method
    [1] "Boschloo"

这让我认为这是一个样本量问题。

3个回答

Fisher 精确检验是保守的(即当原假设为真时,名义 0.05 检验的假阳性率实际上小于 0.05)。你的发现绝非巧合。说一个检验是“精确的”并不意味着它的大小合适,而是小样本中 p 值的解释是正确的。

这是大学生物统计学讲义中的参考资料

华盛顿大学生物统计学教授 Scott S. Emerson 的应用生物统计学

Fisher 检验以表格的两个边缘为条件;您的模拟仅以一个边距为条件。

[你是对的,还有更多:

(1) 您使用 power.prop.test 进行的第一次计算使用二项式分布对正态分布的渐近近似,因此不会给出与精确测试完全相同的答案。

(2) 任何精确的检验都是保守的,因为只有有限数量的可能列联表,并且在零假设下,您无法找到一个子集以恰好 5% 的概率形成拒绝区域,因此您必须稍作妥协少(@AdamO 的回答)。

(3) 以总计、行总计、列总计或行列总计为条件形成不同的精确检验。选择不同的条件方案意味着 (a) 提出不同的测试问题,以及 (b) 更改可能的列联表的数量(因此条件最保守的测试 - 例如 Fisher 的)。

(4) 还可以使用不同的检验统计量,它们不一定在原假设下给出相同的可能表顺序。

(5) 当您进行模拟时,需要考虑模拟错误(@Maarten 的回答)。]

您的蒙特卡罗模拟中存在随机性(应该有),因此即使真正的拒绝率恰好是 0.05 并且您的程序中没有错误,您仍然可能会发现与该数字的微小偏差。如果您要多次重复您的蒙特卡罗模拟 10,000 次并且测试完全按照应有的方式运行,那么您仍然会发现(大约)95% 的模拟会导致拒绝率在 4.6% 和 5.4% 之间. 这些界限基于 2.5th和 97.5thn=10,000 和 p=.05 的二项式分布的百分位数。因此,您在具有 10,000 次重复的模拟中发现拒绝率为 4.8% 的事实并不能提供反对 Fisher 精确检验的所有有力证据。正如 AdamO 指出的那样,即使您增加复制次数,您很可能会发现拒绝率低于 5%,但是当前的模拟没有足够的复制来可靠地发现这种现象。