【问题标题】:R: unexpected results from p.adjust (FDR)R:来自 p.adjust (FDR) 的意外结果
【发布时间】:2012-04-25 21:06:49
【问题描述】:

当我尝试使用 p.adjust 对 p 值向量运行 FDR 调整时,出现了这个问题。问题是许多结果 p 值是相同的。我认为这可能是我的数据的一些怪癖,但我已经用任意输入向量重现了同样的问题。例如:

temp <- runif(40, min = 0, max = 1) 
temp

# [1] 0.81563482 0.17471363 0.74697979 0.88755248 0.69676260 0.58207008
# [7] 0.87138747 0.76432908 0.64352955 0.06501659 0.70680646 0.81557281
#[13] 0.58480274 0.19476004 0.01035137 0.46119840 0.17783440 0.71828874
#[19] 0.30978182 0.76902202 0.01615609 0.93122152 0.37936458 0.52369562
#[25] 0.90997054 0.30098383 0.70873206 0.71159740 0.38148526 0.78415579
#[31] 0.64605509 0.18898361 0.76770495 0.40651004 0.42255944 0.68395505
#[37] 0.51844368 0.25855720 0.12090991 0.50110836

p.adjust(temp, method="fdr")

# [1] 0.9062609 0.9062609 0.9062609 0.9312215 0.9062609 0.9062609 0.9312215
# [8] 0.9062609 0.9062609 0.8668878 0.9062609 0.9062609 0.9062609 0.9062609
#[15] 0.3231218 0.9062609 0.9062609 0.9062609 0.9062609 0.9062609 0.3231218
#[22] 0.9312215 0.9062609 0.9062609 0.9312215 0.9062609 0.9062609 0.9062609
#[29] 0.9062609 0.9062609 0.9062609 0.9062609 0.9062609 0.9062609 0.9062609
#[36] 0.9062609 0.9062609 0.9062609 0.9062609 0.9062609

我想我犯了一些错误。我认为 FDR 将 p 值调整为相同的值是不合理的。大多数数据是相同的,并非全部都与原始 p 值一致。任何想法这里有什么问题?谢谢。

【问题讨论】:

  • 我想你会发现它按预期运行。尝试temp &lt;- runif(5, min =0, max =.005) 然后p.adj &lt;- sapply(p.adjust.methods, function(meth) p.adjust(temp, meth)) 给出所有调整方法。

标签: r


【解决方案1】:

该方法运行良好。你只是不完全理解算法在做什么。我建议阅读一下(Wikipedia Link) 的程序。

n <- 40
p <- runif(n, 0, 1)
adjusted.p <- p.adjust(p, "fdr") #same as p.adjust(p, "BH")

## Let's recreate.  Going back to the paper we
## can construct a q-value by sorting the p-values
## and then applying the transformation:
## q_i = p_i*n/i
## Where p_i is the ith smallest p-value

## Sort the p-values and keep track of the order
id <- order(p)
tmp <- p[id]
(q <- tmp*n/(1:n))
# [1] 2.0322183 1.0993436 1.2357457 1.1113084 0.9282536 0.7877181 0.7348436
# [8] 0.7204077 0.6587102 0.6289974 0.9205222 0.8827835 0.8600234 0.8680704
#[15] 1.1532693 1.1055951 1.0451330 1.1314681 1.1167659 1.1453142 1.1012847
#[22] 1.0783747 1.0672471 1.0500311 1.0389407 1.0089661 1.0117881 0.9917817
#[29] 0.9892826 0.9668636 0.9844052 0.9792733 1.0000320 0.9967073 0.9707149
#[36] 0.9747723 0.9968153 0.9813367 1.0058445 0.9942353

## However there is one more portion to the adjustment
## We don't want a p-value of .02 getting
## a larger q-value than a p-value of .05
## so we make sure that if a smaller q-value
## shows up in the list we set all of
## the q-values corresponding to smaller p-values
## to that corresponding q-value.

## We can do this by reversing the list
## Keeping a running tally of the minimum value
## and then re-reversing
new.q <- rev(cummin(rev(q)))

## Put it back in the original order
new.q[order(id)]
# [1] 0.6289974 0.9668636 0.6289974 0.6289974 0.6289974 0.9707149 0.9707149
# [8] 0.8600234 0.9668636 0.6289974 0.9707149 0.9668636 0.9668636 0.9813367
#[15] 0.9668636 0.9668636 0.9668636 0.9707149 0.9668636 0.9668636 0.6289974
#[22] 0.9942353 0.8600234 0.6289974 0.9668636 0.6289974 0.6289974 0.8680704
#[29] 0.9668636 0.9668636 0.9668636 0.9942353 0.9707149 0.9813367 0.9668636
#[36] 0.8600234 0.6289974 0.9668636 0.9668636 0.9747723

## This should match the adjustment
adjusted.p
# [1] 0.6289974 0.9668636 0.6289974 0.6289974 0.6289974 0.9707149 0.9707149
# [8] 0.8600234 0.9668636 0.6289974 0.9707149 0.9668636 0.9668636 0.9813367
#[15] 0.9668636 0.9668636 0.9668636 0.9707149 0.9668636 0.9668636 0.6289974
#[22] 0.9942353 0.8600234 0.6289974 0.9668636 0.6289974 0.6289974 0.8680704
#[29] 0.9668636 0.9668636 0.9668636 0.9942353 0.9707149 0.9813367 0.9668636
#[36] 0.8600234 0.6289974 0.9668636 0.9668636 0.9747723

【讨论】:

  • 是的,我做了一些研究,发现考虑到我正在处理的参数,这是合理的。我对 FDR 不够熟悉,无法认识到这一点。谢谢。
  • @Dason 感谢您的详细解释(也“复制”了p.adjust() 相关部分的代码):我试图自己解决这个问题。我很难追踪the paper 中构造q_i 的部分以及描述p = 0.02 且q > 0.05 的位。感谢提示
  • @Dason 很抱歉打扰您,我在理解您调整的最后部分时遇到了问题。 rev(cummin(rev(q)))你能解释一下这里发生了什么吗?所以你反转 q 值,例如,如果你的 q 值从 1 到 10,10 变为 1,1 变为 10。那么你 cummin 的意思是用较小的数字替换它,然后重新排列数据?
  • @Learner 解释实际上是该代码之前的 cmets
  • @Dason 我知道你在那里解释过,但说真的我还是不明白!看看这个例子statisticshowto.datasciencecentral.com/…我真的不知道最后一部分它是如何工作的,你能举个例子解释一下吗?
猜你喜欢
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 2015-11-02
相关资源
最近更新 更多