Reads the per-chunk flat tables a window scan produced, concatenates them in genomic order, applies the genome-wide significance threshold alpha / n_windows, and merges contiguous/overlapping significant windows into loci.

aggregate_scan_results(
  chunk_files,
  primary_test = "GLOW_Omni",
  alpha = 0.05,
  merge_gap = 0L,
  cmac_cutoff = NULL,
  output_format = "csv"
)

Arguments

chunk_files

Character vector of per-chunk flat-table file paths.

primary_test

Column name driving significance and locus peaks (default "GLOW_Omni").

alpha

Family-wise error rate (default 0.05).

merge_gap

Integer bp (default 0L); windows within this gap of a locus merge into it. 0 merges only directly overlapping/abutting windows.

cmac_cutoff

Optional numeric; windows with cMAC <= cmac_cutoff are dropped before thresholding (STAARpipeline-style). NULL (default) keeps all windows.

output_format

Format of the input chunk files: "csv" (default) or "fst" (requires the fst package).

Value

A list with:

scan_results_all

The genome-wide flat table (tested windows, ordered by chr then start).

scan_sig_windows

The raw significant windows (primary_test < alpha / n_windows); kept so window-to-window comparisons stay possible.

scan_loci

Merged significant loci (see Details for columns).

summary

A 1-row data.frame: n_windows, threshold, n_sig_windows, n_loci, primary_test, alpha, n_dropped_cmac.

Details

Multiple-testing denominator. n_windows is the number of tested windows after the optional cmac_cutoff filter; the threshold is alpha / n_windows, matching the STAARpipeline convention. Overlapping windows are correlated, so this Bonferroni denominator is conservative — a deliberate convention, not a defect.

Locus-merging. Significant windows are sorted by (chr, start); a window joins the running locus when it is on the same chromosome and its start is <= running_end + merge_gap, else it opens a new locus. Each locus reports its position union, the number of member windows, and the peak (minimum primary_test p-value) member's label and full p-value row (prefixed peak_). Running on the assembled genome-wide table makes chunk-boundary loci merge correctly.

Examples

if (FALSE) { # \dontrun{
files <- list.files("outputs/results", "^scan_chunk_.*\\.csv$",
                    full.names = TRUE)
agg <- aggregate_scan_results(files, primary_test = "GLOW_Omni", alpha = 0.05)
agg$summary
head(agg$scan_loci)
} # }