The table returned by clusterProfiler::enricher() contains p-values, adjusted p-values, and q-values. Its pAdjustMethod argument accepts methods including "holm", "hochberg", "hommel", "bonferroni", "BH", "BY", and "fdr".

BH, BY, and fdr

Inspecting enricher() shows that it calls R’s p.adjust() function for adjustment. The names have a historical relationship:

  • BH is the Benjamini–Hochberg procedure.
  • fdr is another name for the same procedure in p.adjust() and remains available for compatibility.
  • BY is the Benjamini–Yekutieli procedure. When the first FDR method was added to p.adjust(), it was called fdr. The later addition of another FDR procedure required distinct names, while preserving the older alias. The R documentation for p.adjust describes the methods and their assumptions. In particular, BY supports a more general dependence structure than BH; choosing between them is more than choosing an output label.

Adjusted p-values and q-values

The next question is why adjusted p-values and q-values can look similar while referring to different procedures. John Storey’s work introduced a related definition of false discovery rate and the q-value as a measure associated with that definition. The qvalue package estimates quantities including the proportion of true null hypotheses and q-values from a collection of p-values. This motivates a distinction between estimation and control. An estimation procedure seeks to describe the false-discovery proportion associated with a selection rule, while a control procedure is constructed to bound an expected error rate under its assumptions. The original notes also compare small-sample behavior: estimation methods may rely on asymptotic properties, while the properties of the BH procedure are tied to its assumptions about the p-values and dependence. Similar output values do not remove these differences. The terms “q-value” and “FDR-adjusted p-value” are sometimes used loosely as if they were interchangeable. For a reproducible analysis, record the actual procedure and package, rather than relying on that shorthand. See the qvalue package documentation.

← Back to all posts