Creates a quantile-quantile plot comparing observed p-values against the expected uniform distribution, with an optional 95% confidence band and genomic inflation factor (\(\lambda_{GC}\)).

plot_qq(x, pvalue_col = "pvalue", ci = TRUE, title = "QQ Plot", cex = 0.5, ...)

Arguments

x

A glow_marginal_scan data.frame, or a numeric vector of p-values.

pvalue_col

Character name of the p-value column (used when x is a data.frame). Default: "pvalue".

ci

Logical: draw a 95% pointwise confidence band? Default: TRUE.

title

Character plot title. Default: "QQ Plot".

cex

Numeric point size. Default: 0.5.

...

Additional arguments passed to plot().

Value

The genomic inflation factor \(\lambda_{GC}\) (invisibly).

Details

The expected p-values under the null are \(e_i = (i - 0.5) / n\), for \(i = 1, \ldots, n\), where n is the number of valid p-values. Observed p-values are sorted in ascending order before plotting.

The genomic inflation factor is computed as: $$\lambda_{GC} = \frac{\mathrm{median}(\chi^2_1)}{\chi^2_{1, 0.5}}$$ where \(\chi^2_1 = \mathrm{qchisq}(1-p, 1)\) for all valid p-values (before sorting).

The 95% confidence band is derived from the Beta distribution: lower bound is \(\mathrm{qbeta}(0.025, i, n-i+1)\) and upper bound is \(\mathrm{qbeta}(0.975, i, n-i+1)\).

Complexity: O(n log n) due to sorting.

Examples

if (FALSE) { # \dontrun{
# Numeric vector input
set.seed(42)
pvals <- runif(10000)
lambda <- plot_qq(pvals)
message("lambda_GC = ", round(lambda, 3))

# data.frame input
df <- data.frame(pvalue = runif(500))
class(df) <- c("glow_marginal_scan", "data.frame")
lambda <- plot_qq(df)
} # }