% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/cBY_wrapper.R
\name{closedBY}
\alias{closedBY}
\title{Closed Benjamini-Yekutieli procedure for simultaneous FDR control}
\usage{
closedBY(p, set = NULL, alpha = 0.05, approximate = FALSE)
}
\arguments{
\item{p}{Numeric vector of p-values, one per hypothesis. Values must lie
in \eqn{[0, 1]}; exact zeros are replaced internally by a small positive
constant to avoid numerical issues.}

\item{set}{Optional subsetting vector for \code{p} (logical, index, or negative
index), indicating which hypotheses belong to the set to be checked for
closedBY significance. If \code{NULL} (the default), the function instead returns
the size of the largest closedBY-significant set.}

\item{alpha}{Numeric scalar in \eqn{[0, 1]}. The target FDR level. Defaults
to \code{0.05}.}

\item{approximate}{Logical. If \code{FALSE} (the default), uses an exact algorithm
that is guaranteed to find the largest closedBY-significant set. If \code{TRUE},
uses a faster approximate algorithm based on bisection that may
occasionally return a smaller set. The approximate method is recommended
for exploratory analyses or large inputs where computation time is a
concern.}
}
\value{
\itemize{
\item If \code{set} is supplied: a single logical value. \code{TRUE} indicates that the
specified set is closedBY-significant and can be reported as a simultaneous
rejection at FDR level \eqn{\alpha}. \code{FALSE} indicates it cannot.
\item If \code{set = NULL}: a single non-negative integer \eqn{r}. The \eqn{r}
hypotheses with the smallest p-values form a valid simultaneous rejection
set. A return value of \code{0} means no non-empty set can be rejected.
}
}
\description{
Applies the closed testing version of the Benjamini-Yekutieli (BY)
procedure. The standard BY procedure controls the false discovery rate (FDR)
at level \eqn{\alpha} under arbitrary dependence but only provides a single
set of rejections. The closed BY procedure provides \strong{simultaneous FDR
control}: for every set of hypotheses, it determines whether that set can
be reported as discoveries while maintaining FDR control at level
\eqn{\alpha}, regardless of which other sets are inspected.
}
\details{
The closed BY procedure is based on a local e-value for every
intersection hypothesis. A set \eqn{R} of hypotheses is closedBY-significant —
and therefore a valid simultaneous rejection — if and only if, for every
subset \eqn{S \subseteq [m]}, the local e-value exceeds
\eqn{|S \cap R|/|R|\alpha}.
This guarantees post-hoc FDR control: you may report any closedBY-significant
set as your discovery set without inflating the FDR above \eqn{\alpha},
even if the choice of set was data-driven.

The function has two modes:
\itemize{
\item \strong{Set-checking mode} (when \code{set} is supplied): Returns \code{TRUE} if the
specified set is closedBY-significant (i.e., can be reported as a valid
simultaneous rejection at level \eqn{\alpha}), and \code{FALSE} otherwise.
\item \strong{Discovery mode} (when \code{set = NULL}): Returns the size \eqn{r} of the
largest closedBY-significant set. The \eqn{r} hypotheses with the smallest
p-values always form one such set. This gives the maximum number of
hypotheses that can be reported while maintaining simultaneous FDR control.
In particular, the set \eqn{R} consisting of the \eqn{r} smallest p-values is
closedBY-significant.
}

Note that closedBY significance is not a monotone property: a set of size \eqn{r}
being closedBY-significant does not imply that all smaller sets are as well.
The exact algorithm therefore checks all set sizes, while the approximate
algorithm (\code{approximate = TRUE}) uses a faster bisection strategy that may
occasionally underestimate the largest significant set.
}
\examples{
set.seed(42)
# 20 null hypotheses (p ~ Uniform(0,1)) and 10 non-nulls (p ~ Beta(0.1, 1), smaller on average)
p <- c(runif(20), rbeta(10, 0.1, 1))

# --- Discovery mode ---
# Find the maximum number of simultaneous rejections at FDR level 5\%
r <- closedBY(p, alpha = 0.05)
cat("Largest simultaneous rejection set:", r, "\n")

# The r hypotheses with the smallest p-values form a valid discovery set
discovery_set <- p <= sort(p)[r]
cat("P-values in discovery set:", round(sort(p[discovery_set]), 4), "\n")

# --- Set-checking mode ---
# Check whether a researcher-defined set is a valid simultaneous rejection
candidate_set <- p < 0.01
closedBY(p, set = candidate_set, alpha = 0.05)

# --- Exact vs. approximate ---
r_exact  <- closedBY(p, alpha = 0.05, approximate = FALSE)
r_approx <- closedBY(p, alpha = 0.05, approximate = TRUE)
cat("Exact:", r_exact, "  Approximate:", r_approx, "\n")

}
\references{
Benjamini, Y., & Yekutieli, D. (2001). The control of the false discovery
rate in multiple testing under dependency.
\emph{The Annals of Statistics}, 29(4), 1165–1188.

Goeman, J. J., & Solari, A. (2011). Multiple testing for exploratory
research. \emph{Statistical Science}, 26(4), 584–597.

Xu, Z., Solari, A., Fischer, L., de Heide, R., Ramdas, A., & Goeman, J. (2025).
Bringing closure to false discovery rate control: A general principle for
multiple testing. arXiv preprint arXiv:2509.02517.
}
\seealso{
\code{\link[=p.adjust]{p.adjust()}} for standard p-value-based non-simultaneous multiple testing corrections,
including the BY procedure (\code{method = "BY"}).
\code{\link[=closedeBH]{closedeBH()}} for the analogous procedure based on e-values.
}
