我的数据dat
就像这样
set.seed(123)
dat<- data.frame(
comp = rep(1:4,2),
grp = rep(c('A','B'), each=4),
pval = runif(8, min=0, max=0.1) )
dat$pval[sample(nrow(dat), 1)] <- NA
pval列包含每个大组内多个ttest的p值列表 现在我需要应用基本r函数p.adjust来调整每个组中的p值(A,B,...) 我做的是:
dat %>%
group_by(grp) %>%
mutate(pval.adj = p.adjust (pval, method='BH'))
以下是上述代码的输出:
comp grp pval pval.adj
1 A 0.02875775 0.08179538
2 A 0.07883051 0.08830174
3 A 0.04089769 0.08179538
4 A 0.08830174 0.08830174
1 B NA NA
2 B 0.00455565 0.01366695
3 B 0.05281055 0.07921582
4 B 0.08924190 0.08924190
结果没有意义。每个组的最后一个条目,pval和pval.adj是相等的。有些pval.adj比其他人更接近pval。我认为在group_by之后应用p.adjust函数有问题。它花了我几个小时,但无法弄清楚为什么......我很感激,如果有人可以帮助我。
下面是p.adjust函数用法:
p.adjust(p, method = p.adjust.methods, n = length(p))
p.adjust.methods
# c("holm", "hochberg", "hommel", "bonferroni", "BH", "BY",
# "fdr", "none")
答案 0 :(得分:1)
您正在分别对每个P值调用p.adjust。由于这个原因,我通常在管道外面打电话给p.adjust。
答案 1 :(得分:0)
@zesla你的代码很好。你的困惑在于family-wise error rate
和false discovery rate
之间的区别,这就是BH所做的。使用BH,您更有可能看到这些相同的值。
如果您查看p.adjust
的doco并运行示例代码:
set.seed(123)
x <- rnorm(50, mean = c(rep(0, 25), rep(3, 25)))
p <- 2*pnorm(sort(-abs(x)))
round(p, 3)
round(p.adjust(p), 3)
round(p.adjust(p, "BH"), 3)
你会看到同样的效果。您还可以像Holm一样运行传统的family-wise error rate
调整,以查看对您自己数据的影响...
dat %>%
group_by(grp) %>%
mutate(pval.adj = p.adjust (pval, method='holm'))
另请参阅此article有关如何计算BH的信息