在dplyr中的group_by之后应用p.adjust函数

时间:2018-01-11 17:20:21

标签: r dplyr

我的数据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")

2 个答案:

答案 0 :(得分:1)

您正在分别对每个P值调用p.adjust。由于这个原因,我通常在管道外面打电话给p.adjust。

答案 1 :(得分:0)

@zesla你的代码很好。你的困惑在于family-wise error ratefalse 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的信息